Timeseries: fix outside range stale state (#49633)

Co-authored-by: Todd Treece <todd.treece@grafana.com>
This commit is contained in:
Ryan McKinley
2022-05-25 14:19:56 -07:00
committed by GitHub
parent 1f85101787
commit df90393057
5 changed files with 22 additions and 13 deletions

View File

@@ -316,7 +316,7 @@ export const CandlestickPanel: React.FC<CandlestickPanelProps> = ({
/> />
)} )}
<OutsideRangePlugin config={config} range={timeRange} onChangeTimeRange={onChangeTimeRange} /> <OutsideRangePlugin config={config} onChangeTimeRange={onChangeTimeRange} />
</> </>
); );
}} }}

View File

@@ -118,7 +118,7 @@ export const StateTimelinePanel: React.FC<TimelinePanelProps> = ({
timeZone={timeZone} timeZone={timeZone}
renderTooltip={renderCustomTooltip} renderTooltip={renderCustomTooltip}
/> />
<OutsideRangePlugin config={config} range={timeRange} onChangeTimeRange={onChangeTimeRange} /> <OutsideRangePlugin config={config} onChangeTimeRange={onChangeTimeRange} />
</> </>
); );
}} }}

View File

@@ -72,7 +72,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} /> <OutsideRangePlugin config={config} onChangeTimeRange={onChangeTimeRange} />
</> </>
); );
}} }}

View File

@@ -138,7 +138,7 @@ export const TimeSeriesPanel: React.FC<TimeSeriesPanelProps> = ({
/> />
)} )}
<OutsideRangePlugin config={config} range={timeRange} onChangeTimeRange={onChangeTimeRange} /> <OutsideRangePlugin config={config} onChangeTimeRange={onChangeTimeRange} />
</> </>
); );
}} }}

View File

@@ -1,34 +1,43 @@
import React, { useLayoutEffect, useRef } from 'react'; import React, { useLayoutEffect, useRef, useState } from 'react';
import uPlot from 'uplot'; import uPlot, { TypedArray, Scale } from 'uplot';
import { TimeRange, AbsoluteTimeRange } from '@grafana/data'; import { AbsoluteTimeRange } from '@grafana/data';
import { UPlotConfigBuilder, Button } from '@grafana/ui'; import { UPlotConfigBuilder, Button } from '@grafana/ui';
interface ThresholdControlsPluginProps { interface ThresholdControlsPluginProps {
config: UPlotConfigBuilder; config: UPlotConfigBuilder;
range: TimeRange;
onChangeTimeRange: (timeRange: AbsoluteTimeRange) => void; onChangeTimeRange: (timeRange: AbsoluteTimeRange) => void;
} }
export const OutsideRangePlugin: React.FC<ThresholdControlsPluginProps> = ({ config, range, onChangeTimeRange }) => { export const OutsideRangePlugin: React.FC<ThresholdControlsPluginProps> = ({ config, onChangeTimeRange }) => {
const plotInstance = useRef<uPlot>(); const plotInstance = useRef<uPlot>();
const [timevalues, setTimeValues] = useState<number[] | TypedArray>([]);
const [timeRange, setTimeRange] = useState<Scale | undefined>();
useLayoutEffect(() => { useLayoutEffect(() => {
config.addHook('init', (u) => { config.addHook('init', (u) => {
plotInstance.current = u; plotInstance.current = u;
}); });
config.addHook('setScale', (u) => {
setTimeValues(u.data?.[0] ?? []);
setTimeRange(u.scales['x'] ?? undefined);
});
}, [config]); }, [config]);
const timevalues = plotInstance.current?.data?.[0]; if (timevalues.length < 2 || !onChangeTimeRange) {
if (!timevalues || !plotInstance.current || timevalues.length < 2 || !onChangeTimeRange) { return null;
}
if (!timeRange || !timeRange.time || !timeRange.min || !timeRange.max!) {
return null; return null;
} }
// Time values are always sorted for uPlot to work // Time values are always sorted for uPlot to work
const first = timevalues[0]; const first = timevalues[0];
const last = timevalues[timevalues.length - 1]; const last = timevalues[timevalues.length - 1];
const fromX = range.from.valueOf(); const fromX = timeRange.min;
const toX = range.to.valueOf(); const toX = timeRange.max;
// (StartA <= EndB) and (EndA >= StartB) // (StartA <= EndB) and (EndA >= StartB)
if (first <= toX && last >= fromX) { if (first <= toX && last >= fromX) {