Graph panel: listen to events from timeseries panel (#41033)

* TimeSeries: share cursor with old graph

* Typo fix

* Fix typecheck errors

* Revert "TimeSeries: share cursor with old graph"

This reverts commit 1e7dd4f627.

* Graph: subscribe to DataHoverEvent

* Revert "Fix typecheck errors"

This reverts commit 737c8ea8c1.
This commit is contained in:
Zoltán Bedi 2021-11-03 11:49:37 +01:00 committed by GitHub
parent 47f6bb3583
commit f8d75726e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 7 deletions

View File

@ -355,6 +355,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{ sync: DashboardCursor
// convert the points
payload.point[xScaleUnit] = src.posToVal(x, xScaleKey);
payload.point[yScaleKey] = src.posToVal(y, yScaleKey);
payload.point.panelRelY = y > 0 ? y / h : 1; // used by old graph panel to position tooltip
eventBus.publish(hoverEvent);
hoverEvent.payload.down = undefined;
}

View File

@ -134,7 +134,7 @@ export function collectStackingGroups(f: Field, groups: Map<string, number[]>, s
}
/**
* Finds y axis midpoind for point at given idx (css pixels relative to uPlot canvas)
* Finds y axis midpoint for point at given idx (css pixels relative to uPlot canvas)
* @internal
**/
@ -177,7 +177,7 @@ export function findMidPointYPosition(u: uPlot, idx: number) {
// find median position
y = (u.valToPos(min, u.series[sMinIdx].scale!) + u.valToPos(max, u.series[sMaxIdx].scale!)) / 2;
} else {
// snap tooltip to min OR max point, one of thos is not null :)
// snap tooltip to min OR max point, one of those is not null :)
y = u.valToPos((min || max)!, u.series[(sMaxIdx || sMinIdx)!].scale!);
}

View File

@ -29,6 +29,9 @@ import { provideTheme } from 'app/core/utils/ConfigProvider';
import {
DataFrame,
DataFrameView,
DataHoverClearEvent,
DataHoverEvent,
DataHoverPayload,
FieldDisplay,
FieldType,
formattedValueToString,
@ -40,6 +43,7 @@ import {
LegacyEventHandler,
LegacyGraphHoverClearEvent,
LegacyGraphHoverEvent,
LegacyGraphHoverEventPayload,
LinkModelSupplier,
PanelEvents,
toUtc,
@ -49,6 +53,7 @@ import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { ContextSrv } from 'app/core/services/context_srv';
import { getFieldLinksSupplier } from 'app/angular/panel/panellinks/linkSuppliers';
import { DashboardModel } from '../../../features/dashboard/state';
import { isLegacyGraphHoverEvent } from './utils';
const LegendWithThemeProvider = provideTheme(Legend);
@ -99,6 +104,9 @@ class GraphElement {
this.ctrl.dashboard.events.on(LegacyGraphHoverEvent.type, this.onGraphHover.bind(this), this.scope);
this.ctrl.dashboard.events.on(LegacyGraphHoverClearEvent.type, this.onGraphHoverClear.bind(this), this.scope);
this.ctrl.dashboard.events.on(DataHoverEvent.type, this.onGraphHover.bind(this), this.scope);
this.ctrl.dashboard.events.on(DataHoverClearEvent.type, this.onGraphHoverClear.bind(this), this.scope);
// plot events
this.elem.bind('plotselected', this.onPlotSelected.bind(this));
this.elem.bind('plotclick', this.onPlotClick.bind(this));
@ -147,18 +155,27 @@ class GraphElement {
ReactDOM.render(legendReactElem, this.legendElem, () => this.renderPanel());
}
onGraphHover(evt: any) {
onGraphHover(evt: LegacyGraphHoverEventPayload | DataHoverPayload) {
// ignore other graph hover events if shared tooltip is disabled
if (!this.dashboard.sharedTooltipModeEnabled()) {
return;
}
// ignore if we are the emitter
if (!this.plot || evt.panel.id === this.panel.id || this.ctrl.otherPanelInFullscreenMode()) {
if (isLegacyGraphHoverEvent(evt)) {
// ignore if we are the emitter
if (!this.plot || evt.panel?.id === this.panel.id || this.ctrl.otherPanelInFullscreenMode()) {
return;
}
this.tooltip.show(evt.pos);
}
// DataHoverEvent can come from multiple panels that doesn't include x position
if (!evt.point?.time) {
return;
}
this.tooltip.show(evt.pos);
this.tooltip.show({ x: evt.point.time, panelRelY: evt.point.panelRelY ?? 1 });
}
onPanelTeardown() {

View File

@ -1,4 +1,11 @@
import { DataFrame, ReducerID, reduceField, AbsoluteTimeRange, FieldType } from '@grafana/data';
import {
AbsoluteTimeRange,
DataFrame,
FieldType,
LegacyGraphHoverEventPayload,
reduceField,
ReducerID,
} from '@grafana/data';
/**
* Find the min and max time that covers all data
@ -22,3 +29,8 @@ export function getDataTimeRange(frames: DataFrame[]): AbsoluteTimeRange | undef
}
return found ? range : undefined;
}
// Check wether event is LegacyGraphHoverEvent
export function isLegacyGraphHoverEvent(event: any): event is LegacyGraphHoverEventPayload {
return event.hasOwnProperty('pos');
}