mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tooltips: Generate data links in TooltipPlugin2 (#97818)
Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
parent
8d4e5a4e09
commit
03d176fae4
@ -40,7 +40,7 @@ export const VizTooltipFooter = ({ dataLinks, actions, annotate }: VizTooltipFoo
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrapper}>
|
<div className={styles.wrapper}>
|
||||||
{dataLinks.length > 0 && <div className={styles.dataLinks}>{renderDataLinks(dataLinks, styles)}</div>}
|
{dataLinks?.length > 0 && <div className={styles.dataLinks}>{renderDataLinks(dataLinks, styles)}</div>}
|
||||||
{actions && actions.length > 0 && <div className={styles.dataLinks}>{renderActions(actions)}</div>}
|
{actions && actions.length > 0 && <div className={styles.dataLinks}>{renderActions(actions)}</div>}
|
||||||
{annotate != null && (
|
{annotate != null && (
|
||||||
<div className={styles.addAnnotations}>
|
<div className={styles.addAnnotations}>
|
||||||
|
@ -4,7 +4,7 @@ import * as React from 'react';
|
|||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2, LinkModel } from '@grafana/data';
|
||||||
import { DashboardCursorSync } from '@grafana/schema';
|
import { DashboardCursorSync } from '@grafana/schema';
|
||||||
|
|
||||||
import { useStyles2 } from '../../../themes';
|
import { useStyles2 } from '../../../themes';
|
||||||
@ -27,6 +27,8 @@ export const enum TooltipHoverMode {
|
|||||||
xyOne,
|
xyOne,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GeDataLinksCallback = (seriesIdx: number, dataIdx: number) => LinkModel[];
|
||||||
|
|
||||||
interface TooltipPlugin2Props {
|
interface TooltipPlugin2Props {
|
||||||
config: UPlotConfigBuilder;
|
config: UPlotConfigBuilder;
|
||||||
hoverMode: TooltipHoverMode;
|
hoverMode: TooltipHoverMode;
|
||||||
@ -40,6 +42,7 @@ interface TooltipPlugin2Props {
|
|||||||
clientZoom?: boolean;
|
clientZoom?: boolean;
|
||||||
|
|
||||||
onSelectRange?: OnSelectRangeCallback;
|
onSelectRange?: OnSelectRangeCallback;
|
||||||
|
getDataLinks?: GeDataLinksCallback;
|
||||||
|
|
||||||
render: (
|
render: (
|
||||||
u: uPlot,
|
u: uPlot,
|
||||||
@ -49,7 +52,8 @@ interface TooltipPlugin2Props {
|
|||||||
dismiss: () => void,
|
dismiss: () => void,
|
||||||
// selected time range (for annotation triggering)
|
// selected time range (for annotation triggering)
|
||||||
timeRange: TimeRange2 | null,
|
timeRange: TimeRange2 | null,
|
||||||
viaSync: boolean
|
viaSync: boolean,
|
||||||
|
dataLinks: LinkModel[]
|
||||||
) => React.ReactNode;
|
) => React.ReactNode;
|
||||||
|
|
||||||
maxWidth?: number;
|
maxWidth?: number;
|
||||||
@ -102,6 +106,8 @@ const MIN_ZOOM_DIST = 5;
|
|||||||
|
|
||||||
const maybeZoomAction = (e?: MouseEvent | null) => e != null && !e.ctrlKey && !e.metaKey;
|
const maybeZoomAction = (e?: MouseEvent | null) => e != null && !e.ctrlKey && !e.metaKey;
|
||||||
|
|
||||||
|
const getDataLinksFallback: GeDataLinksCallback = () => [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @alpha
|
* @alpha
|
||||||
*/
|
*/
|
||||||
@ -115,6 +121,7 @@ export const TooltipPlugin2 = ({
|
|||||||
maxWidth,
|
maxWidth,
|
||||||
syncMode = DashboardCursorSync.Off,
|
syncMode = DashboardCursorSync.Off,
|
||||||
syncScope = 'global', // eventsScope
|
syncScope = 'global', // eventsScope
|
||||||
|
getDataLinks = getDataLinksFallback,
|
||||||
}: TooltipPlugin2Props) => {
|
}: TooltipPlugin2Props) => {
|
||||||
const domRef = useRef<HTMLDivElement>(null);
|
const domRef = useRef<HTMLDivElement>(null);
|
||||||
const portalRoot = useRef<HTMLElement | null>(null);
|
const portalRoot = useRef<HTMLElement | null>(null);
|
||||||
@ -131,6 +138,9 @@ export const TooltipPlugin2 = ({
|
|||||||
const renderRef = useRef(render);
|
const renderRef = useRef(render);
|
||||||
renderRef.current = render;
|
renderRef.current = render;
|
||||||
|
|
||||||
|
const getLinksRef = useRef(getDataLinks);
|
||||||
|
getLinksRef.current = getDataLinks;
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
sizeRef.current = {
|
sizeRef.current = {
|
||||||
width: 0,
|
width: 0,
|
||||||
@ -187,6 +197,7 @@ export const TooltipPlugin2 = ({
|
|||||||
let seriesIdxs: Array<number | null> = plot?.cursor.idxs!.slice()!;
|
let seriesIdxs: Array<number | null> = plot?.cursor.idxs!.slice()!;
|
||||||
let closestSeriesIdx: number | null = null;
|
let closestSeriesIdx: number | null = null;
|
||||||
let viaSync = false;
|
let viaSync = false;
|
||||||
|
let dataLinks: LinkModel[] = [];
|
||||||
|
|
||||||
let pendingRender = false;
|
let pendingRender = false;
|
||||||
let pendingPinned = false;
|
let pendingPinned = false;
|
||||||
@ -242,7 +253,16 @@ export const TooltipPlugin2 = ({
|
|||||||
isHovering: _isHovering,
|
isHovering: _isHovering,
|
||||||
contents:
|
contents:
|
||||||
_isHovering || selectedRange != null
|
_isHovering || selectedRange != null
|
||||||
? renderRef.current(_plot!, seriesIdxs, closestSeriesIdx, _isPinned, dismiss, selectedRange, viaSync)
|
? renderRef.current(
|
||||||
|
_plot!,
|
||||||
|
seriesIdxs,
|
||||||
|
closestSeriesIdx,
|
||||||
|
_isPinned,
|
||||||
|
dismiss,
|
||||||
|
selectedRange,
|
||||||
|
viaSync,
|
||||||
|
dataLinks
|
||||||
|
)
|
||||||
: null,
|
: null,
|
||||||
dismiss,
|
dismiss,
|
||||||
};
|
};
|
||||||
@ -257,6 +277,8 @@ export const TooltipPlugin2 = ({
|
|||||||
_isPinned = false;
|
_isPinned = false;
|
||||||
_isHovering = false;
|
_isHovering = false;
|
||||||
_plot!.setCursor({ left: -10, top: -10 });
|
_plot!.setCursor({ left: -10, top: -10 });
|
||||||
|
dataLinks = [];
|
||||||
|
|
||||||
scheduleRender(prevIsPinned);
|
scheduleRender(prevIsPinned);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -313,6 +335,8 @@ export const TooltipPlugin2 = ({
|
|||||||
}
|
}
|
||||||
// only pinnable tooltip is visible *and* is within proximity to series/point
|
// only pinnable tooltip is visible *and* is within proximity to series/point
|
||||||
else if (_isHovering && closestSeriesIdx != null && !_isPinned) {
|
else if (_isHovering && closestSeriesIdx != null && !_isPinned) {
|
||||||
|
dataLinks = getLinksRef.current(closestSeriesIdx!, seriesIdxs[closestSeriesIdx!]!);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
_isPinned = true;
|
_isPinned = true;
|
||||||
scheduleRender(true);
|
scheduleRender(true);
|
||||||
|
@ -157,7 +157,10 @@ export const BarChartPanel = (props: PanelProps<Options>) => {
|
|||||||
hoverMode={
|
hoverMode={
|
||||||
options.tooltip.mode === TooltipDisplayMode.Single ? TooltipHoverMode.xOne : TooltipHoverMode.xAll
|
options.tooltip.mode === TooltipDisplayMode.Single ? TooltipHoverMode.xOne : TooltipHoverMode.xAll
|
||||||
}
|
}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2) => {
|
getDataLinks={(seriesIdx: number, dataIdx: number) =>
|
||||||
|
vizSeries[0].fields[seriesIdx]!.getLinks?.({ valueRowIndex: dataIdx }) ?? []
|
||||||
|
}
|
||||||
|
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2, viaSync, dataLinks) => {
|
||||||
return (
|
return (
|
||||||
<TimeSeriesTooltip
|
<TimeSeriesTooltip
|
||||||
series={vizSeries[0]}
|
series={vizSeries[0]}
|
||||||
@ -169,6 +172,7 @@ export const BarChartPanel = (props: PanelProps<Options>) => {
|
|||||||
isPinned={isPinned}
|
isPinned={isPinned}
|
||||||
maxHeight={options.tooltip.maxHeight}
|
maxHeight={options.tooltip.maxHeight}
|
||||||
replaceVariables={replaceVariables}
|
replaceVariables={replaceVariables}
|
||||||
|
dataLinks={dataLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -282,7 +282,10 @@ export const CandlestickPanel = ({
|
|||||||
clientZoom={true}
|
clientZoom={true}
|
||||||
syncMode={cursorSync}
|
syncMode={cursorSync}
|
||||||
syncScope={eventsScope}
|
syncScope={eventsScope}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange2, viaSync) => {
|
getDataLinks={(seriesIdx: number, dataIdx: number) =>
|
||||||
|
alignedFrame.fields[seriesIdx]!.getLinks?.({ valueRowIndex: dataIdx }) ?? []
|
||||||
|
}
|
||||||
|
render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange2, viaSync, dataLinks) => {
|
||||||
if (enableAnnotationCreation && timeRange2 != null) {
|
if (enableAnnotationCreation && timeRange2 != null) {
|
||||||
setNewAnnotationRange(timeRange2);
|
setNewAnnotationRange(timeRange2);
|
||||||
dismiss();
|
dismiss();
|
||||||
@ -307,6 +310,7 @@ export const CandlestickPanel = ({
|
|||||||
annotate={enableAnnotationCreation ? annotate : undefined}
|
annotate={enableAnnotationCreation ? annotate : undefined}
|
||||||
maxHeight={options.tooltip.maxHeight}
|
maxHeight={options.tooltip.maxHeight}
|
||||||
replaceVariables={replaceVariables}
|
replaceVariables={replaceVariables}
|
||||||
|
dataLinks={dataLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -172,7 +172,10 @@ export const StateTimelinePanel = ({
|
|||||||
queryZoom={onChangeTimeRange}
|
queryZoom={onChangeTimeRange}
|
||||||
syncMode={cursorSync}
|
syncMode={cursorSync}
|
||||||
syncScope={eventsScope}
|
syncScope={eventsScope}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2, viaSync) => {
|
getDataLinks={(seriesIdx: number, dataIdx: number) =>
|
||||||
|
alignedFrame.fields[seriesIdx]!.getLinks?.({ valueRowIndex: dataIdx }) ?? []
|
||||||
|
}
|
||||||
|
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2, viaSync, dataLinks) => {
|
||||||
if (enableAnnotationCreation && timeRange2 != null) {
|
if (enableAnnotationCreation && timeRange2 != null) {
|
||||||
setNewAnnotationRange(timeRange2);
|
setNewAnnotationRange(timeRange2);
|
||||||
dismiss();
|
dismiss();
|
||||||
@ -199,6 +202,7 @@ export const StateTimelinePanel = ({
|
|||||||
withDuration={true}
|
withDuration={true}
|
||||||
maxHeight={options.tooltip.maxHeight}
|
maxHeight={options.tooltip.maxHeight}
|
||||||
replaceVariables={replaceVariables}
|
replaceVariables={replaceVariables}
|
||||||
|
dataLinks={dataLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -11,7 +11,7 @@ import { VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types';
|
|||||||
import { getContentItems } from '@grafana/ui/src/components/VizTooltip/utils';
|
import { getContentItems } from '@grafana/ui/src/components/VizTooltip/utils';
|
||||||
import { findNextStateIndex, fmtDuration } from 'app/core/components/TimelineChart/utils';
|
import { findNextStateIndex, fmtDuration } from 'app/core/components/TimelineChart/utils';
|
||||||
|
|
||||||
import { getDataLinks, getFieldActions } from '../status-history/utils';
|
import { getFieldActions } from '../status-history/utils';
|
||||||
import { TimeSeriesTooltipProps } from '../timeseries/TimeSeriesTooltip';
|
import { TimeSeriesTooltipProps } from '../timeseries/TimeSeriesTooltip';
|
||||||
import { isTooltipScrollable } from '../timeseries/utils';
|
import { isTooltipScrollable } from '../timeseries/utils';
|
||||||
|
|
||||||
@ -32,6 +32,7 @@ export const StateTimelineTooltip2 = ({
|
|||||||
withDuration,
|
withDuration,
|
||||||
maxHeight,
|
maxHeight,
|
||||||
replaceVariables,
|
replaceVariables,
|
||||||
|
dataLinks,
|
||||||
}: StateTimelineTooltip2Props) => {
|
}: StateTimelineTooltip2Props) => {
|
||||||
const xField = series.fields[0];
|
const xField = series.fields[0];
|
||||||
|
|
||||||
@ -70,10 +71,9 @@ export const StateTimelineTooltip2 = ({
|
|||||||
if (isPinned && seriesIdx != null) {
|
if (isPinned && seriesIdx != null) {
|
||||||
const field = series.fields[seriesIdx];
|
const field = series.fields[seriesIdx];
|
||||||
const dataIdx = dataIdxs[seriesIdx]!;
|
const dataIdx = dataIdxs[seriesIdx]!;
|
||||||
const links = getDataLinks(field, dataIdx);
|
|
||||||
const actions = getFieldActions(series, field, replaceVariables!, dataIdx);
|
const actions = getFieldActions(series, field, replaceVariables!, dataIdx);
|
||||||
|
|
||||||
footer = <VizTooltipFooter dataLinks={links} annotate={annotate} actions={actions} />;
|
footer = <VizTooltipFooter dataLinks={dataLinks} annotate={annotate} actions={actions} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerItem: VizTooltipItem = {
|
const headerItem: VizTooltipItem = {
|
||||||
|
@ -104,7 +104,10 @@ export const StatusHistoryPanel = ({
|
|||||||
queryZoom={onChangeTimeRange}
|
queryZoom={onChangeTimeRange}
|
||||||
syncMode={cursorSync}
|
syncMode={cursorSync}
|
||||||
syncScope={eventsScope}
|
syncScope={eventsScope}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2, viaSync) => {
|
getDataLinks={(seriesIdx: number, dataIdx: number) =>
|
||||||
|
alignedFrame.fields[seriesIdx]!.getLinks?.({ valueRowIndex: dataIdx }) ?? []
|
||||||
|
}
|
||||||
|
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2, viaSync, dataLinks) => {
|
||||||
if (enableAnnotationCreation && timeRange2 != null) {
|
if (enableAnnotationCreation && timeRange2 != null) {
|
||||||
setNewAnnotationRange(timeRange2);
|
setNewAnnotationRange(timeRange2);
|
||||||
dismiss();
|
dismiss();
|
||||||
@ -131,6 +134,7 @@ export const StatusHistoryPanel = ({
|
|||||||
withDuration={false}
|
withDuration={false}
|
||||||
maxHeight={options.tooltip.maxHeight}
|
maxHeight={options.tooltip.maxHeight}
|
||||||
replaceVariables={replaceVariables}
|
replaceVariables={replaceVariables}
|
||||||
|
dataLinks={dataLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -106,7 +106,10 @@ export const TimeSeriesPanel = ({
|
|||||||
clientZoom={true}
|
clientZoom={true}
|
||||||
syncMode={cursorSync}
|
syncMode={cursorSync}
|
||||||
syncScope={eventsScope}
|
syncScope={eventsScope}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange2, viaSync) => {
|
getDataLinks={(seriesIdx: number, dataIdx: number) =>
|
||||||
|
alignedFrame.fields[seriesIdx]!.getLinks?.({ valueRowIndex: dataIdx }) ?? []
|
||||||
|
}
|
||||||
|
render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange2, viaSync, dataLinks) => {
|
||||||
if (enableAnnotationCreation && timeRange2 != null) {
|
if (enableAnnotationCreation && timeRange2 != null) {
|
||||||
setNewAnnotationRange(timeRange2);
|
setNewAnnotationRange(timeRange2);
|
||||||
dismiss();
|
dismiss();
|
||||||
@ -132,6 +135,7 @@ export const TimeSeriesPanel = ({
|
|||||||
annotate={enableAnnotationCreation ? annotate : undefined}
|
annotate={enableAnnotationCreation ? annotate : undefined}
|
||||||
maxHeight={options.tooltip.maxHeight}
|
maxHeight={options.tooltip.maxHeight}
|
||||||
replaceVariables={replaceVariables}
|
replaceVariables={replaceVariables}
|
||||||
|
dataLinks={dataLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
import { DataFrame, Field, FieldType, formattedValueToString, InterpolateFunction } from '@grafana/data';
|
import { DataFrame, Field, FieldType, formattedValueToString, InterpolateFunction, LinkModel } from '@grafana/data';
|
||||||
import { SortOrder, TooltipDisplayMode } from '@grafana/schema/dist/esm/common/common.gen';
|
import { SortOrder, TooltipDisplayMode } from '@grafana/schema/dist/esm/common/common.gen';
|
||||||
import { VizTooltipContent } from '@grafana/ui/src/components/VizTooltip/VizTooltipContent';
|
import { VizTooltipContent } from '@grafana/ui/src/components/VizTooltip/VizTooltipContent';
|
||||||
import { VizTooltipFooter } from '@grafana/ui/src/components/VizTooltip/VizTooltipFooter';
|
import { VizTooltipFooter } from '@grafana/ui/src/components/VizTooltip/VizTooltipFooter';
|
||||||
@ -9,7 +9,7 @@ import { VizTooltipWrapper } from '@grafana/ui/src/components/VizTooltip/VizTool
|
|||||||
import { VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types';
|
import { VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types';
|
||||||
import { getContentItems } from '@grafana/ui/src/components/VizTooltip/utils';
|
import { getContentItems } from '@grafana/ui/src/components/VizTooltip/utils';
|
||||||
|
|
||||||
import { getDataLinks, getFieldActions } from '../status-history/utils';
|
import { getFieldActions } from '../status-history/utils';
|
||||||
import { fmt } from '../xychart/utils';
|
import { fmt } from '../xychart/utils';
|
||||||
|
|
||||||
import { isTooltipScrollable } from './utils';
|
import { isTooltipScrollable } from './utils';
|
||||||
@ -37,6 +37,7 @@ export interface TimeSeriesTooltipProps {
|
|||||||
maxHeight?: number;
|
maxHeight?: number;
|
||||||
|
|
||||||
replaceVariables?: InterpolateFunction;
|
replaceVariables?: InterpolateFunction;
|
||||||
|
dataLinks: LinkModel[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TimeSeriesTooltip = ({
|
export const TimeSeriesTooltip = ({
|
||||||
@ -50,6 +51,7 @@ export const TimeSeriesTooltip = ({
|
|||||||
annotate,
|
annotate,
|
||||||
maxHeight,
|
maxHeight,
|
||||||
replaceVariables,
|
replaceVariables,
|
||||||
|
dataLinks,
|
||||||
}: TimeSeriesTooltipProps) => {
|
}: TimeSeriesTooltipProps) => {
|
||||||
const xField = series.fields[0];
|
const xField = series.fields[0];
|
||||||
const xVal = formattedValueToString(xField.display!(xField.values[dataIdxs[0]!]));
|
const xVal = formattedValueToString(xField.display!(xField.values[dataIdxs[0]!]));
|
||||||
@ -78,10 +80,9 @@ export const TimeSeriesTooltip = ({
|
|||||||
if (isPinned && seriesIdx != null) {
|
if (isPinned && seriesIdx != null) {
|
||||||
const field = series.fields[seriesIdx];
|
const field = series.fields[seriesIdx];
|
||||||
const dataIdx = dataIdxs[seriesIdx]!;
|
const dataIdx = dataIdxs[seriesIdx]!;
|
||||||
const links = getDataLinks(field, dataIdx);
|
|
||||||
const actions = getFieldActions(series, field, replaceVariables!, dataIdx);
|
const actions = getFieldActions(series, field, replaceVariables!, dataIdx);
|
||||||
|
|
||||||
footer = <VizTooltipFooter dataLinks={links} actions={actions} annotate={annotate} />;
|
footer = <VizTooltipFooter dataLinks={dataLinks} actions={actions} annotate={annotate} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerItem: VizTooltipItem | null = xField.config.custom?.hideFrom?.tooltip
|
const headerItem: VizTooltipItem | null = xField.config.custom?.hideFrom?.tooltip
|
||||||
|
@ -119,7 +119,10 @@ export const TrendPanel = ({
|
|||||||
hoverMode={
|
hoverMode={
|
||||||
options.tooltip.mode === TooltipDisplayMode.Single ? TooltipHoverMode.xOne : TooltipHoverMode.xAll
|
options.tooltip.mode === TooltipDisplayMode.Single ? TooltipHoverMode.xOne : TooltipHoverMode.xAll
|
||||||
}
|
}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned = false) => {
|
getDataLinks={(seriesIdx: number, dataIdx: number) =>
|
||||||
|
alignedDataFrame.fields[seriesIdx]!.getLinks?.({ valueRowIndex: dataIdx }) ?? []
|
||||||
|
}
|
||||||
|
render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange, viaSync, dataLinks) => {
|
||||||
return (
|
return (
|
||||||
<TimeSeriesTooltip
|
<TimeSeriesTooltip
|
||||||
series={alignedDataFrame}
|
series={alignedDataFrame}
|
||||||
@ -130,6 +133,7 @@ export const TrendPanel = ({
|
|||||||
isPinned={isPinned}
|
isPinned={isPinned}
|
||||||
maxHeight={options.tooltip.maxHeight}
|
maxHeight={options.tooltip.maxHeight}
|
||||||
replaceVariables={replaceVariables}
|
replaceVariables={replaceVariables}
|
||||||
|
dataLinks={dataLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
Loading…
Reference in New Issue
Block a user