chartjs-plugin-zoom icon indicating copy to clipboard operation
chartjs-plugin-zoom copied to clipboard

Extend onZoom and onPan callbacks for syncing multiple charts

Open vbackeberg opened this issue 6 months ago • 5 comments

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.

  • 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: https://github.com/chartjs/chartjs-plugin-zoom/issues/238#issuecomment-2002819777

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 avatar Apr 02 '25 11:04 vbackeberg