Fix chart performance issues and duplicate keys
- Memoize XAxisTick and YAxisTick renderers with useCallback - Remove Y-axis tickCount and allowDecimals=false to prevent duplicate keys - Add React.memo to SimulationChart with custom comparison - Remove unnecessary sorting after isFed and remove dose actions - Add handleActionWithoutSort for actions that don't affect order - Prevents double state updates that caused 'every other click' freezes
This commit is contained in:
@@ -52,7 +52,7 @@ const CHART_COLORS = {
|
||||
cursor: '#6b7280' // gray-500
|
||||
} as const;
|
||||
|
||||
const SimulationChart = ({
|
||||
const SimulationChart = React.memo(({
|
||||
combinedProfile,
|
||||
templateProfile,
|
||||
chartView,
|
||||
@@ -173,7 +173,8 @@ const SimulationChart = ({
|
||||
}, [totalHours, xTickInterval]);
|
||||
|
||||
// Custom tick renderer for x-axis to handle 12h/24h/continuous formats and dark mode
|
||||
const XAxisTick = (props: any) => {
|
||||
// Memoized to prevent unnecessary re-renders
|
||||
const XAxisTick = React.useCallback((props: any) => {
|
||||
const { x, y, payload } = props;
|
||||
const h = payload.value as number;
|
||||
let label: string;
|
||||
@@ -200,17 +201,18 @@ const SimulationChart = ({
|
||||
{label}
|
||||
</text>
|
||||
);
|
||||
};
|
||||
}, [showDayTimeOnXAxis, isDarkTheme, t]);
|
||||
|
||||
// Custom tick renderre for y-axis to handle dark mode
|
||||
const YAxisTick = (props: any) => {
|
||||
// Custom tick renderer for y-axis to handle dark mode
|
||||
// Memoized to prevent unnecessary re-renders
|
||||
const YAxisTick = React.useCallback((props: any) => {
|
||||
const { x, y, payload } = props;
|
||||
return (
|
||||
<text x={x} y={y + 4} textAnchor="end" fill={isDarkTheme ? '#ccc' : '#666'}>
|
||||
{payload.value}
|
||||
</text>
|
||||
);
|
||||
};
|
||||
}, [isDarkTheme]);
|
||||
|
||||
// Calculate Y-axis domain based on data and user settings
|
||||
const yAxisDomain = React.useMemo(() => {
|
||||
@@ -529,9 +531,7 @@ const SimulationChart = ({
|
||||
domain={yAxisDomain as any}
|
||||
axisLine={{ stroke: isDarkTheme ? '#ccc' : '#666' }}
|
||||
tick={<YAxisTick />}
|
||||
tickCount={16}
|
||||
interval={0}
|
||||
allowDecimals={false}
|
||||
allowDecimals={true}
|
||||
allowDataOverflow={false}
|
||||
/>
|
||||
<RechartsTooltip
|
||||
@@ -760,6 +760,27 @@ const SimulationChart = ({
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}, (prevProps, nextProps) => {
|
||||
// Custom comparison function to prevent unnecessary re-renders
|
||||
// Only re-render if relevant props actually changed
|
||||
return (
|
||||
prevProps.combinedProfile === nextProps.combinedProfile &&
|
||||
prevProps.templateProfile === nextProps.templateProfile &&
|
||||
prevProps.chartView === nextProps.chartView &&
|
||||
prevProps.showDayTimeOnXAxis === nextProps.showDayTimeOnXAxis &&
|
||||
prevProps.showDayReferenceLines === nextProps.showDayReferenceLines &&
|
||||
prevProps.showIntakeTimeLines === nextProps.showIntakeTimeLines &&
|
||||
prevProps.showTherapeuticRange === nextProps.showTherapeuticRange &&
|
||||
prevProps.therapeuticRange?.min === nextProps.therapeuticRange?.min &&
|
||||
prevProps.therapeuticRange?.max === nextProps.therapeuticRange?.max &&
|
||||
prevProps.simulationDays === nextProps.simulationDays &&
|
||||
prevProps.displayedDays === nextProps.displayedDays &&
|
||||
prevProps.yAxisMin === nextProps.yAxisMin &&
|
||||
prevProps.yAxisMax === nextProps.yAxisMax &&
|
||||
prevProps.days === nextProps.days
|
||||
);
|
||||
});
|
||||
|
||||
SimulationChart.displayName = 'SimulationChart';
|
||||
|
||||
export default SimulationChart;
|
||||
|
||||
Reference in New Issue
Block a user