From 6be24cd2de68582c6f41ae153be6d03187cc69b3 Mon Sep 17 00:00:00 2001 From: Javier Ruiz Calle Date: Wed, 3 Dec 2025 11:30:05 +0100 Subject: [PATCH] Set cursor pointer when underlying point has data links --- .../uPlot/plugins/TooltipPlugin2.tsx | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin2.tsx b/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin2.tsx index 606839aacad..a2968e234f7 100644 --- a/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin2.tsx +++ b/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin2.tsx @@ -221,6 +221,8 @@ export const TooltipPlugin2 = ({ let pendingRender = false; let pendingPinned = false; + let prevCursorStyle = ''; + const scheduleRender = (setPinned = false) => { if (!pendingRender) { // defer unrender for 100ms to reduce flickering in small gaps @@ -292,8 +294,27 @@ export const TooltipPlugin2 = ({ setState(state); - // TODO: set u.over.style.cursor = 'pointer' if we hovered a oneClick point - // else revert to default...but only when the new pointer is different from prev + // Update cursor style when hovering over points with data links + if (_plot != null) { + let newCursorStyle = ''; + + if (_isHovering && !_isPinned && closestSeriesIdx != null && closestSeriesIdx > 0) { + // Check if the hovered point has data links + const dataIdx = seriesIdxs[closestSeriesIdx]; + if (dataIdx != null) { + const links = getLinksRef.current(closestSeriesIdx, dataIdx); + if (links && links.length > 0) { + newCursorStyle = 'pointer'; + } + } + } + + // Only update if cursor style changed to avoid unnecessary DOM updates + if (newCursorStyle !== prevCursorStyle) { + _plot.over.style.cursor = newCursorStyle; + prevCursorStyle = newCursorStyle; + } + } selectedRange = null; }; @@ -306,6 +327,12 @@ export const TooltipPlugin2 = ({ dataLinks = []; adHocFilters = []; + // Reset cursor style when dismissing + if (_plot!.over.style.cursor !== '') { + _plot!.over.style.cursor = ''; + prevCursorStyle = ''; + } + scheduleRender(prevIsPinned); };