Skip to content

Extend onZoom and onPan callbacks for syncing multiple charts #933

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

vbackeberg
Copy link

@vbackeberg vbackeberg commented Apr 2, 2025

Purpose

onZoom and onPan callbacks now return additional data that is useful for syncing multiple charts.

Changes

  • onZoom returns the amount it zoomed.
  • onPan returns the delta it panned.

These values can be used to zoom/pan other charts by the same amount.
The values are basically piped through from the function args, so there is no additional computation.
As charts may only zoom/pan certain axis, the amount/delta returned will only set the values that were actually applied.

  • pan() receives a new PanTrigger parameter.

It can be used in the spirit of ZoomTrigger to distinguish between "api" and user interactions.
This is required to pan other charts when the user pans, but not trigger a loop through the subsequent programmatic calls to pan().

Example

function createChart(chart:Chart, chartElement: HTMLCanvasElement) {
  chart = new Chart(chartElement.getContext('2d')!, {
    type: 'line',
    data: { datasets: items },
    options: {
      plugins: {
        zoom: {
          pan: {
            enabled: true,
            mode: 'x',
            onPan: ({ chart, delta, trigger }) => {
              if (trigger === 'api') return;
              Object.values(Chart.instances).forEach((c) => {
                if (c.id !== chart.id) {
                  c.pan({ x: delta.x });
                }
              });
            }
          },
          zoom: {
            wheel: { enabled: true },
            mode: 'xy',
            onZoom: ({ chart, amount, trigger }) => {
              if (trigger === 'api' || amount === undefined) return;
              Object.values(Chart.instances).forEach((c) => {
                if (c.id !== chart.id) {
                  c.zoom(amount);
                }
              });
            }
          },
        },
      },
    }
  });
}

Background

So far there is no good way to sync zoom and pan across multiple charts that I could come up with or have found during my research.

The only approach I found was this from 2019:
#238 (comment)

The changes I propose solve the issue of syncing multiple charts in a simple way while not breaking anything.
I think it would be a good addition to the library that could help many others.

@vbackeberg vbackeberg changed the title Extend on zoom on pan callbacks Extend onZoom and onPan callbacks Apr 2, 2025
@vbackeberg vbackeberg changed the title Extend onZoom and onPan callbacks Extend onZoom and onPan callbacks for syncing multiple charts Apr 2, 2025
@vbackeberg vbackeberg marked this pull request as ready for review April 8, 2025 06:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants