PlotLegend: Memoize for better performance (#56123)

This commit is contained in:
kay delaney 2022-10-14 09:51:27 +01:00 committed by GitHub
parent 08ffcfdf16
commit e819ed0f51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 98 deletions

View File

@ -9,8 +9,8 @@ export interface Props extends React.HTMLAttributes<HTMLDivElement> {
gradient?: string;
}
export const SeriesIcon = React.forwardRef<HTMLDivElement, Props>(
({ color, className, gradient, ...restProps }, ref) => {
export const SeriesIcon = React.memo(
React.forwardRef<HTMLDivElement, Props>(({ color, className, gradient, ...restProps }, ref) => {
const theme = useTheme2();
let cssColor: string;
@ -36,7 +36,7 @@ export const SeriesIcon = React.forwardRef<HTMLDivElement, Props>(
};
return <div data-testid="series-icon" ref={ref} className={className} style={styles} {...restProps} />;
}
})
);
SeriesIcon.displayName = 'SeriesIcon';

View File

@ -110,4 +110,4 @@ export function VizLegend<T>({
}
}
VizLegend.displayName = 'Legend';
VizLegend.displayName = 'VizLegend';

View File

@ -15,7 +15,7 @@ interface Props {
/**
* @internal
*/
export const VizLegendSeriesIcon: React.FunctionComponent<Props> = ({ seriesName, color, gradient, readonly }) => {
export const VizLegendSeriesIcon = React.memo(({ seriesName, color, gradient, readonly }: Props) => {
const { onSeriesColorChange } = usePanelContext();
const onChange = useCallback(
(color: string) => {
@ -40,6 +40,6 @@ export const VizLegendSeriesIcon: React.FunctionComponent<Props> = ({ seriesName
);
}
return <SeriesIcon color={color} gradient={gradient} />;
};
});
VizLegendSeriesIcon.displayName = 'VizLegendSeriesIcon';

View File

@ -27,115 +27,110 @@ interface PlotLegendProps extends VizLegendOptions, Omit<VizLayoutLegendProps, '
config: UPlotConfigBuilder;
}
export const PlotLegend: React.FC<PlotLegendProps> = ({
data,
config,
placement,
calcs,
displayMode,
...vizLayoutLegendProps
}) => {
const theme = useTheme2();
const legendItems = config
.getSeries()
.map<VizLegendItem | undefined>((s) => {
const seriesConfig = s.props;
const fieldIndex = seriesConfig.dataFrameFieldIndex;
const axisPlacement = config.getAxisPlacement(s.props.scaleKey);
export const PlotLegend: React.FC<PlotLegendProps> = React.memo(
({ data, config, placement, calcs, displayMode, ...vizLayoutLegendProps }) => {
const theme = useTheme2();
const legendItems = config
.getSeries()
.map<VizLegendItem | undefined>((s) => {
const seriesConfig = s.props;
const fieldIndex = seriesConfig.dataFrameFieldIndex;
const axisPlacement = config.getAxisPlacement(s.props.scaleKey);
if (!fieldIndex) {
return undefined;
}
if (!fieldIndex) {
return undefined;
}
const field = data[fieldIndex.frameIndex]?.fields[fieldIndex.fieldIndex];
const field = data[fieldIndex.frameIndex]?.fields[fieldIndex.fieldIndex];
if (!field || field.config.custom?.hideFrom?.legend) {
return undefined;
}
if (!field || field.config.custom?.hideFrom?.legend) {
return undefined;
}
const label = getFieldDisplayName(field, data[fieldIndex.frameIndex]!, data);
const scaleColor = getFieldSeriesColor(field, theme);
const seriesColor = scaleColor.color;
const label = getFieldDisplayName(field, data[fieldIndex.frameIndex]!, data);
const scaleColor = getFieldSeriesColor(field, theme);
const seriesColor = scaleColor.color;
return {
disabled: !(seriesConfig.show ?? true),
fieldIndex,
color: seriesColor,
label,
yAxis: axisPlacement === AxisPlacement.Left ? 1 : 2,
getDisplayValues: () => {
if (!calcs?.length) {
return [];
}
const fmt = field.display ?? defaultFormatter;
let countFormatter: DisplayProcessor | null = null;
const fieldCalcs = reduceField({
field,
reducers: calcs,
});
return calcs.map<DisplayValue>((reducerId) => {
const fieldReducer = fieldReducers.get(reducerId);
let formatter = fmt;
if (fieldReducer.id === ReducerID.diffperc) {
formatter = getDisplayProcessor({
field: {
...field,
config: {
...field.config,
unit: 'percent',
},
},
theme,
});
return {
disabled: !(seriesConfig.show ?? true),
fieldIndex,
color: seriesColor,
label,
yAxis: axisPlacement === AxisPlacement.Left ? 1 : 2,
getDisplayValues: () => {
if (!calcs?.length) {
return [];
}
if (
fieldReducer.id === ReducerID.count ||
fieldReducer.id === ReducerID.changeCount ||
fieldReducer.id === ReducerID.distinctCount
) {
if (!countFormatter) {
countFormatter = getDisplayProcessor({
const fmt = field.display ?? defaultFormatter;
let countFormatter: DisplayProcessor | null = null;
const fieldCalcs = reduceField({
field,
reducers: calcs,
});
return calcs.map<DisplayValue>((reducerId) => {
const fieldReducer = fieldReducers.get(reducerId);
let formatter = fmt;
if (fieldReducer.id === ReducerID.diffperc) {
formatter = getDisplayProcessor({
field: {
...field,
config: {
...field.config,
unit: 'none',
unit: 'percent',
},
},
theme,
});
}
formatter = countFormatter;
}
return {
...formatter(fieldCalcs[reducerId]),
title: fieldReducer.name,
description: fieldReducer.description,
};
});
},
getItemKey: () => `${label}-${fieldIndex.frameIndex}-${fieldIndex.fieldIndex}`,
};
})
.filter((i) => i !== undefined) as VizLegendItem[];
if (
fieldReducer.id === ReducerID.count ||
fieldReducer.id === ReducerID.changeCount ||
fieldReducer.id === ReducerID.distinctCount
) {
if (!countFormatter) {
countFormatter = getDisplayProcessor({
field: {
...field,
config: {
...field.config,
unit: 'none',
},
},
theme,
});
}
formatter = countFormatter;
}
return (
<VizLayout.Legend placement={placement} {...vizLayoutLegendProps}>
<VizLegend
placement={placement}
items={legendItems}
displayMode={displayMode}
sortBy={vizLayoutLegendProps.sortBy}
sortDesc={vizLayoutLegendProps.sortDesc}
/>
</VizLayout.Legend>
);
};
return {
...formatter(fieldCalcs[reducerId]),
title: fieldReducer.name,
description: fieldReducer.description,
};
});
},
getItemKey: () => `${label}-${fieldIndex.frameIndex}-${fieldIndex.fieldIndex}`,
};
})
.filter((i) => i !== undefined) as VizLegendItem[];
return (
<VizLayout.Legend placement={placement} {...vizLayoutLegendProps}>
<VizLegend
placement={placement}
items={legendItems}
displayMode={displayMode}
sortBy={vizLayoutLegendProps.sortBy}
sortDesc={vizLayoutLegendProps.sortDesc}
/>
</VizLayout.Legend>
);
}
);
PlotLegend.displayName = 'PlotLegend';