Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.resize no longer works with explicit size #9049

Closed
joshkel opened this issue May 7, 2021 · 4 comments
Closed

.resize no longer works with explicit size #9049

joshkel opened this issue May 7, 2021 · 4 comments
Milestone

Comments

@joshkel
Copy link
Contributor

joshkel commented May 7, 2021

Expected and Current Behavior

Calling the .resize method with an explicit width and height no longer works after upgrading from Chart.js 3.1.1 to 3.2.0; it instead automatically sizes the chart to its current size.

Possible Solution

From stepping through the code with a debugger, the problem appears to have been introduced in #8928. (See here.) The if (me.options.responsive) { block within bindEvents causes resize() to be called with default arguments, which causes the just-set width and height to be reset.

Steps to Reproduce

See https://codepen.io/joshkel/pen/YzZPrjj.

When Chart.js 3.1.1 is loaded:

  • The Print button sizes the chart smaller.
  • The Resize button causes the chart to flicker to the smaller size, then it's immediately resized (which is fine for my purposes - I only need it to be the smaller size long enough to print).

When Chart.js 3.2.0 or 3.2.1 is loaded:

  • The Print button causes the chart to print at its screen size, even though I'm trying to use beforeprint to resize it.
  • The Resize button has no visible effect.

Context

I'm using an explicit width and height as part of responsive printing support. (And that approach to printing does feel like a bit of a hack - see #8149 - so if there's a better approach here, please let me know.)

Environment

  • Chart.js version: observed in 3.2.0 and 3.2.1
  • Browser name and version: Chrome 90.0.4430.93
@kurkle
Copy link
Member

kurkle commented May 7, 2021

Right, the sets are never equal on a responsive chart, because of resize and detach listeners (and potentially attach).
Maybe the fix would be to ignore those listeners when comparing the sets.

@kurkle kurkle added this to the Version 3.3 milestone May 7, 2021
joshkel added a commit to joshkel/Chart.js that referenced this issue May 7, 2021
Because `this._listeners` may contain both event handlers from options and internal event handlers for responsive support, the `setsEqual` check would often fail, causing event handlers to be unnecessarily detached and reattached and fired.

If I'm understanding correctly, this is the root cause of chartjs#9049.
@joshkel
Copy link
Contributor Author

joshkel commented May 7, 2021

Thanks. I started creating a PR for this; see #9050.

However, if I'm understanding the code correctly, ignoring those listeners may introduce another issue; right now, the update method is able to bind / unbind the attach/detatch/resize events if the responsive option changes, and after this change, it will no longer detect that.

Is Chart.js supposed to update its events when responsive changes? I was trying to think of a good way to implement that; one idea is to have two separate _listeners objects, one for standard events and one for responsive-related events. Then the update method can call unbind + rebind if either the _listeners keys no longer match events or if the _responsiveListeners state no longer matches the responsive option. Would that make sense?

@kurkle
Copy link
Member

kurkle commented May 7, 2021

@joshkel I think your suggestion of two separate sets would be most maintainable solution

@joshkel
Copy link
Contributor Author

joshkel commented May 7, 2021

@kurkle Thanks. I updated the PR; feedback welcome.

etimberg pushed a commit that referenced this issue May 10, 2021
* Fix detecting changed events

Because `this._listeners` may contain both event handlers from options and internal event handlers for responsive support, the `setsEqual` check would often fail, causing event handlers to be unnecessarily detached and reattached and fired.

If I'm understanding correctly, this is the root cause of #9049.

* Use a separate object for responsive listeners

Correctly update events when responsive property changes as well as when requested events change.

* Code review feedback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants