BarChart: fix excessive re-renders during mousemove and panel resize (#45027)

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
Leon Sorokin 2022-02-08 16:32:23 -06:00 committed by GitHub
parent 7c0b453e19
commit b3b1f945b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 25 deletions

View File

@ -99,7 +99,7 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({ data, options, w
}, [options]); // change every time the options object changes (while editing)
const structureRev = useMemo(() => {
const f0 = info.viz;
const f0 = info.viz[0];
const f1 = frame0Ref.current;
if (!(f0 && f1 && compareDataFrameStructures(f0, f1, true))) {
structureRef.current++;
@ -132,7 +132,7 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({ data, options, w
}
}, [height, options.xTickLabelRotation, options.xTickLabelMaxLength]);
if (!info.viz?.fields.length) {
if (!info.viz[0]?.fields.length) {
return <PanelDataErrorView panelId={id} data={data} message={info.warn} needsNumberField={true} />;
}
@ -178,7 +178,7 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({ data, options, w
}
}
return <PlotLegend data={[info.viz]} config={config} maxHeight="35%" maxWidth="60%" {...options.legend} />;
return <PlotLegend data={info.viz} config={config} maxHeight="35%" maxWidth="60%" {...options.legend} />;
};
const rawValue = (seriesIdx: number, valueIdx: number) => {
@ -233,14 +233,14 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({ data, options, w
rawValue,
getColor,
fillOpacity,
allFrames: [info.viz],
allFrames: info.viz,
});
};
return (
<GraphNG
theme={theme}
frames={[info.viz]}
frames={info.viz}
prepConfig={prepConfig}
propsToDiff={propsToDiff}
preparePlotFrame={(f) => f[0]} // already processed in by the panel above!

View File

@ -69,9 +69,10 @@ export const plugin = new PanelPlugin<PanelOptions, BarChartFieldConfig>(BarChar
.setPanelOptions((builder, context) => {
const disp = prepareBarChartDisplayValues(context.data, config.theme2, context.options ?? ({} as any));
let xaxisPlaceholder = 'First string or time field';
if (disp.viz?.fields?.length) {
const first = disp.viz.fields[0];
xaxisPlaceholder += ` (${getFieldDisplayName(first, disp.viz)})`;
const viz = disp.viz ? disp.viz[0] : undefined;
if (viz?.fields?.length) {
const first = viz.fields[0];
xaxisPlaceholder += ` (${getFieldDisplayName(first, viz)})`;
}
builder

View File

@ -7,8 +7,11 @@ export interface BarChartDisplayValues {
/** All fields joined */
aligned: DataFrame;
/** The fields we can display, first field is X axis */
viz: DataFrame;
/**
* The fields we can display, first field is X axis.
* This needs to be an array to avoid extra re-initialization in GraphNG
*/
viz: [DataFrame];
/** Potentialy color by a field value */
colorByField?: Field;

View File

@ -185,7 +185,7 @@ describe('BarChart utils', () => {
});
const result = prepareBarChartDisplayValues([df], createTheme(), { stacking: StackingMode.None } as any);
const field = result.viz.fields[1];
const field = result.viz[0].fields[1];
expect(field!.values.toArray()).toMatchInlineSnapshot(`
Array [
-10,
@ -209,19 +209,19 @@ describe('BarChart utils', () => {
const resultAsc = prepareBarChartDisplayValues([frame], createTheme(), {
legend: { sortBy: 'Min', sortDesc: false },
} as any);
expect(resultAsc.viz.fields[0].type).toBe(FieldType.string);
expect(resultAsc.viz.fields[1].name).toBe('a');
expect(resultAsc.viz.fields[2].name).toBe('c');
expect(resultAsc.viz.fields[3].name).toBe('b');
} as any).viz[0];
expect(resultAsc.fields[0].type).toBe(FieldType.string);
expect(resultAsc.fields[1].name).toBe('a');
expect(resultAsc.fields[2].name).toBe('c');
expect(resultAsc.fields[3].name).toBe('b');
const resultDesc = prepareBarChartDisplayValues([frame], createTheme(), {
legend: { sortBy: 'Min', sortDesc: true },
} as any);
expect(resultDesc.viz.fields[0].type).toBe(FieldType.string);
expect(resultDesc.viz.fields[1].name).toBe('b');
expect(resultDesc.viz.fields[2].name).toBe('c');
expect(resultDesc.viz.fields[3].name).toBe('a');
} as any).viz[0];
expect(resultDesc.fields[0].type).toBe(FieldType.string);
expect(resultDesc.fields[1].name).toBe('b');
expect(resultDesc.fields[2].name).toBe('c');
expect(resultDesc.fields[3].name).toBe('a');
});
});
});

View File

@ -434,10 +434,12 @@ export function prepareBarChartDisplayValues(
return {
aligned: frame,
colorByField,
viz: {
length: firstField.values.length,
fields: fields, // ideally: fields.filter((f) => !Boolean(f.config.custom?.hideFrom?.viz)),
},
viz: [
{
length: firstField.values.length,
fields: fields, // ideally: fields.filter((f) => !Boolean(f.config.custom?.hideFrom?.viz)),
},
],
};
}