Time series panel: Position tooltip correctly when window scrolled or resized (#34782) (#34794)

* Position GraphNG tooltip correctly when window scrolled or resized

* Use syncRect uPlot hook instead of polling

* update snap?!

(cherry picked from commit 1fa755bada)

Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
Grot (@grafanabot)
2021-05-27 13:53:58 +02:00
committed by GitHub
co-authored by Dominik Prokop
parent 6d44eb8954
commit b3a1a063fe
4 changed files with 20 additions and 5 deletions
@@ -229,6 +229,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{ sync: DashboardCursor
data: frame, data: frame,
}; };
const hoverEvent = new DataHoverEvent(payload); const hoverEvent = new DataHoverEvent(payload);
builder.setSync();
builder.setCursor({ builder.setCursor({
sync: { sync: {
key: '__global_', key: '__global_',
@@ -36,7 +36,9 @@ export class UPlotChart extends React.Component<PlotProps, UPlotChartState> {
this.state = { this.state = {
ctx: { ctx: {
plot: null, plot: null,
getCanvasBoundingBox: () => this.plotCanvasBBox.current, getCanvasBoundingBox: () => {
return this.plotCanvasBBox.current;
},
}, },
}; };
} }
@@ -50,6 +52,11 @@ export class UPlotChart extends React.Component<PlotProps, UPlotChartState> {
if (width === 0 && height === 0) { if (width === 0 && height === 0) {
return; return;
} }
this.props.config.addHook('syncRect', (u, rect) => {
(this.plotCanvasBBox as MutableRefObject<any>).current = rect;
});
this.props.config.addHook('setSize', (u) => { this.props.config.addHook('setSize', (u) => {
const canvas = u.over; const canvas = u.over;
if (!canvas) { if (!canvas) {
@@ -29,6 +29,7 @@ export class UPlotConfigBuilder {
private hasBottomAxis = false; private hasBottomAxis = false;
private hooks: Hooks.Arrays = {}; private hooks: Hooks.Arrays = {};
private tz: string | undefined = undefined; private tz: string | undefined = undefined;
private sync = false;
// to prevent more than one threshold per scale // to prevent more than one threshold per scale
private thresholds: Record<string, UPlotThresholdOptions> = {}; private thresholds: Record<string, UPlotThresholdOptions> = {};
/** /**
@@ -134,6 +135,14 @@ export class UPlotConfigBuilder {
this.tooltipInterpolator = interpolator; this.tooltipInterpolator = interpolator;
} }
setSync() {
this.sync = true;
}
hasSync() {
return this.sync;
}
getConfig() { getConfig() {
const config: PlotConfig = { series: [{}] }; const config: PlotConfig = { series: [{}] };
config.axes = this.ensureNonOverlappingAxes(Object.values(this.axes)).map((a) => a.getConfig()); config.axes = this.ensureNonOverlappingAxes(Object.values(this.axes)).map((a) => a.getConfig());
@@ -39,7 +39,6 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({
const [focusedSeriesIdx, setFocusedSeriesIdx] = useState<number | null>(null); const [focusedSeriesIdx, setFocusedSeriesIdx] = useState<number | null>(null);
const [focusedPointIdx, setFocusedPointIdx] = useState<number | null>(null); const [focusedPointIdx, setFocusedPointIdx] = useState<number | null>(null);
const [coords, setCoords] = useState<CartesianCoords2D | null>(null); const [coords, setCoords] = useState<CartesianCoords2D | null>(null);
const pluginId = `TooltipPlugin`; const pluginId = `TooltipPlugin`;
// Debug logs // Debug logs
@@ -88,20 +87,19 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({
} else { } else {
// default series/datapoint idx retireval // default series/datapoint idx retireval
config.addHook('setCursor', (u) => { config.addHook('setCursor', (u) => {
setFocusedPointIdx(u.cursor.idx === undefined ? u.posToIdx(u.cursor.left || 0) : u.cursor.idx);
const bbox = plotCtx.getCanvasBoundingBox(); const bbox = plotCtx.getCanvasBoundingBox();
if (!bbox) { if (!bbox) {
return; return;
} }
const { x, y } = positionTooltip(u, bbox); const { x, y } = positionTooltip(u, bbox);
if (x !== undefined && y !== undefined) { if (x !== undefined && y !== undefined) {
setCoords({ x, y }); setCoords({ x, y });
} else { } else {
setCoords(null); setCoords(null);
} }
setFocusedPointIdx(u.cursor.idx === undefined ? u.posToIdx(u.cursor.left || 0) : u.cursor.idx);
}); });
config.addHook('setSeries', (_, idx) => { config.addHook('setSeries', (_, idx) => {