mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TooltipPlugin: add crosshair exception (#37285)
* TooltipPlugin: add crosshair exception * TooltipPlugin: set active plot and add class * Plot: hide cursor pts when not active in crosshair mode * TooltipPlugin: clean up adding class * TooltipPlugin: rename crosshair class * rename class, move up to chart root element Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
parent
6906a74179
commit
9fa8f5cc95
@ -17,3 +17,7 @@
|
||||
width: 100%;
|
||||
border-bottom: 1px dashed rgba(120, 120, 130, 0.5);
|
||||
}
|
||||
|
||||
.shared-crosshair:not(.plot-active) .u-cursor-pt {
|
||||
display: none !important;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { Portal } from '../../Portal/Portal';
|
||||
import { usePlotContext } from '../context';
|
||||
import {
|
||||
CartesianCoords2D,
|
||||
DashboardCursorSync,
|
||||
DataFrame,
|
||||
FALLBACK_COLOR,
|
||||
FieldType,
|
||||
@ -22,6 +23,7 @@ interface TooltipPluginProps {
|
||||
data: DataFrame;
|
||||
config: UPlotConfigBuilder;
|
||||
mode?: TooltipDisplayMode;
|
||||
sync?: DashboardCursorSync;
|
||||
// Allows custom tooltip content rendering. Exposes aligned data frame with relevant indexes for data inspection
|
||||
// Use field.state.origin indexes from alignedData frame field to get access to original data frame and field index.
|
||||
renderTooltip?: (alignedFrame: DataFrame, seriesIdx: number | null, datapointIdx: number | null) => React.ReactNode;
|
||||
@ -34,6 +36,7 @@ const TOOLTIP_OFFSET = 10;
|
||||
*/
|
||||
export const TooltipPlugin: React.FC<TooltipPluginProps> = ({
|
||||
mode = TooltipDisplayMode.Single,
|
||||
sync,
|
||||
timeZone,
|
||||
config,
|
||||
renderTooltip,
|
||||
@ -46,6 +49,7 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({
|
||||
const [focusedPointIdxs, setFocusedPointIdxs] = useState<Array<number | null>>([]);
|
||||
const [coords, setCoords] = useState<CartesianCoords2D | null>(null);
|
||||
const plotInstance = plotCtx.plot;
|
||||
const [isActive, setIsActive] = useState<boolean>(false);
|
||||
|
||||
const pluginId = `TooltipPlugin`;
|
||||
|
||||
@ -57,19 +61,35 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({
|
||||
useEffect(() => {
|
||||
const plotMouseLeave = () => {
|
||||
setCoords(null);
|
||||
setIsActive(false);
|
||||
if (plotCtx.plot) {
|
||||
plotCtx.plot.root.classList.remove('plot-active');
|
||||
}
|
||||
};
|
||||
|
||||
const plotMouseEnter = () => {
|
||||
setIsActive(true);
|
||||
if (plotCtx.plot) {
|
||||
plotCtx.plot.root.classList.add('plot-active');
|
||||
}
|
||||
};
|
||||
|
||||
if (plotCtx && plotCtx.plot) {
|
||||
plotCtx.plot.over.addEventListener('mouseleave', plotMouseLeave);
|
||||
plotCtx.plot.over.addEventListener('mouseenter', plotMouseEnter);
|
||||
if (sync === DashboardCursorSync.Crosshair) {
|
||||
plotCtx.plot.root.classList.add('shared-crosshair');
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
setCoords(null);
|
||||
if (plotCtx && plotCtx.plot) {
|
||||
plotCtx.plot.over.removeEventListener('mouseleave', plotMouseLeave);
|
||||
plotCtx.plot.over.removeEventListener('mouseenter', plotMouseEnter);
|
||||
}
|
||||
};
|
||||
}, [plotCtx.plot?.root, setCoords]);
|
||||
}, [plotCtx.plot?.root]);
|
||||
|
||||
// Add uPlot hooks to the config, or re-add when the config changed
|
||||
useLayoutEffect(() => {
|
||||
@ -120,7 +140,7 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({
|
||||
}
|
||||
}, [plotCtx, config, setFocusedPointIdx, setFocusedSeriesIdx, setCoords]);
|
||||
|
||||
if (!plotInstance || focusedPointIdx === null || mode === TooltipDisplayMode.None) {
|
||||
if (!plotInstance || focusedPointIdx === null || (!isActive && sync === DashboardCursorSync.Crosshair)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { DashboardCursorSync, Field, PanelProps } from '@grafana/data';
|
||||
import { Field, PanelProps } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { TooltipDisplayMode, usePanelContext, TimeSeries, TooltipPlugin, ZoomPlugin } from '@grafana/ui';
|
||||
import { usePanelContext, TimeSeries, TooltipPlugin, ZoomPlugin, TooltipDisplayMode } from '@grafana/ui';
|
||||
import { getFieldLinksForExplore } from 'app/features/explore/utils/links';
|
||||
import React, { useMemo } from 'react';
|
||||
import { AnnotationsPlugin } from './plugins/AnnotationsPlugin';
|
||||
@ -53,12 +53,15 @@ export const TimeSeriesPanel: React.FC<TimeSeriesPanelProps> = ({
|
||||
return (
|
||||
<>
|
||||
<ZoomPlugin config={config} onZoom={onChangeTimeRange} />
|
||||
<TooltipPlugin
|
||||
data={alignedDataFrame}
|
||||
config={config}
|
||||
mode={sync === DashboardCursorSync.Tooltip ? TooltipDisplayMode.Multi : options.tooltip.mode}
|
||||
timeZone={timeZone}
|
||||
/>
|
||||
{options.tooltip.mode === TooltipDisplayMode.None || (
|
||||
<TooltipPlugin
|
||||
data={alignedDataFrame}
|
||||
config={config}
|
||||
mode={options.tooltip.mode}
|
||||
sync={sync}
|
||||
timeZone={timeZone}
|
||||
/>
|
||||
)}
|
||||
{/* Renders annotation markers*/}
|
||||
{data.annotations && (
|
||||
<AnnotationsPlugin annotations={data.annotations} config={config} timeZone={timeZone} />
|
||||
|
Loading…
Reference in New Issue
Block a user