From a1298d64a744abd61fadfe590816f9b7eb833352 Mon Sep 17 00:00:00 2001 From: Andreas Weyer Date: Tue, 10 Feb 2026 19:41:01 +0000 Subject: [PATCH] Fix invalid size error in chart causing crashes due to temporary invalid dimensions during mount/update --- src/components/simulation-chart.tsx | 21 +++++++++++++++++---- src/hooks/useElementSize.ts | 20 ++++++++++++++------ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/components/simulation-chart.tsx b/src/components/simulation-chart.tsx index e5fc212..d6983c7 100644 --- a/src/components/simulation-chart.tsx +++ b/src/components/simulation-chart.tsx @@ -76,6 +76,11 @@ const SimulationChart = React.memo(({ const containerRef = React.useRef(null); const { width: containerWidth } = useElementSize(containerRef, 150); + // Guard against invalid dimensions during initial render + const yAxisWidth = 80; + const minContainerWidth = yAxisWidth + 100; // Minimum 100px for chart area + const safeContainerWidth = Math.max(containerWidth, minContainerWidth); + // Track current theme for chart styling const [isDarkTheme, setIsDarkTheme] = React.useState(false); @@ -96,9 +101,8 @@ const SimulationChart = React.memo(({ return () => observer.disconnect(); }, []); - // Y-axis takes ~80px, scrollable area gets the rest - const yAxisWidth = 80; - const scrollableWidth = containerWidth - yAxisWidth; + // Calculate scrollable width using safe container width + const scrollableWidth = safeContainerWidth - yAxisWidth; // Calculate chart width for scrollable area const chartWidth = simDays <= dispDays @@ -106,7 +110,7 @@ const SimulationChart = React.memo(({ : Math.ceil((scrollableWidth / dispDays) * simDays); // Use shorter captions on narrow containers to reduce wrapping - const isCompactLabels = containerWidth < 640; // tweakable threshold for mobile + const isCompactLabels = safeContainerWidth < 640; // tweakable threshold for mobile // Precompute series labels with translations const seriesLabels = React.useMemo>(() => { @@ -446,6 +450,15 @@ const SimulationChart = React.memo(({ ); }, [seriesLabels]); + // Don't render chart if dimensions are invalid (prevents crash during initialization) + if (chartWidth <= 0 || scrollableWidth <= 0) { + return ( +
+

{t('loadingChart', { defaultValue: 'Loading chart...' })}

+
+ ); + } + // Render the chart return (
diff --git a/src/hooks/useElementSize.ts b/src/hooks/useElementSize.ts index 7ba656f..30bbef5 100644 --- a/src/hooks/useElementSize.ts +++ b/src/hooks/useElementSize.ts @@ -38,17 +38,25 @@ export function useElementSize( const element = ref.current; if (!element) return; - // Set initial size - setSize({ - width: element.clientWidth, - height: element.clientHeight, - }); + // Set initial size (guard against 0 dimensions) + const initialWidth = element.clientWidth; + const initialHeight = element.clientHeight; + + if (initialWidth > 0 && initialHeight > 0) { + setSize({ + width: initialWidth, + height: initialHeight, + }); + } // Use ResizeObserver for efficient element size tracking const resizeObserver = new ResizeObserver((entries) => { for (const entry of entries) { const { width, height } = entry.contentRect; - setSize({ width, height }); + // Guard against invalid dimensions + if (width > 0 && height > 0) { + setSize({ width, height }); + } } });