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

fix: trigger onZoom from zoomScale #889

Merged
merged 1 commit into from
Nov 17, 2024
Merged

fix: trigger onZoom from zoomScale #889

merged 1 commit into from
Nov 17, 2024

Conversation

kurkle
Copy link
Member

@kurkle kurkle commented Nov 17, 2024

fix #775

@kurkle kurkle added the bug label Nov 17, 2024
Copy link

Size Change: +12 B (+0.06%)

Total Size: 20.5 kB

Filename Size Change
dist/chartjs-plugin-zoom.esm.js 7.44 kB +2 B (+0.03%)
dist/chartjs-plugin-zoom.js 7.58 kB +4 B (+0.05%)
dist/chartjs-plugin-zoom.min.js 5.51 kB +6 B (+0.11%)

compressed-size-action

@kurkle kurkle merged commit 08844c2 into master Nov 17, 2024
12 checks passed
@kurkle kurkle deleted the fix/zoom-scale branch November 17, 2024 23:50
@yubiuser
Copy link
Contributor

This update broke our use case and I don't know how to mitigate the new behavior. We basically have the same situation as described as in #768:

We have a time series bar chart with only positive y-values. When zooming, y-axis should stay fixed at zero, because it does not make sense to lose the zero anchor. We basically used onZoom to trigger chart.zoomScale to set the new scale with fixed y min to zero.

Screenshot from 2024-11-19 17-40-09

But with this change, this causes an endless loop. Any idea how to circumvent this?

Old code

      onZoom: function ({ chart }) {
        // The first time the chart is zoomed, save the maximum initial scale bound
        if (!chart.absMax) chart.absMax = chart.getInitialScaleBounds().y.max;
        // Calculate the maximum value to be shown for the current zoom level
        const zoomMax = chart.absMax / chart.getZoomLevel();
        // Update the y axis scale
        chart.zoomScale("y", { min: 0, max: zoomMax }, "default");
        // Update the y axis ticks and round values to natural numbers
        chart.options.scales.y.ticks.callback = function (value) {
          return value.toFixed(0);
        };

@kurkle
Copy link
Member Author

kurkle commented Nov 19, 2024

Instead of calling zoomScale from onZoom, just specify min: 0 in the y-scale options?

Or, you can just update the scale directly:

chart.options.scales.y.min = 0;
chart.options.scales.y.max = chart.absMax / chart.getZoomLevel(); // probably not needed
chart.update();

@yubiuser
Copy link
Contributor

Instead of calling zoomScale from onZoom, just specify min: 0 in the y-scale options?

This does not work, as it specifies the minimum, but not the maximal minimum (it doesn't get negative).


chart.options.scales.y.min = 0;
chart.options.scales.y.max = chart.absMax / chart.getZoomLevel(); // probably not needed
chart.update();

This works, but gives an unpleasant scale jump
Peek 2024-11-20 07-49

Before it was smooth
Peek 2024-11-20 07-55

@kurkle
Copy link
Member Author

kurkle commented Nov 20, 2024

maybe chart.update('none') produces similar result?

@yubiuser
Copy link
Contributor

Yes, but now I can only zoom in, and not zoom out again.

      onZoom: function ({ chart }) {
        chart.options.scales.y.min = 0;
        chart.update('none');
        }

@kurkle
Copy link
Member Author

kurkle commented Nov 22, 2024

I've created #901 for letting you do something like:

      onZoom: function ({ chart, trigger }) {
        if (trigger === 'api') {
          // Ignore onZoom triggered by the chart.zoomScale api call below
          return;
        }
        // The first time the chart is zoomed, save the maximum initial scale bound
        if (!chart.absMax) chart.absMax = chart.getInitialScaleBounds().y.max;
        // Calculate the maximum value to be shown for the current zoom level
        const zoomMax = chart.absMax / chart.getZoomLevel();
        // Update the y axis scale
        chart.zoomScale("y", { min: 0, max: zoomMax }, "default");
        // Update the y axis ticks and round values to natural numbers
        chart.options.scales.y.ticks.callback = function (value) {
          return value.toFixed(0);
        };

@yubiuser
Copy link
Contributor

Perfect. Tested it locally compiled and it works like charm.

Peek 2024-11-23 09-10

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

Successfully merging this pull request may close these issues.

onZoom callbacks for zoomScale function
2 participants