mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Timeseries: add zoom to data button (#47862)
This commit is contained in:
parent
785145c045
commit
f4e285b8b4
@ -19,6 +19,7 @@ import { AxisProps } from '@grafana/ui/src/components/uPlot/config/UPlotAxisBuil
|
|||||||
import { prepareCandlestickFields } from './fields';
|
import { prepareCandlestickFields } from './fields';
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
import { PanelDataErrorView } from '@grafana/runtime';
|
import { PanelDataErrorView } from '@grafana/runtime';
|
||||||
|
import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin';
|
||||||
|
|
||||||
interface CandlestickPanelProps extends PanelProps<CandlestickOptions> {}
|
interface CandlestickPanelProps extends PanelProps<CandlestickOptions> {}
|
||||||
|
|
||||||
@ -311,6 +312,8 @@ export const CandlestickPanel: React.FC<CandlestickPanelProps> = ({
|
|||||||
onThresholdsChange={onThresholdsChange}
|
onThresholdsChange={onThresholdsChange}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<OutsideRangePlugin config={config} range={timeRange} onChangeTimeRange={onChangeTimeRange} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -6,6 +6,7 @@ import { TimelineChart } from './TimelineChart';
|
|||||||
import { prepareTimelineFields, prepareTimelineLegendItems } from './utils';
|
import { prepareTimelineFields, prepareTimelineLegendItems } from './utils';
|
||||||
import { StateTimelineTooltip } from './StateTimelineTooltip';
|
import { StateTimelineTooltip } from './StateTimelineTooltip';
|
||||||
import { getLastStreamingDataFramePacket } from 'app/features/live/data/StreamingDataFrame';
|
import { getLastStreamingDataFramePacket } from 'app/features/live/data/StreamingDataFrame';
|
||||||
|
import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin';
|
||||||
|
|
||||||
interface TimelinePanelProps extends PanelProps<TimelineOptions> {}
|
interface TimelinePanelProps extends PanelProps<TimelineOptions> {}
|
||||||
|
|
||||||
@ -114,6 +115,7 @@ export const StateTimelinePanel: React.FC<TimelinePanelProps> = ({
|
|||||||
timeZone={timeZone}
|
timeZone={timeZone}
|
||||||
renderTooltip={renderCustomTooltip}
|
renderTooltip={renderCustomTooltip}
|
||||||
/>
|
/>
|
||||||
|
<OutsideRangePlugin config={config} range={timeRange} onChangeTimeRange={onChangeTimeRange} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -5,6 +5,7 @@ import { StatusPanelOptions } from './types';
|
|||||||
import { TimelineChart } from '../state-timeline/TimelineChart';
|
import { TimelineChart } from '../state-timeline/TimelineChart';
|
||||||
import { TimelineMode } from '../state-timeline/types';
|
import { TimelineMode } from '../state-timeline/types';
|
||||||
import { prepareTimelineFields, prepareTimelineLegendItems } from '../state-timeline/utils';
|
import { prepareTimelineFields, prepareTimelineLegendItems } from '../state-timeline/utils';
|
||||||
|
import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin';
|
||||||
|
|
||||||
interface TimelinePanelProps extends PanelProps<StatusPanelOptions> {}
|
interface TimelinePanelProps extends PanelProps<StatusPanelOptions> {}
|
||||||
|
|
||||||
@ -68,6 +69,7 @@ export const StatusHistoryPanel: React.FC<TimelinePanelProps> = ({
|
|||||||
<>
|
<>
|
||||||
<ZoomPlugin config={config} onZoom={onChangeTimeRange} />
|
<ZoomPlugin config={config} onZoom={onChangeTimeRange} />
|
||||||
<TooltipPlugin data={alignedFrame} config={config} mode={options.tooltip.mode} timeZone={timeZone} />
|
<TooltipPlugin data={alignedFrame} config={config} mode={options.tooltip.mode} timeZone={timeZone} />
|
||||||
|
<OutsideRangePlugin config={config} range={timeRange} onChangeTimeRange={onChangeTimeRange} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -12,6 +12,7 @@ import { AnnotationEditorPlugin } from './plugins/AnnotationEditorPlugin';
|
|||||||
import { ThresholdControlsPlugin } from './plugins/ThresholdControlsPlugin';
|
import { ThresholdControlsPlugin } from './plugins/ThresholdControlsPlugin';
|
||||||
import { config } from 'app/core/config';
|
import { config } from 'app/core/config';
|
||||||
import { PanelDataErrorView } from '@grafana/runtime';
|
import { PanelDataErrorView } from '@grafana/runtime';
|
||||||
|
import { OutsideRangePlugin } from './plugins/OutsideRangePlugin';
|
||||||
|
|
||||||
interface TimeSeriesPanelProps extends PanelProps<TimeSeriesOptions> {}
|
interface TimeSeriesPanelProps extends PanelProps<TimeSeriesOptions> {}
|
||||||
|
|
||||||
@ -134,6 +135,8 @@ export const TimeSeriesPanel: React.FC<TimeSeriesPanelProps> = ({
|
|||||||
onThresholdsChange={onThresholdsChange}
|
onThresholdsChange={onThresholdsChange}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<OutsideRangePlugin config={config} range={timeRange} onChangeTimeRange={onChangeTimeRange} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
import React, { useLayoutEffect, useRef } from 'react';
|
||||||
|
import { TimeRange, AbsoluteTimeRange } from '@grafana/data';
|
||||||
|
import { UPlotConfigBuilder, Button } from '@grafana/ui';
|
||||||
|
import uPlot from 'uplot';
|
||||||
|
|
||||||
|
interface ThresholdControlsPluginProps {
|
||||||
|
config: UPlotConfigBuilder;
|
||||||
|
range: TimeRange;
|
||||||
|
onChangeTimeRange: (timeRange: AbsoluteTimeRange) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const OutsideRangePlugin: React.FC<ThresholdControlsPluginProps> = ({ config, range, onChangeTimeRange }) => {
|
||||||
|
const plotInstance = useRef<uPlot>();
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
config.addHook('init', (u) => {
|
||||||
|
plotInstance.current = u;
|
||||||
|
});
|
||||||
|
}, [config]);
|
||||||
|
|
||||||
|
const timevalues = plotInstance.current?.data?.[0];
|
||||||
|
if (!timevalues || !plotInstance.current || timevalues.length < 2 || !onChangeTimeRange) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time values are always sorted for uPlot to work
|
||||||
|
const first = timevalues[0];
|
||||||
|
const last = timevalues[timevalues.length - 1];
|
||||||
|
const fromX = range.from.valueOf();
|
||||||
|
const toX = range.to.valueOf();
|
||||||
|
|
||||||
|
// (StartA <= EndB) and (EndA >= StartB)
|
||||||
|
if (first <= toX && last >= fromX) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: '50%',
|
||||||
|
transform: 'translateY(-50%)',
|
||||||
|
width: '100%',
|
||||||
|
textAlign: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div>Data outside time range</div>
|
||||||
|
<Button onClick={(v) => onChangeTimeRange({ from: first, to: last })} variant="secondary">
|
||||||
|
Zoom to data
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
OutsideRangePlugin.displayName = 'OutsideRangePlugin';
|
Loading…
Reference in New Issue
Block a user