Wrong chart size when using `throttled`
See original GitHub issueExpected behavior
All resizeObserver callbacks wrapped with throttled
and when resize calls then it should be called with the latest actual size of chart container.
Code is here: https://github.com/chartjs/Chart.js/blob/51441272a781ba575149b214933f0c5b4bafb6ab/src/platform/platform.dom.js#L193
Current behavior
Function throttled
just skips calls when it’s ticking
and when real function call performs then throttled function calls with not actual arguments.
Source of throttled
is here: https://github.com/chartjs/Chart.js/blob/51441272a781ba575149b214933f0c5b4bafb6ab/src/helpers/helpers.extras.ts#L26-L41
Reproducible sample
https://jsfiddle.net/fxcLgy7d/
It’s not easy to reproduce with real chart and resizeObserver so that just example provided how throttled
works with emulated resize calls.
Optional extra steps/info to reproduce
No response
Possible solution
Option #1. Just save latest arguments when throttled function calls: https://github.com/chartjs/Chart.js/blob/51441272a781ba575149b214933f0c5b4bafb6ab/src/helpers/helpers.extras.ts#L26
function throttled(fn, thisArg) {
let ticking = false;
let latestArgs;
return function(...args) {
latestArgs = args; // <-- save latest actual arguments
if (!ticking) {
ticking = true;
requestAnimFrame.call(window, ()=>{
ticking = false;
fn.apply(thisArg, latestArgs); // <-- call function with the latest actual arguments
});
}
};
}
Option #2. When listener of resize calls then always get actual size from getBoundingClientRect
:
https://github.com/chartjs/Chart.js/blob/51441272a781ba575149b214933f0c5b4bafb6ab/src/platform/platform.dom.js#L195
const resize = throttled((width, height) => {
const w = container.clientWidth;
const rect = container.getBoundingClientRect();
listener(rect.width, rect.height); // <-- use here actual size from `getBoundingClientRect` because while this throttled callback calls then size could be changed already (but resize skipped, because another throttled call is in progress)
if (w < container.clientWidth) {
listener();
}
}, window);
Context
In my project this leads to wrong size of chart
chart.js version
4.0.1
Browser name and version
Chrome 107
Link to your project
No response
Issue Analytics
- State:
- Created 10 months ago
- Comments:10 (6 by maintainers)
Top GitHub Comments
@etimberg , no. It will not work. Check here: https://jsfiddle.net/uhoL6cjz/ In your version
const argsToUse
will be saved to the closure of each function call.You need to level up this variable to move out from closure:
Sorry, my question was really to @etimberg and I was referring to this: https://github.com/chartjs/Chart.js/commit/e6892a92cba764b5c032e30d31393313e05b1031