echarts icon indicating copy to clipboard operation
echarts copied to clipboard

[Bug] Connected Charts Zoom & Zoom reset behaviors are not consistent

Open ragava28 opened this issue 2 years ago • 5 comments

Version

5.4.2

Link to Minimal Reproduction

https://codepen.io/ragava28/pen/dyQPZNb?editors=0010

Steps to Reproduce

https://codepen.io/ragava28/pen/dyQPZNb?editors=0010

  1. Click on zoom button from toolbox in any chart.
  2. Which enables zoom in all connected charts , so users can zoom from any connected chart.
  3. After zooming , Zoom reset button gets enabled, but only from the chart in which user performed zoom in operation.
  4. It should also get enabled for all the connected charts .

Any suggestions to enable zoom reset for all the connected charts

Current Behavior

Zoom reset button gets enabled, but only from the chart in which user performed zoom in operation.

Expected Behavior

Zoom reset button should get enabled for all connected charts .

Environment

- OS:
- Browser:
- Framework:

Any additional comments?

image

We have connected charts as shown in above screen shot , in which each row is a line chart connected in x-axis, and we are hiding zoom & zoom reset for all other charts except 1st row.

As all are connected charts , user clicks on zoom button in 1st row chart from tool box, and he can zoom from any connected chart (like 2nd ,3rd ..etc.) , but zoom reset is working only from the chart which user has zoomed .

Any way to enable zoom reset on all charts. Any suggestion is well appreciated

ragava28 avatar Jun 08 '23 22:06 ragava28

The simple solution, since zoom/reset is shared, is to use only one toolbox for both charts.

helgasoft avatar Jun 09 '23 04:06 helgasoft

I already tried it, please see below sample . https://codepen.io/ragava28/pen/KKrwbYP?editors=0010

In the sample I removed toolbox code for chart 2 & kept it for chart1 & both charts are connected. after this change, Zoom & zoom reset both functionality are broken.

ragava28 avatar Jun 09 '23 14:06 ragava28

sorry, I meant "only one visible toolbox". But once hidden, zooming cannot be started on that second chart and has to be initiated always from the first. Which is a bad option. Since toolbox is a poor choice, why not do it thru dataZoom ? I think the following is pretty good UI, with or without the (first) visible dataZoom. And functionality is the same.

option1= {...
  toolbox: { feature: { restore:{} } },
  dataZoom: [{}, {type:'inside'}],
...}
option2= {...
  dataZoom: [{show:false}, {type:'inside'}],
...}

helgasoft avatar Jun 09 '23 18:06 helgasoft

these charts are going to have high data density , zooming using dataZoom will make it difficult for user to interact with charts. initially we had restore button(like shown in below example) in place of zoom reset, which was working fine , but we recently realized that restore removes newly added data(real time data) or objects like (mark line or mark area) after initial load of the chart.

https://codepen.io/ragava28/pen/LYXVNMJ?editors=0010

in above example chart 1 & 2 are connected charts and every 5 seconds a new sample gets added to the chart1. after loading few new samples, when we click on restore , it removes the newly added samples , until the next new sample shows up & we rebind the complete data object back to chart. because of this gap we are trying with zoom reset.

ragava28 avatar Jun 10 '23 13:06 ragava28

Hello,

I'd like to share a solid and extensible solution to the problem described in this issue — namely, the inconsistent behavior of the Zoom Reset button in grouped ECharts instances (echarts.connect), and the undesired side effects of using restore().

Problem Summary

Based on the issue and discussion, the core problem can be summarized as follows:

When zoom is applied via the toolbox on one chart in a connected group (echarts.connect), the zoom itself is synchronized across all linked charts (typically via shared xAxis). However, the Zoom Reset button becomes active and functional only on the chart where the zoom action was initially performed. Attempts to use a single shared toolbox for all charts often lead to UX issues or unexpected behavior — users lose the ability to interact with charts independently while maintaining synchronization. Using the embedded dataZoom (type "inside") offers synchronized zoom and reset functionality, but it lacks visual UI elements and is inconvenient for charts with dense data. The restore action resets the chart to its original state, but it also removes dynamically added data such as real-time points, annotations (markLine, markPoint), or runtime-injected series — making it unsuitable for interactive or live dashboards.

My Solution

This implementation provides a global zoom reset mechanism for all charts connected via echarts.connect() — while fully preserving dynamic chart state and real-time data.

Key Aspects:

  1. Charts are grouped using echarts.connect('group1') to enable synchronized zooming and tooltips.
  2. Each chart includes a standard toolbox with the dataZoom feature — no customization or overriding is required.
  3. A custom bindZoomReset() function listens to native canvas click events and detects clicks on the built-in Zoom Reset button (__title === "Zoom Reset").
  4. When detected, the function dispatches a dataZoom action to all charts in the group, applying a predefined zoom range (e.g. start: 0, end: 100).
  5. Crucially, this avoids using restore() — so dynamically appended data (e.g. via live updates) remains untouched.

Minimal Example

function bindZoomReset(charts, minX = 0, maxX = 100) {
  charts.forEach(chart => {
    chart.getZr().on('click', event => {
      if (event.target?.__title === 'Zoom Reset') {
        charts.forEach(c => {
          c.dispatchAction({
            type: 'dataZoom',
            start: minX,
            end: maxX
          });
        });
      }
    });
  });
}

// Basic usage with two connected charts
bindZoomReset([chart1, chart2]);

Full Example Overview

In the live demo, a slightly more scalable version is used:

const charts = [
  { chart: chart1, gen: i => [i, i, i] },
  { chart: chart2, gen: i => [i, i ** 2] }
];

bindZoomReset(charts.map(c => c.chart));

This pattern:

  • Cleanly separates chart logic from reset logic
  • Enables adding/removing charts without changing the function
  • Supports real-time updates by pairing each chart with a data generator
  • Keeps all charts responsive via a shared container (flexbox layout)

Live Demo

CodePen: Synchronized Zoom Reset Demo

Outcome

  • All connected charts reset zoom in sync when any chart’s Zoom Reset is clicked
  • Dynamic/live data is preserved (no use of restore())
  • Modular, extensible approach that works with any number of charts
  • Responsive layout ready for dashboards and embedded contexts

Final Note

I hope this solution addresses the challenge described by @ragava28 and offers a practical workaround for others encountering similar issues with zoom reset behavior in connected ECharts instances.

@Ovilia — if you find this approach reasonable, perhaps it could be considered for inclusion in the official documentation or utility layer. I'd be happy to collaborate further or polish it into a reusable plugin or example.

Thanks for your time and consideration!

Feel free to reach out via my GitHub profile if you'd like to discuss this further.

itshchen avatar May 30 '25 10:05 itshchen