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

Samples: Sync axes and tooltips #17875

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft

Conversation

TorsteinHonsi
Copy link
Collaborator

A continuation of the topic of the blog post How to synchronize the axes of multiple charts.

The following adjustments are made:

  • No master chart. Zooming on either chart is reflected on all others. Initial extremes are set as the union of all charts' extremes instead of the master.
  • One common Reset Zoom button.
  • Tooltips are synchronized.
  • The tickPositions are not hard set, instead allowed to be calculated based on the chart size and the synchronized min and max.

See the preview here.

@highsoft-bot
Copy link
Collaborator

File size comparison

No differences found

@highsoft-bot
Copy link
Collaborator

highsoft-bot commented Oct 21, 2022

Visual test results - Differences found

Found 1 diffing sample(s). Please review the differences.


Samples changed

Change type Sample
Modified samples/highcharts/blog/synchronize-axes-multiple-charts/demo.js
Modified samples/highcharts/blog/synchronize-axes-multiple-charts/demo.js
Modified samples/highcharts/blog/synchronize-axes-multiple-charts/demo.js
Modified samples/highcharts/blog/synchronize-axes-multiple-charts/demo.js
Modified samples/highcharts/blog/synchronize-axes-multiple-charts/demo.js
Modified samples/highcharts/blog/synchronize-axes-multiple-charts/demo.js

@rdp1414
Copy link

rdp1414 commented Oct 24, 2022

Hello,

Thanks for addressing the changes. In our use-case, all the synced charts have equal plot-area size - See fiddle. I have 3 queries on which please give your thoughts:

  1. When the data ranges are little apart, say - 1st chart range is [0, 100], 2nd chart range is [10, 110], ..., then upon zoom and reset-zoom, charts don't go back to their state when charts were initially rendered - See fiddle.
  2. When the data plotted in charts are quite apart, say - 1st chart range is [0, 100], 2nd chart range is [50, 150], ..., then even in their initial render, 1st chart's yAxis is not in sync with other chart's yAxis - See fiddle.

Initial extremes are set as the union of all charts' extremes instead of the master.

Till how far the data ranges in charts can be?

  1. For the charts laid out in a row - See fiddle. We want to share a common yAxis: Labels and title of only the left-most chart of a row are present and not others- See fiddle. But as you can see that there are 2 issues here. Can you please suggest something here?

    1. The yAxis labels disabled for 2nd and 3rd chart are causing wide gaps between.
    2. The yAxis title of 1st (leftmost) chart is cut.
  2. In the demo, I see you used tooltip.refresh callback. Now, Highcharts.addEvent will apply the tooltip.refresh callback to all charts in the page (even if there're charts which are not a part of this project). If we want to add this tooltip.resfresh callback locally to the charts, but I couldn't find any option like tooltip.events.refresh.

  3. In the original demo - See fiddle (all charts of equal width), if we make 2 small changes - See fiddle:

    1. Instead of zoomType: 'xy', we have zoomType: 'x'.
    2. Have data in increasing order (which is a popular use-case) because we often have charts showing accumulated PnL of stocks.

    There is one problem: If you zoom into any chart in the x-range [0, 10], correspondingly y-range doesn't change which happens in a normal chart - See fiddle. I don't think this has any relation with increasing order of data or anything - When zoom-type is x, then corresponding y values don't change their range which happens in normal chart.

    Basically in such zoomed case (please tell if you disagree), the x-range of connected charts should be equal to x-range of zoomed range. For the y-range, we should take a global min-max of y-range in that zoomed x-range among all connected charts, i.e. basically re-using the same logic used for initial render.

@TorsteinHonsi
Copy link
Collaborator Author

  1. Fixed, see d99429c . With this change, we synchronize the axes not only on initial render, but also after zooming out.

  2. When setting min and max, the exact layout of ticks depends on what is rendered from before. To make it more predictable, try setting a tickAmount setting to all Y axes - see jsfiddle

  3. It is one setting that causes both these effects:
    marginLeft: 50, // Keep all charts left aligned
    This setting is there to assure vertical alignment. But in this case you don’t want vertical alignment, so you can either remove it from the global options, or set it to undefined in the individual chart options. See fiddle.

  4. Currently this event is not in the options structure. However, you can add it to chart instances like this:

const chart = Highcharts.chart();
Highcharts.addEvent(chart.tooltip, ‘refresh’, myHandler);

Optionally, you can set a custom option to identify the charts that are part of the tooltip sync, and check that in the common handler.

  1. What happens is that the y axes are kept synchronized, which is how we set up this demo. I agree it would make sense, when zoomType === 'x', that only the x axes were synchronized. Then all charts would zoom to the same x extremes, but the y axes would respond to the individual charts' data extremes. This would also apply to initial values. If this is what you'd expect, then I can modify the demo to assure greater granularity. Perhaps we should even introduce a custom option to assign a sync-group to every axis. That way we could group charts with different levels of synchronization. What do you think about that?

@rdp1414
Copy link

rdp1414 commented Oct 27, 2022

Hello,

Thanks for the first 4 points - Many queries are solved.

If this is what you'd expect, then I can modify the demo to assure greater granularity.

Yes, that would be desirable. If granularity is not achieved i.e. yAxis doesn't modify in x-axis range [0, 10] (see fiddle) as it does in normal chart (see fiddle) then the intent of user to "zoom" gets defeated, I think.

Perhaps we should even introduce a custom option to assign a sync-group to every axis. That way we could group charts with different levels of synchronization. What do you think about that?

If I understand correctly; please correct me if not: After initial synchronization, zoom, reset-zoom, etc (all which is done in the demo now), invoke a function which does -

  1. Loop through each axis (over multiple charts) which are shared and get the max series (data) value plotted on that axis in the current view.
  2. Calculate the maximum among those maximums (say maxDataMax).
  3. Similarly for minimums (say minDataMin).
  4. Then apply setExtremes(minDataMin, maxDataMax) to any one of the axis because the already axes synchronization logic in place will sync it to other connected axes as well. Here, we should be careful about unwanted feedbacks, etc.

If you can share a demo which achieves granularity, that'll be helpful.

@TorsteinHonsi
Copy link
Collaborator Author

Hi @rdp1414 , sorry for the late reply!

In the latest commit, I implemented a custom.syncGroup option. I think it is a promising approach. Please see the live demo on jsFiddle and see what you think. Instructions in the fiddle.

@highsoft-bot
Copy link
Collaborator

Webpack monitoring

LGTM 👍

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.

None yet

3 participants