highcharts / highcharts-vue

Other
686 stars 150 forks source link

Syncing Charts over the vuex store #83

Closed JonasGilg closed 5 years ago

JonasGilg commented 5 years ago

Hi, I am trying to sync multiple charts over the Vuex store. Here is my attempt: https://codesandbox.io/embed/vuex-store-x971v

When I zoom into the first chart, the other charts update as well, but if I zoom into another chart the first chart doesn't zoom in.

I would like to do this over the Vuex store, because I have a lot of charts and only need synchronized zoom on specific ones. Also I have other controls that control zoom, which also make use of the store.

Denyllon commented 5 years ago

Hello @TheJhonny007 ,

Thank you for reporting the issue. We have been taking a closer look on your case, but need a bit more time to familiarize with it, because it's quite complex. If there will be any updates, then I will let you know about that.

Kind regards!

Denyllon commented 5 years ago

Hello @TheJhonny007 ,

Thank you for your patience. The most recommended way to implement synchronized charts with Vuex, is by defining a separate extremes within component's data, and using Axis.setExtremes() to set the new extremes values, when those has changed. Setting extremes like on the example attached above (changing the xAxis.min and max directly in a configuration object) is not guarantee that the charts will be synchronized correctly.

In conclusion, first of all, please add the ref into your chart component:

<template>
  <div>
    <highcharts :options="chartOptions" ref="chart"></highcharts>
  </div>
</template>

Then, your component should be configured in the following way:

watch: {
    getMin(min) {
      this.extremes.min = min
    },
    getMax(max) {
      this.extremes.max = max;
    },
    extremes: {
        handler(extremes) {
            const chart = this.$refs.chart.chart

            chart.xAxis[0].setExtremes(extremes.min, extremes.max)
        },
        deep: true
    }
  },
  data() {
      return {
          extremes: {
              min: 0,
              max: 0
          },
          chartOptions: {
            chart: {
                zoomType: "x",
                height: "250px",
            },
            series: [{
                data: this.chartData // sample data
            }],
            xAxis: {
                minRange: 0.1,
                events: {
                    setExtremes: this.syncExtremes
                }
            }
        }
      }
  },

Live example: https://codesandbox.io/s/vuex-store-v7l8h Highcharts API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#setExtremes

Kind regards!

JonasGilg commented 5 years ago

@Denyllon Thank you very much. I didn't want to use the setExtremes function, because the highcharts-vue documentation says that it should be avoided to use the chart object reference functions. But it seams like it is the only way.

Denyllon commented 5 years ago

You are right, but I meant that updating chart data through Chart.update() or Series.setData() could cause some inconsistency between the chart and component data values. In this case, using Axis.setExtremes() does not mutate any component data, so you can apply it without any worries. Maybe it's good moment to explain it more precisely in documentation? What do you think about that?

JonasGilg commented 5 years ago

Yeah, that should be documented more precisely. It is hard to separate what can be done with chart reference functions and what not.