question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Wrong chart size when using `throttled`

See original GitHub issue

Expected 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:closed
  • Created 10 months ago
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
abaksha-sccommented, Dec 6, 2022

@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:

export function throttled<TArgs extends Array<any>>(
  fn: (...args: TArgs) => void,
  thisArg: any,
) {
  let ticking = false;
  let argsToUse = [];

  return function(...args: TArgs) {
    // Save the args for use later
    argsToUse = Array.from(args) as TArgs;
    if (!ticking) {
      ticking = true;
      requestAnimFrame.call(window, () => {
        ticking = false;
        fn.apply(thisArg, argsToUse);
      });
    }
  };
1reaction
kurklecommented, Dec 4, 2022

Sorry, my question was really to @etimberg and I was referring to this: https://github.com/chartjs/Chart.js/commit/e6892a92cba764b5c032e30d31393313e05b1031

Read more comments on GitHub >

github_iconTop Results From Across the Web

Microsoft Graph throttling guidance
Find best practices for maintaining optimal performance of the Microsoft Graph service if an overwhelming number of requests occurs.
Read more >
Avoid throttling & implement throttling strategies - YouTube
... to avoid being throttled by Microsoft Graph. This video is part of a series in a playlist and is associated with a...
Read more >
Microsoft Graph API, Throttling & SharePoint Lists/Libraries
I came up against a strange and somewhat misleading one this week which is worth being aware of if you are using the...
Read more >
How to optimize cpu consumption in d3js responsive bar chart ...
1. Throttling: the chart doesn't resizes at every browser resizing events, with timeout i can set how miliseconds i want to skip. window....
Read more >
Rate Limits - Graph API - Meta for Developers - Facebook
When an app or user has reached their rate limit, requests made by that app or user will fill and the API will...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found