From 3e3a6573434036bad6224d7bc9301ce5bcd2286c Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Thu, 3 Mar 2022 10:57:54 -0600 Subject: [PATCH] BarChart: fix hovered series highlight in tooltip (#44882) --- .../barchart/__snapshots__/utils.test.ts.snap | 56 ++++++++---- public/app/plugins/panel/barchart/bars.ts | 86 ++++++++++--------- 2 files changed, 86 insertions(+), 56 deletions(-) diff --git a/public/app/plugins/panel/barchart/__snapshots__/utils.test.ts.snap b/public/app/plugins/panel/barchart/__snapshots__/utils.test.ts.snap index 300a917e722..2410f353ef2 100644 --- a/public/app/plugins/panel/barchart/__snapshots__/utils.test.ts.snap +++ b/public/app/plugins/panel/barchart/__snapshots__/utils.test.ts.snap @@ -59,15 +59,18 @@ Object { }, ], "cursor": Object { + "dataIdx": [Function], "drag": Object { "setScale": false, + "x": false, + "y": false, }, "focus": Object { "prox": 30, }, "points": Object { - "fill": [Function], - "show": false, + "bbox": [Function], + "fill": "rgba(255,255,255,0.4)", "size": [Function], "stroke": [Function], "width": [Function], @@ -195,15 +198,18 @@ Object { }, ], "cursor": Object { + "dataIdx": [Function], "drag": Object { "setScale": false, + "x": false, + "y": false, }, "focus": Object { "prox": 30, }, "points": Object { - "fill": [Function], - "show": false, + "bbox": [Function], + "fill": "rgba(255,255,255,0.4)", "size": [Function], "stroke": [Function], "width": [Function], @@ -331,15 +337,18 @@ Object { }, ], "cursor": Object { + "dataIdx": [Function], "drag": Object { "setScale": false, + "x": false, + "y": false, }, "focus": Object { "prox": 30, }, "points": Object { - "fill": [Function], - "show": false, + "bbox": [Function], + "fill": "rgba(255,255,255,0.4)", "size": [Function], "stroke": [Function], "width": [Function], @@ -467,15 +476,18 @@ Object { }, ], "cursor": Object { + "dataIdx": [Function], "drag": Object { "setScale": false, + "x": false, + "y": false, }, "focus": Object { "prox": 30, }, "points": Object { - "fill": [Function], - "show": false, + "bbox": [Function], + "fill": "rgba(255,255,255,0.4)", "size": [Function], "stroke": [Function], "width": [Function], @@ -603,15 +615,18 @@ Object { }, ], "cursor": Object { + "dataIdx": [Function], "drag": Object { "setScale": false, + "x": false, + "y": false, }, "focus": Object { "prox": 30, }, "points": Object { - "fill": [Function], - "show": false, + "bbox": [Function], + "fill": "rgba(255,255,255,0.4)", "size": [Function], "stroke": [Function], "width": [Function], @@ -739,15 +754,18 @@ Object { }, ], "cursor": Object { + "dataIdx": [Function], "drag": Object { "setScale": false, + "x": false, + "y": false, }, "focus": Object { "prox": 30, }, "points": Object { - "fill": [Function], - "show": false, + "bbox": [Function], + "fill": "rgba(255,255,255,0.4)", "size": [Function], "stroke": [Function], "width": [Function], @@ -875,15 +893,18 @@ Object { }, ], "cursor": Object { + "dataIdx": [Function], "drag": Object { "setScale": false, + "x": false, + "y": false, }, "focus": Object { "prox": 30, }, "points": Object { - "fill": [Function], - "show": false, + "bbox": [Function], + "fill": "rgba(255,255,255,0.4)", "size": [Function], "stroke": [Function], "width": [Function], @@ -1011,15 +1032,18 @@ Object { }, ], "cursor": Object { + "dataIdx": [Function], "drag": Object { "setScale": false, + "x": false, + "y": false, }, "focus": Object { "prox": 30, }, "points": Object { - "fill": [Function], - "show": false, + "bbox": [Function], + "fill": "rgba(255,255,255,0.4)", "size": [Function], "stroke": [Function], "width": [Function], diff --git a/public/app/plugins/panel/barchart/bars.ts b/public/app/plugins/panel/barchart/bars.ts index 098160b6e73..ef7cc7f6336 100644 --- a/public/app/plugins/panel/barchart/bars.ts +++ b/public/app/plugins/panel/barchart/bars.ts @@ -125,12 +125,7 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { } let qt: Quadtree; - let hovered: Rect | undefined = undefined; - - let barMark = document.createElement('div'); - barMark.classList.add('bar-mark'); - barMark.style.position = 'absolute'; - barMark.style.background = 'rgba(255,255,255,0.4)'; + let hRect: Rect | null; const xSplits: Axis.Splits = (u: uPlot) => { const dim = isXHorizontal ? u.bbox.width : u.bbox.height; @@ -408,7 +403,47 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { const init = (u: uPlot) => { let over = u.over; over.style.overflow = 'hidden'; - over.appendChild(barMark); + u.root.querySelectorAll('.u-cursor-pt').forEach((el) => { + (el as HTMLElement).style.borderRadius = '0'; + }); + }; + + const cursor: uPlot.Cursor = { + x: false, + y: false, + drag: { + x: false, + y: false, + }, + dataIdx: (u, seriesIdx) => { + if (seriesIdx === 1) { + hRect = null; + + let cx = u.cursor.left! * devicePixelRatio; + let cy = u.cursor.top! * devicePixelRatio; + + qt.get(cx, cy, 1, 1, (o) => { + if (pointWithin(cx, cy, o.x, o.y, o.x + o.w, o.y + o.h)) { + hRect = o; + } + }); + } + + return hRect && seriesIdx === hRect.sidx ? hRect.didx : null; + }, + points: { + fill: 'rgba(255,255,255,0.4)', + bbox: (u, seriesIdx) => { + let isHovered = hRect && seriesIdx === hRect.sidx; + + return { + left: isHovered ? hRect!.x / devicePixelRatio : -10, + top: isHovered ? hRect!.y / devicePixelRatio : -10, + width: isHovered ? hRect!.w / devicePixelRatio : 0, + height: isHovered ? hRect!.h / devicePixelRatio : 0, + }; + }, + }, }; // Build bars @@ -518,35 +553,10 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { updateTooltipPosition, u ) => { - let found: Rect | undefined; - let cx = u.cursor.left! * devicePixelRatio; - let cy = u.cursor.top! * devicePixelRatio; - - qt.get(cx, cy, 1, 1, (o) => { - if (pointWithin(cx, cy, o.x, o.y, o.x + o.w, o.y + o.h)) { - found = o; - } - }); - - if (found) { - // prettier-ignore - if (found !== hovered) { - barMark.style.display = ''; - barMark.style.left = found.x / devicePixelRatio + 'px'; - barMark.style.top = found.y / devicePixelRatio + 'px'; - barMark.style.width = found.w / devicePixelRatio + 'px'; - barMark.style.height = found.h / devicePixelRatio + 'px'; - hovered = found; - updateActiveSeriesIdx(hovered.sidx); - updateActiveDatapointIdx(hovered.didx); - updateTooltipPosition(); - } - } else if (hovered !== undefined) { - updateActiveSeriesIdx(hovered!.sidx); - updateActiveDatapointIdx(hovered!.didx); + if (hRect) { + updateActiveSeriesIdx(hRect.sidx); + updateActiveDatapointIdx(hRect.didx); updateTooltipPosition(); - hovered = undefined; - barMark.style.display = 'none'; } else { updateTooltipPosition(true); } @@ -567,11 +577,7 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { } return { - cursor: { - x: false, - y: false, - points: { show: false }, - }, + cursor, // scale & axis opts xRange, xValues,