mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Viz: get UPlotChart out of the timeRange business (#70412)
This commit is contained in:
parent
ce6f73bd32
commit
1db0ace5e7
@ -5303,9 +5303,7 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "2"],
|
[0, 0, 0, "Do not use any type assertions.", "2"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
|
||||||
[0, 0, 0, "Do not use any type assertions.", "4"],
|
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
|
|
||||||
],
|
],
|
||||||
"public/app/plugins/panel/live/LiveChannelEditor.tsx:5381": [
|
"public/app/plugins/panel/live/LiveChannelEditor.tsx:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
|
@ -248,7 +248,7 @@ export class GraphNG extends Component<GraphNGProps, GraphNGState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { width, height, children, timeRange, renderLegend } = this.props;
|
const { width, height, children, renderLegend } = this.props;
|
||||||
const { config, alignedFrame, alignedData } = this.state;
|
const { config, alignedFrame, alignedData } = this.state;
|
||||||
|
|
||||||
if (!config) {
|
if (!config) {
|
||||||
@ -263,7 +263,6 @@ export class GraphNG extends Component<GraphNGProps, GraphNGState> {
|
|||||||
data={alignedData!}
|
data={alignedData!}
|
||||||
width={vizWidth}
|
width={vizWidth}
|
||||||
height={vizHeight}
|
height={vizHeight}
|
||||||
timeRange={timeRange}
|
|
||||||
plotRef={(u) => ((this.plotInstance as React.MutableRefObject<uPlot>).current = u)}
|
plotRef={(u) => ((this.plotInstance as React.MutableRefObject<uPlot>).current = u)}
|
||||||
>
|
>
|
||||||
{children ? children(config, alignedFrame) : null}
|
{children ? children(config, alignedFrame) : null}
|
||||||
|
@ -202,9 +202,7 @@ export class Sparkline extends PureComponent<SparklineProps, State> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, configBuilder } = this.state;
|
const { data, configBuilder } = this.state;
|
||||||
const { width, height, sparkline } = this.props;
|
const { width, height } = this.props;
|
||||||
return (
|
return <UPlotChart data={data} config={configBuilder} width={width} height={height} />;
|
||||||
<UPlotChart data={data} config={configBuilder} width={width} height={height} timeRange={sparkline.timeRange!} />
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import createMockRaf from 'mock-raf';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
|
|
||||||
import { dateTime, FieldConfig, FieldType, MutableDataFrame } from '@grafana/data';
|
import { FieldConfig, FieldType, MutableDataFrame } from '@grafana/data';
|
||||||
import { GraphFieldConfig, GraphDrawStyle } from '@grafana/schema';
|
import { GraphFieldConfig, GraphDrawStyle } from '@grafana/schema';
|
||||||
|
|
||||||
import { UPlotChart } from './Plot';
|
import { UPlotChart } from './Plot';
|
||||||
@ -49,15 +49,9 @@ const mockData = () => {
|
|||||||
} as FieldConfig<GraphFieldConfig>,
|
} as FieldConfig<GraphFieldConfig>,
|
||||||
});
|
});
|
||||||
|
|
||||||
const timeRange = {
|
|
||||||
from: dateTime(1602673200000),
|
|
||||||
to: dateTime(1602680400000),
|
|
||||||
raw: { from: '1602673200000', to: '1602680400000' },
|
|
||||||
};
|
|
||||||
|
|
||||||
const config = new UPlotConfigBuilder();
|
const config = new UPlotConfigBuilder();
|
||||||
config.addSeries({} as SeriesProps);
|
config.addSeries({} as SeriesProps);
|
||||||
return { data: data, timeRange, config };
|
return { data: data, config };
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('UPlotChart', () => {
|
describe('UPlotChart', () => {
|
||||||
@ -73,13 +67,12 @@ describe('UPlotChart', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('destroys uPlot instance when component unmounts', () => {
|
it('destroys uPlot instance when component unmounts', () => {
|
||||||
const { data, timeRange, config } = mockData();
|
const { data, config } = mockData();
|
||||||
|
|
||||||
const { unmount } = render(
|
const { unmount } = render(
|
||||||
<UPlotChart
|
<UPlotChart
|
||||||
data={preparePlotData2(data, getStackingGroups(data))} // mock
|
data={preparePlotData2(data, getStackingGroups(data))} // mock
|
||||||
config={config}
|
config={config}
|
||||||
timeRange={timeRange}
|
|
||||||
width={100}
|
width={100}
|
||||||
height={100}
|
height={100}
|
||||||
/>
|
/>
|
||||||
@ -92,13 +85,12 @@ describe('UPlotChart', () => {
|
|||||||
|
|
||||||
describe('data update', () => {
|
describe('data update', () => {
|
||||||
it('skips uPlot reinitialization when there are no field config changes', () => {
|
it('skips uPlot reinitialization when there are no field config changes', () => {
|
||||||
const { data, timeRange, config } = mockData();
|
const { data, config } = mockData();
|
||||||
|
|
||||||
const { rerender } = render(
|
const { rerender } = render(
|
||||||
<UPlotChart
|
<UPlotChart
|
||||||
data={preparePlotData2(data, getStackingGroups(data))} // mock
|
data={preparePlotData2(data, getStackingGroups(data))} // mock
|
||||||
config={config}
|
config={config}
|
||||||
timeRange={timeRange}
|
|
||||||
width={100}
|
width={100}
|
||||||
height={100}
|
height={100}
|
||||||
/>
|
/>
|
||||||
@ -112,7 +104,6 @@ describe('UPlotChart', () => {
|
|||||||
<UPlotChart
|
<UPlotChart
|
||||||
data={preparePlotData2(data, getStackingGroups(data))} // changed
|
data={preparePlotData2(data, getStackingGroups(data))} // changed
|
||||||
config={config}
|
config={config}
|
||||||
timeRange={timeRange}
|
|
||||||
width={100}
|
width={100}
|
||||||
height={100}
|
height={100}
|
||||||
/>
|
/>
|
||||||
@ -124,15 +115,9 @@ describe('UPlotChart', () => {
|
|||||||
|
|
||||||
describe('config update', () => {
|
describe('config update', () => {
|
||||||
it('skips uPlot intialization for width and height equal 0', async () => {
|
it('skips uPlot intialization for width and height equal 0', async () => {
|
||||||
const { data, timeRange, config } = mockData();
|
const { data, config } = mockData();
|
||||||
const { queryAllByTestId } = render(
|
const { queryAllByTestId } = render(
|
||||||
<UPlotChart
|
<UPlotChart data={preparePlotData2(data, getStackingGroups(data))} config={config} width={0} height={0} />
|
||||||
data={preparePlotData2(data, getStackingGroups(data))}
|
|
||||||
config={config}
|
|
||||||
timeRange={timeRange}
|
|
||||||
width={0}
|
|
||||||
height={0}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(queryAllByTestId('uplot-main-div')).toHaveLength(1);
|
expect(queryAllByTestId('uplot-main-div')).toHaveLength(1);
|
||||||
@ -140,13 +125,12 @@ describe('UPlotChart', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('reinitializes uPlot when config changes', () => {
|
it('reinitializes uPlot when config changes', () => {
|
||||||
const { data, timeRange, config } = mockData();
|
const { data, config } = mockData();
|
||||||
|
|
||||||
const { rerender } = render(
|
const { rerender } = render(
|
||||||
<UPlotChart
|
<UPlotChart
|
||||||
data={preparePlotData2(data, getStackingGroups(data))} // frame
|
data={preparePlotData2(data, getStackingGroups(data))} // frame
|
||||||
config={config}
|
config={config}
|
||||||
timeRange={timeRange}
|
|
||||||
width={100}
|
width={100}
|
||||||
height={100}
|
height={100}
|
||||||
/>
|
/>
|
||||||
@ -161,7 +145,6 @@ describe('UPlotChart', () => {
|
|||||||
<UPlotChart
|
<UPlotChart
|
||||||
data={preparePlotData2(data, getStackingGroups(data))}
|
data={preparePlotData2(data, getStackingGroups(data))}
|
||||||
config={nextConfig}
|
config={nextConfig}
|
||||||
timeRange={timeRange}
|
|
||||||
width={100}
|
width={100}
|
||||||
height={100}
|
height={100}
|
||||||
/>
|
/>
|
||||||
@ -172,13 +155,12 @@ describe('UPlotChart', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('skips uPlot reinitialization when only dimensions change', () => {
|
it('skips uPlot reinitialization when only dimensions change', () => {
|
||||||
const { data, timeRange, config } = mockData();
|
const { data, config } = mockData();
|
||||||
|
|
||||||
const { rerender } = render(
|
const { rerender } = render(
|
||||||
<UPlotChart
|
<UPlotChart
|
||||||
data={preparePlotData2(data, getStackingGroups(data))} // frame
|
data={preparePlotData2(data, getStackingGroups(data))} // frame
|
||||||
config={config}
|
config={config}
|
||||||
timeRange={timeRange}
|
|
||||||
width={100}
|
width={100}
|
||||||
height={100}
|
height={100}
|
||||||
/>
|
/>
|
||||||
@ -189,7 +171,6 @@ describe('UPlotChart', () => {
|
|||||||
<UPlotChart
|
<UPlotChart
|
||||||
data={preparePlotData2(data, getStackingGroups(data))} // frame
|
data={preparePlotData2(data, getStackingGroups(data))} // frame
|
||||||
config={config}
|
config={config}
|
||||||
timeRange={timeRange}
|
|
||||||
width={200}
|
width={200}
|
||||||
height={200}
|
height={200}
|
||||||
/>
|
/>
|
||||||
|
@ -16,16 +16,6 @@ function sameConfig(prevProps: PlotProps, nextProps: PlotProps) {
|
|||||||
return nextProps.config === prevProps.config;
|
return nextProps.config === prevProps.config;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sameTimeRange(prevProps: PlotProps, nextProps: PlotProps) {
|
|
||||||
let prevTime = prevProps.timeRange;
|
|
||||||
let nextTime = nextProps.timeRange;
|
|
||||||
|
|
||||||
return (
|
|
||||||
prevTime === nextTime ||
|
|
||||||
(nextTime.from.valueOf() === prevTime.from.valueOf() && nextTime.to.valueOf() === prevTime.to.valueOf())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
type UPlotChartState = {
|
type UPlotChartState = {
|
||||||
plot: uPlot | null;
|
plot: uPlot | null;
|
||||||
};
|
};
|
||||||
@ -100,11 +90,6 @@ export class UPlotChart extends Component<PlotProps, UPlotChartState> {
|
|||||||
this.reinitPlot();
|
this.reinitPlot();
|
||||||
} else if (!sameData(prevProps, this.props)) {
|
} else if (!sameData(prevProps, this.props)) {
|
||||||
plot?.setData(this.props.data as AlignedData);
|
plot?.setData(this.props.data as AlignedData);
|
||||||
} else if (!sameTimeRange(prevProps, this.props)) {
|
|
||||||
plot?.setScale('x', {
|
|
||||||
min: this.props.timeRange.from.valueOf(),
|
|
||||||
max: this.props.timeRange.to.valueOf(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import uPlot, { Options, AlignedData } from 'uplot';
|
import uPlot, { Options, AlignedData } from 'uplot';
|
||||||
|
|
||||||
import { TimeRange } from '@grafana/data';
|
|
||||||
|
|
||||||
import { UPlotConfigBuilder } from './config/UPlotConfigBuilder';
|
import { UPlotConfigBuilder } from './config/UPlotConfigBuilder';
|
||||||
|
|
||||||
export type PlotConfig = Pick<
|
export type PlotConfig = Pick<
|
||||||
@ -23,7 +21,6 @@ export interface PlotProps {
|
|||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
config: UPlotConfigBuilder;
|
config: UPlotConfigBuilder;
|
||||||
timeRange: TimeRange;
|
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
// Reference to uPlot instance
|
// Reference to uPlot instance
|
||||||
plotRef?: (u: uPlot) => void;
|
plotRef?: (u: uPlot) => void;
|
||||||
|
@ -192,7 +192,7 @@ export const HeatmapPanel = ({
|
|||||||
<>
|
<>
|
||||||
<VizLayout width={width} height={height} legend={renderLegend()}>
|
<VizLayout width={width} height={height} legend={renderLegend()}>
|
||||||
{(vizWidth: number, vizHeight: number) => (
|
{(vizWidth: number, vizHeight: number) => (
|
||||||
<UPlotChart config={builder} data={facets as any} width={vizWidth} height={vizHeight} timeRange={timeRange}>
|
<UPlotChart config={builder} data={facets as any} width={vizWidth} height={vizHeight}>
|
||||||
{/*children ? children(config, alignedFrame) : null*/}
|
{/*children ? children(config, alignedFrame) : null*/}
|
||||||
</UPlotChart>
|
</UPlotChart>
|
||||||
)}
|
)}
|
||||||
|
@ -323,13 +323,7 @@ export class Histogram extends React.Component<HistogramProps, State> {
|
|||||||
return (
|
return (
|
||||||
<VizLayout width={width} height={height} legend={this.renderLegend(config)}>
|
<VizLayout width={width} height={height} legend={this.renderLegend(config)}>
|
||||||
{(vizWidth: number, vizHeight: number) => (
|
{(vizWidth: number, vizHeight: number) => (
|
||||||
<UPlotChart
|
<UPlotChart config={this.state.config!} data={this.state.alignedData} width={vizWidth} height={vizHeight}>
|
||||||
config={this.state.config!}
|
|
||||||
data={this.state.alignedData}
|
|
||||||
width={vizWidth}
|
|
||||||
height={vizHeight}
|
|
||||||
timeRange={null as any}
|
|
||||||
>
|
|
||||||
{children ? children(config, alignedFrame) : null}
|
{children ? children(config, alignedFrame) : null}
|
||||||
</UPlotChart>
|
</UPlotChart>
|
||||||
)}
|
)}
|
||||||
|
@ -1,15 +1,7 @@
|
|||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import {
|
import { DataFrame, Field, formattedValueToString, getFieldDisplayName, GrafanaTheme2, LinkModel } from '@grafana/data';
|
||||||
DataFrame,
|
|
||||||
Field,
|
|
||||||
formattedValueToString,
|
|
||||||
getFieldDisplayName,
|
|
||||||
GrafanaTheme2,
|
|
||||||
LinkModel,
|
|
||||||
TimeRange,
|
|
||||||
} from '@grafana/data';
|
|
||||||
import { LinkButton, useStyles2, VerticalGroup, VizTooltipOptions } from '@grafana/ui';
|
import { LinkButton, useStyles2, VerticalGroup, VizTooltipOptions } from '@grafana/ui';
|
||||||
import { findField } from 'app/features/dimensions';
|
import { findField } from 'app/features/dimensions';
|
||||||
import { getTitleFromHref } from 'app/features/explore/utils/links';
|
import { getTitleFromHref } from 'app/features/explore/utils/links';
|
||||||
@ -39,7 +31,6 @@ export interface Props {
|
|||||||
seriesMapping: SeriesMapping;
|
seriesMapping: SeriesMapping;
|
||||||
hoveredPointIndex: number; // the hovered point
|
hoveredPointIndex: number; // the hovered point
|
||||||
options: VizTooltipOptions;
|
options: VizTooltipOptions;
|
||||||
range: TimeRange;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TooltipView = ({
|
export const TooltipView = ({
|
||||||
@ -50,7 +41,6 @@ export const TooltipView = ({
|
|||||||
rowIndex,
|
rowIndex,
|
||||||
hoveredPointIndex,
|
hoveredPointIndex,
|
||||||
options,
|
options,
|
||||||
range,
|
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const style = useStyles2(getStyles);
|
const style = useStyles2(getStyles);
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ export const XYChartPanel2 = (props: Props) => {
|
|||||||
<>
|
<>
|
||||||
<VizLayout width={props.width} height={props.height} legend={renderLegend()}>
|
<VizLayout width={props.width} height={props.height} legend={renderLegend()}>
|
||||||
{(vizWidth: number, vizHeight: number) => (
|
{(vizWidth: number, vizHeight: number) => (
|
||||||
<UPlotChart config={builder} data={facets} width={vizWidth} height={vizHeight} timeRange={props.timeRange} />
|
<UPlotChart config={builder} data={facets} width={vizWidth} height={vizHeight} />
|
||||||
)}
|
)}
|
||||||
</VizLayout>
|
</VizLayout>
|
||||||
<Portal>
|
<Portal>
|
||||||
@ -252,7 +252,6 @@ export const XYChartPanel2 = (props: Props) => {
|
|||||||
rowIndex={hover.xIndex}
|
rowIndex={hover.xIndex}
|
||||||
hoveredPointIndex={hover.scatterIndex}
|
hoveredPointIndex={hover.scatterIndex}
|
||||||
data={props.data.series}
|
data={props.data.series}
|
||||||
range={props.timeRange}
|
|
||||||
/>
|
/>
|
||||||
</VizTooltipContainer>
|
</VizTooltipContainer>
|
||||||
)}
|
)}
|
||||||
|
Loading…
Reference in New Issue
Block a user