Fix chart container sizing warnings

This commit is contained in:
Evan Yang
2026-03-07 18:15:44 +08:00
parent eb46651373
commit 326a0086b7
+66 -4
View File
@@ -48,22 +48,84 @@ function ChartContainer({
}) {
const uniqueId = React.useId();
const chartId = `chart-${id || uniqueId.replace(/:/g, '')}`;
const containerRef = React.useRef<HTMLDivElement>(null);
const [containerSize, setContainerSize] = React.useState({
width: 0,
height: 0,
});
React.useLayoutEffect(() => {
const element = containerRef.current;
if (!element) {
return;
}
const updateSize = (width: number, height: number) => {
setContainerSize((current) => {
if (current.width === width && current.height === height) {
return current;
}
return { width, height };
});
};
const measure = () => {
const rect = element.getBoundingClientRect();
updateSize(rect.width, rect.height);
};
measure();
if (typeof ResizeObserver === 'undefined') {
return;
}
const observer = new ResizeObserver((entries) => {
const entry = entries[0];
if (!entry) {
return;
}
updateSize(entry.contentRect.width, entry.contentRect.height);
});
observer.observe(element);
return () => observer.disconnect();
}, []);
const hasUsableSize = containerSize.width > 0 && containerSize.height > 0;
const initialDimension = React.useMemo(
() => ({
width: Math.max(1, Math.round(containerSize.width)),
height: Math.max(1, Math.round(containerSize.height)),
}),
[containerSize.height, containerSize.width]
);
return (
<ChartContext.Provider value={{ config }}>
<div
ref={containerRef}
data-slot='chart'
data-chart={chartId}
className={cn(
"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border aspect-video min-h-0 min-w-0 text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
className
)}
{...props}
>
<ChartStyle id={chartId} config={config} />
<RechartsPrimitive.ResponsiveContainer>
{children}
</RechartsPrimitive.ResponsiveContainer>
{hasUsableSize ? (
<RechartsPrimitive.ResponsiveContainer
width='100%'
height='100%'
minWidth={0}
minHeight={0}
initialDimension={initialDimension}
>
{children}
</RechartsPrimitive.ResponsiveContainer>
) : null}
</div>
</ChartContext.Provider>
);