"responsive" option problem since v4
Expected behavior
Chart should be resized when window size changes. (now it resizes only when scaling to smaller resolution)
Current behavior
I am using "responsive" option to resize chart based on it's parent container size. Everything works while scaling window size down, but when it comes to changing window resolution to larger one that doesn't work.
Reproducible sample
https://codepen.io/ouqu5/pen/ZEjEPqm
Optional extra steps/info to reproduce
- Resize window to mobile/tablet (chart resizes properly)
- Resize it back to full screen (chart is not resized)
Possible solution
No response
Context
No response
chart.js version
4.1.1
Browser name and version
No response
Link to your project
No response
Hi ouqu5, have you tried to set the option maintainAspectRatio to false? And also, you will probably need to set the width and height in the parent container, not in the canvas element.
Read this docs about responsiveness: Responsive charts, read the important note about responsive charts and also check this example which is full responsive.
I know that maintainAspectRatio fixes this problem but it should work event with this option enabled. I've followed all steps in docs so my chart setup is 100% valid.
Example you've send works because it's using chart.js 3.5.1 version while problem occurs only from version 4 of this library.
@ouqu5 the example also works with the latest version
There is indeed an issue with version 4.x. When reducing size of container, it works. But not when increasing. Last working version 3.9.1.
@igomonteiro example works only because of maintainAspectRatio: false. Try enabling it, as it is by default.
seeing this issue as well, with 4.1.1. in most cases. I would think this should work regardless of what maintainAspectRatio is set to.
Any update on this? Still appears to be an issue in 4.2.0
From my experience you have to define the height of the container, too, now. maintainAspectRatio respects container height.
By setting an aspect-ratio on the containing div I was able to get the same responsiveness for graphs using an aspect ratio. This confuses me because it seems like maintainAspectRatio should control the size of the canvas because if I wanted to size the container I would just size the container in the first place.
Have this issue as well.
I've had this issue as well—I have found a workaround, however. I'm using MUI specifically.
As long as the chart has a sibling that consumes space inside its parent, auto-resizing works. As soon as the chart sits alone in a parent, it will resize down but not up.
This does not work:
return (
<Box>
<Chart
type="bar"
datasetIdKey="name" // the dataset property to use as the unique identifier for the data set. See: https://react-chartjs-2.js.org/docs/working-with-datasets/
options={options}
data={data}
plugins={[legendExtraMargin]}
/>
</Box>
This does not work:
return (
<Box>
<div />
<Chart
type="bar"
datasetIdKey="name" // the dataset property to use as the unique identifier for the data set. See: https://react-chartjs-2.js.org/docs/working-with-datasets/
options={options}
data={data}
plugins={[legendExtraMargin]}
/>
</Box>
This does work:
return (
<Box>
<div> </div>
<Chart
type="bar"
datasetIdKey="name" // the dataset property to use as the unique identifier for the data set. See: https://react-chartjs-2.js.org/docs/working-with-datasets/
options={options}
data={data}
plugins={[legendExtraMargin]}
/>
</Box>
YMMV but hopefully this workaround helps. Obviously, being forced to display something is not ideal, but you could adjust the size of the rendered element to mitigate. Interestingly, making it very small (max-height: 1px, font-size: 1px, or line-height: 0.1) causes the resize to animate very slowly ¯\(ツ)/¯
I was able to fix this without setting an exact container height by defining an aspect-ratio instead. The default aspect ratio for Chart.js is 2, so doing this restores Chart.js 3 behaviour:
<div class="chart-container" style="aspect-ratio: 2">
<canvas id="chart"></canvas>
</div>
I would suggest just to fix it instead of using workarounds. This is maybe not critical but important issue.
Bumping this issue.
If I pass an onResize function to the options array of a chart component, like onResize: () => {console.log('Resizing chart')}, I am experiencing that the function fires when scaling the chart down, but it doesn't fire when the viewport scales up.
I was able to fix this without setting an exact container height by defining an aspect-ratio instead. The default aspect ratio for Chart.js is 2, so doing this restores Chart.js 3 behaviour:
<div class="chart-container" style="aspect-ratio: 2"> <canvas id="chart"></canvas> </div>
@athisun 's workaround worked for me
Also onResize() is never being called for me with responsive: true...
On version 4.2.1
I created a duplicate ticket for this issue (I didn't see this ticket prior to creating that one). I created a couple of Stackblitz demos to show the behavior working in 3.9.1 and not working in 4.3.0. I figured I'd cross-post them here:
Here's the 3.9.1 version, where responsiveness works: https://stackblitz.com/edit/angular-9rtbka
...And here's the 4.3.0 version, where responsiveness doesn't work (I also tried with 4.2.1, and got the same behavior): https://stackblitz.com/edit/angular-bcncvn
As noted above, responsiveness works when the browser width shrinks, but the chart doesn't expand as the browser width grows.
Hope this helps! Thanks!
For me the event was only being triggered when my viewport increased in size, and the height property never seemed to update, only the width.
I was able to fix the issue with with this workaround:
canvas {
width: 100% !important;
height: 100% !important;
}
For what it's worth, I'm using Vue.js and including my charts with PrimeVue. The version of chart.js is v4.3.0.
If you're using this fix then the styles need adding globally.
I'll throw my hat into this. I have the problem, I - for the life of mine - can not get it to shrink. At all. The example demo seems to work with all relative values, but when I do use percentages in my Angular (+ Tailwind) project, it does not.
<!-- This works! -->
<div class="chart-container w-[80vw] h-[300px]">
<canvas #chart [id]="chartId" aria-label="Chart" role="img">
<p>Chart could not be loaded</p>
</canvas>
</div>
However...
<!-- This works! -->
<div class="chart-container w-[100%] h-[300px]">
<canvas #chart [id]="chartId" aria-label="Chart" role="img">
<p>Chart could not be loaded</p>
</canvas>
</div>
Does not.
I - for the life of mine - can not get it to shrink
@akleimrey This is likely since the new resize behaviour prioritizes maintaining the container height. Have you tried the above method of setting an aspect ratio instead of a height and width? https://github.com/chartjs/Chart.js/issues/11005#issuecomment-1475697112
I - for the life of mine - can not get it to shrink
@akleimrey This is likely since the new resize behaviour prioritizes maintaining the container height. Have you tried the above method of setting an aspect ratio instead of a height and width? #11005 (comment)
@athisun I did but to no result. But in a perfect "Rubber Duck" problem-solving moment, I got a bit closer to my problem. My problem is the flexbox, but I can't simply replace my solution. It basically looks currently like this:
<div id="main" class="flex flex-col min-h-[100%] dark:bg-dark-background dark:text-background">
<app-header></app-header>
<div id="content" class="lg:w-[75rem] mx-auto">
<router-outlet>
</router-outlet>
</div>
<app-footer></app-footer>
</div>
And my dashboard page looks rather simple like that:
<app-map></app-map>
<app-chart [plugins]="plugin" chartType="HORIZONTAL_BAR"></app-chart>
<app-chart [plugins]="plugin2" chartType="BAR"></app-chart>
With a single chart component just looking like this:
<div class="chart-container w-[90%] h-[300px]">
<canvas #chart [id]="chartId" aria-label="Chart" role="img">
<p>Chart could not be loaded</p>
</canvas>
</div>
So, the div with the id main is mostly used to at least occupy 100% space but is also used to always at the minimum have the footer at the bottom, without having to define positions. If the content is larger, the page grows nicely. I'm going through solutions to make this work, but apparently, there is no single simple solution ever.
None of these are permanent solutions, though, right? We have a clear regression in behavior from 3.9 to 4.x when it comes to how responsive charts behave (in particular, when the browser increases in width). There are no indications in the documentation that this is a breaking change--if there were a documented best practice going forward (e.g., some kind of different CSS on the canvas or parent tag), then I think we could all happily upgrade. So until we hear otherwise, this just feels like a bug that needs to get addressed at the library level, rather than library consumers figuring out workarounds which may or may not work.
If I've missed something, and there really is documentation that this is a breaking change and we need to invoke our charts in a different fashion, I retract my above statement.
For me the event was only being triggered when my viewport increased in size, and the height property never seemed to update, only the width.
I was able to fix the issue with with this workaround:
canvas { width: 100% !important; height: 100% !important; }For what it's worth, I'm using Vue.js and including my charts with PrimeVue. The version of chart.js is
v4.3.0.If you're using this fix then the styles need adding globally.
This worked for me using PrimeVue 3.25.0 and chart.js 4.3.0.
I am also observing the fact that the options.onResize function is only called when the container gets smaller; it doesn't fire when the container gets larger.
I am also observing the onResize function getting called occasionally in an infinite loop when the container gets smaller. I put a console.log in there and sometimes it logs 100s of times in a few seconds; it seems to catch itself if you continue resizing, but something occurs to make it decide to call onResize infinitely.
I have same behavior with css
table-layout: fixed
https://angular-chart-js-nhvr2v.stackblitz.io
When the view grows, charts grow accordingly, when view goes smaller, chart size doesn't change correctly. When outside change is triggered, ie. do onblur from input, chart sizes are correct again. What's more, if I try the workaround of setting canvas size, the behavior changes to the opposite, increasing doesn't work and decreasing does.
I tried to replicate my use case as closely as possible, but it is kind of extreme behavior, so maybe this is not the best example for the problem, but leaving it here anyway in case it helps. It is very stable solution though in the environment I use it, the decreasing size is the only problem.
I have the same problem. When responsive and maintaining aspect ratio the chart does not properly resize on expand. Collapsing works fine.
When the view grows, charts grow accordingly, when view goes smaller, chart size doesn't change correctly.
🐛 Same issue. You have to reload the page after an enlargement to get the correct size of the chart again.
📖 I using [email protected], [email protected] and [email protected].
Same issue. The chart scales down when page size reduces but does not properly expand when page size increases again. I have to reload the page to get back the correct size of the chart.
Example is shown here: https://www.teyanglau.com/ (on the nested radial chart)
This still appears to be a problem in 4.4. Is there any word at all on the status of this issue? I don't think I've seen any of the library maintainers chime in on this thread.
@etimberg Apologies for pinging you, but it would be great if you or one of the other maintainers could chime in on this issue. This seems like a clear regression from 3.9.x to 4.x.x, and it's preventing (at least) those of us on this thread from upgrading to 4.x of the library. I can't find anywhere in the docs that indicates this is a breaking change which involves some modification to how we invoke ChartJS for responsiveness.
Thanks!!
Had the same issue, and for me this proposal solved it - https://github.com/chartjs/Chart.js/issues/11243
So one thing to do was to use aspect-ratio in chart container:
Using the
aspect-ratioproperty it's possible to make a chart fit nicely within the parent container's width instead of the window size.
And what actually fixed the scaling issue when you resize the window to expand it - is to use overflow: hidden:
overflow: hiddenis also needed otherwise the height won't change and won't trigger a redraw.
<div class="chart-container" style="position: relative; width: 100%; aspect-ratio: 2/1; overflow: hidden;">
<canvas id="chart"></canvas>
</div>
That sounds like some sort of css issue, but still it should be addressed in some way by the Chart.js (as a fix, or in docs).
All credits goes to @PeterN !
ChartJS also has an aspect ratio attribute. Do you need to set both in order for this to work? Also, do things work correctly if you change the aspect ratio after load?