I work with [email protected] && [email protected] && react@19 and saw millions of similar questions in StackOverflow how to make the chart responsive, but I didn't figure out how to do it.
I have a lot of different charts, and I want them to fit 100% of their parent div, no matter what. That's all. Many times I see that in the first load the chart take 100% height and width, but in my app the client can change the height & width of "parent" div, and then it's no more responsive.
To reproduce the problem here is the code:
.App {
font-family: sans-serif;
text-align: center;
}
.parent {
height: 200px;
width: 600px;
background: red;
padding: 10px;
}
import { useEffect, useRef } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import "./styles.css";
const options = {
title: {
text: "My chart",
},
series: [
{
data: [1, 2, 3],
},
],
};
export default function App() {
const chartRef = useRef();
useEffect(() => {
const container = chartRef.current?.container.current;
container.style.height = "100%";
container.style.width = "100%";
chartRef.current?.chart.reflow();
}, [chartRef, chartRef.current]);
return (
<div className="App">
<h1>Hello to Highcahrts dynamic height problem</h1>
<div className="parent">
<HighchartsReact
highcharts={Highcharts}
options={options}
ref={chartRef}
/>
</div>
</div>
);
}
Link to codesandbox: https://codesandbox.io/p/sandbox/6jsx4p?file=%2Fsrc%2FApp.js%3A1%2C1-41%2C1
It simply overflows the parent div.
The docs says:
By default (when null) the height is calculated from the offset height of the containing element, or 400 pixels if the containing element's height is 0.
from: https://api.highcharts.com/highcharts/chart.height
So in the example above, the height of the arent is hardcoded 200px
, and still the chart somehow decide that the parent height is 0 and apply 400px
on the chart.
Any idea how to solve it?
To ensure Highcharts adapts to its parent container, observe size changes in the parent and trigger a chart reflow()
. This can be achieved using ResizeObserver
, as shown below:
import React, { useEffect, useRef } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import "./styles.css";
const options = {
title: {
text: "My chart",
},
series: [
{
data: [1, 2, 3],
},
],
};
export default function App() {
const chartRef = useRef(null);
const parentRef = useRef(null);
useEffect(() => {
const parent = parentRef.current;
if (parent && chartRef.current) {
const resizeObserver = new ResizeObserver(() => {
if (chartRef.current?.chart) {
chartRef.current.chart.reflow();
}
});
resizeObserver.observe(parent);
return () => {
resizeObserver.disconnect();
};
}
}, []);
return (
<div className="App">
<h1>Hello to Highcharts dynamic height problem</h1>
<div
ref={parentRef}
className="parent"
style={{
height: "200px",
width: "400px",
background: "red",
padding: "10px",
}}
>
<HighchartsReact
highcharts={Highcharts}
options={options}
ref={chartRef}
containerProps={{ style: { height: "100%", width: "100%" } }}
/>
</div>
</div>
);
}