Prevent unnecessary chart and board component re-renders
This commit is contained in:
1 parent
1f0de47c01
commit
400a35d7af
4 files changed
+104
-22
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { useTheme } from '@umami/react-zen';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { memo, useCallback, useMemo, useState } from 'react';
|
||||
import { Chart, type ChartProps } from '@/components/charts/Chart';
|
||||
import { ChartTooltip } from '@/components/charts/ChartTooltip';
|
||||
import { useLocale } from '@/components/hooks';
|
||||
@@ -8,6 +8,8 @@ import { getThemeColors } from '@/lib/colors';
|
||||
import { DATE_FORMATS, formatDate } from '@/lib/date';
|
||||
import { formatLongCurrency, formatLongNumber } from '@/lib/format';
|
||||
|
||||
const MemoChart = memo(Chart);
|
||||
|
||||
const dateFormats = {
|
||||
millisecond: 'T',
|
||||
second: 'pp',
|
||||
@@ -32,7 +34,13 @@ export interface BarChartProps extends ChartProps {
|
||||
maxDate?: Date;
|
||||
}
|
||||
|
||||
export function BarChart({
|
||||
interface TooltipState {
|
||||
title: string;
|
||||
color?: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
function BarChartComponent({
|
||||
chartData,
|
||||
renderXLabel,
|
||||
renderYLabel,
|
||||
@@ -45,7 +53,7 @@ export function BarChart({
|
||||
currency,
|
||||
...props
|
||||
}: BarChartProps) {
|
||||
const [tooltip, setTooltip] = useState(null);
|
||||
const [tooltip, setTooltip] = useState<TooltipState | null>(null);
|
||||
const { theme } = useTheme();
|
||||
const { locale } = useLocale();
|
||||
const { colors } = useMemo(() => getThemeColors(theme), [theme]);
|
||||
@@ -94,13 +102,23 @@ export function BarChart({
|
||||
},
|
||||
},
|
||||
};
|
||||
}, [chartData, colors, unit, stacked, renderXLabel, renderYLabel]);
|
||||
}, [
|
||||
colors,
|
||||
unit,
|
||||
stacked,
|
||||
renderXLabel,
|
||||
renderYLabel,
|
||||
minDate,
|
||||
maxDate,
|
||||
locale,
|
||||
XAxisType,
|
||||
YAxisType,
|
||||
]);
|
||||
|
||||
const handleTooltip = ({ tooltip }: { tooltip: any }) => {
|
||||
const { opacity, labelColors, dataPoints } = tooltip;
|
||||
|
||||
setTooltip(
|
||||
opacity
|
||||
const handleTooltip = useCallback(
|
||||
({ tooltip }: { tooltip: any }) => {
|
||||
const { opacity, labelColors, dataPoints } = tooltip;
|
||||
const nextTooltip = opacity
|
||||
? {
|
||||
title: formatDate(
|
||||
new Date(dataPoints[0].raw?.d || dataPoints[0].raw?.x || dataPoints[0].raw),
|
||||
@@ -112,13 +130,26 @@ export function BarChart({
|
||||
? formatLongCurrency(dataPoints[0].raw.y, currency)
|
||||
: `${formatLongNumber(dataPoints[0].raw.y)} ${dataPoints[0].dataset.label}`,
|
||||
}
|
||||
: null,
|
||||
);
|
||||
};
|
||||
: null;
|
||||
|
||||
setTooltip(prev => {
|
||||
if (
|
||||
prev?.title === nextTooltip?.title &&
|
||||
prev?.color === nextTooltip?.color &&
|
||||
prev?.value === nextTooltip?.value
|
||||
) {
|
||||
return prev;
|
||||
}
|
||||
|
||||
return nextTooltip;
|
||||
});
|
||||
},
|
||||
[currency, locale, unit],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Chart
|
||||
<MemoChart
|
||||
{...props}
|
||||
type="bar"
|
||||
chartData={chartData}
|
||||
@@ -129,3 +160,7 @@ export function BarChart({
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const BarChart = memo(BarChartComponent);
|
||||
|
||||
BarChart.displayName = 'BarChart';
|
||||
Reference in new issue
Block a user