diff --git a/src/core/chart-container.tsx b/src/core/chart-container.tsx
index 08e6a5cc..4ae559cb 100644
--- a/src/core/chart-container.tsx
+++ b/src/core/chart-container.tsx
@@ -68,7 +68,7 @@ export function ChartContainer({
const withMinHeight = (height: number) => Math.max(chartMinHeight ?? DEFAULT_CHART_MIN_HEIGHT, height) - heightOffset;
const measuredChartHeight = withMinHeight(measures.chart - measures.header - measures.footer);
const effectiveChartHeight = fitHeight ? measuredChartHeight : withMinHeight(chartHeight ?? DEFAULT_CHART_HEIGHT);
- const hasLegend = primaryLegend || secondaryLegend;
+ const hasLegend = !!(primaryLegend || secondaryLegend);
return (
) : (
{verticalAxisTitle}
{chart(effectiveChartHeight)}
@@ -125,10 +131,37 @@ export function ChartContainer({
);
}
+/**
+ * Computes the styles for the chart plot wrapper in the bottom/no-legend layout case.
+ * Includes visibility hiding when waiting for footer measurements with bottom legend.
+ * When fitHeight is enabled with a bottom legend, we must wait for the footer measurements to complete before
+ * we can compute the correct chart height. During this time, the chart is rendered but hidden with CSS.
+ */
+function getChartPlotWrapperStyles({
+ measures,
+ fitHeight,
+ hasLegend,
+ chartMinWidth,
+ legendPosition,
+}: {
+ hasLegend: boolean;
+ fitHeight?: boolean;
+ chartMinWidth?: number;
+ legendPosition: "bottom" | "side";
+ measures: { header: number; footer: number; chart: number };
+}): React.CSSProperties {
+ const needsFooterMeasure =
+ fitHeight && hasLegend && legendPosition !== "side" && measures.footer === 0 && measures.chart > 0;
+ return {
+ ...(needsFooterMeasure && { visibility: "hidden" }),
+ ...(chartMinWidth !== undefined && { minInlineSize: chartMinWidth }),
+ };
+}
+
// This hook combines 3 resize observer and does a small optimization to batch their updates in a single set-state.
function useContainerQueries() {
- const [measuresState, setMeasuresState] = useState({ ready: false, chart: 0, header: 0, footer: 0 });
- const measuresRef = useRef({ ready: false, chart: 0, header: 0, footer: 0 });
+ const [measuresState, setMeasuresState] = useState({ chart: 0, header: 0, footer: 0 });
+ const measuresRef = useRef({ chart: 0, header: 0, footer: 0 });
const measureDebounce = useRef(new DebouncedCall()).current;
const setMeasure = (type: "chart" | "header" | "footer", value: number) => {
measuresRef.current[type] = value;