I'm putting a chart (made using Chart.js) inside a CSS grid, and I want the chart to responsively fill the full width of its grid cell. However, even after turning on responsive
and turning off maintainAspectRatio
for the chart, the chart does not redraw to fill the container if the viewport is widened enough.
To reproduce:
<main>
<div id="chart-container">
<canvas id="chart"></canvas>
</div>
<div id="other">Some other data here</div>
</main>
<style>
main {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas:
'chart chart more';
}
#chart-container {
grid-area: chart;
}
#other {
grid-area: more;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const chartElement = document.getElementById('chart');
new Chart(chartElement, {
type: 'line',
responsive: true,
maintainAspectRatio: false,
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June'],
datasets: [{
label: 'Sample Data',
data: [17, 15, 8, 2, 12, 19]
}]
}
});
</script>
Here are screenshots with grid lines turned on in the developer tools to illustrate the issue.
If I add width: 100%
to the container, there is no difference in the resizing. If I add width: 100%
to the canvas element, the chart becomes distorted (like when you resize an image horizontally but not vertically). I also added the following in an attempt to force the resize event to fire on the chart upon window resize, with no difference:
window.addEventListener('beforeprint', () => {
chartElement.resize();
})
I've been scouring the Chart.js documentation for other possible solutions, but haven't found any. Is there a way to make the chart redraw to take up the full grid cell width when the viewport is resized? Thanks in advance!
You can use the resize
event listener for that, and also you need to call the resize()
on the chart instance, not on chartElement
:
<script>
const chartElement = document.getElementById('chart');
const chartInstance = new Chart(chartElement,
// ...
);
window.addEventListener('resize', () => { chartInstance?.resize(); });
</script>