BarChart: Fix stacked hover (#57711)

This commit is contained in:
Leon Sorokin 2022-10-31 16:48:21 -05:00 committed by GitHub
parent 6aa3003a54
commit fbfd0fd51b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 3 deletions

View File

@ -15,7 +15,7 @@ import { formatTime } from '@grafana/ui/src/components/uPlot/config/UPlotAxisBui
import { StackingGroup, preparePlotData2 } from '@grafana/ui/src/components/uPlot/utils';
import { distribute, SPACE_BETWEEN } from './distribute';
import { intersects, pointWithin, Quadtree, Rect } from './quadtree';
import { findRect, intersects, pointWithin, Quadtree, Rect } from './quadtree';
const groupDistr = SPACE_BETWEEN;
const barDistr = SPACE_BETWEEN;
@ -437,7 +437,14 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
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;
if (isStacked) {
// choose the smallest hovered rect (when stacked bigger ones overlap smaller ones)
if (hRect == null || o.h * o.w < hRect.h * hRect.w) {
hRect = o;
}
} else {
hRect = o;
}
}
});
}
@ -449,11 +456,18 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
bbox: (u, seriesIdx) => {
let isHovered = hRect && seriesIdx === hRect.sidx;
let heightReduce = 0;
// get height of bar rect at same index of the series below the hovered one
if (isStacked && isHovered && hRect!.sidx > 1) {
heightReduce = findRect(qt, hRect!.sidx - 1, hRect!.didx)!.h;
}
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,
height: isHovered ? (hRect!.h - heightReduce) / devicePixelRatio : 0,
};
},
},

View File

@ -11,6 +11,29 @@ export function pointWithin(px: number, py: number, rlft: number, rtop: number,
return px >= rlft && px <= rrgt && py >= rtop && py <= rbtm;
}
/**
* @internal
*/
export function findRect(qt: Quadtree, sidx: number, didx: number): Rect | undefined {
let out: Rect | undefined;
if (qt.o.length) {
out = qt.o.find((rect) => rect.sidx === sidx && rect.didx === didx);
}
if (out == null && qt.q) {
for (let i = 0; i < qt.q.length; i++) {
out = findRect(qt.q[i], sidx, didx);
if (out) {
break;
}
}
}
return out;
}
/**
* @internal
*