Vue ApexCharts updating data series dynamically

Bik Lander picture Bik Lander · Jan 14, 2020 · Viewed 9.6k times · Source

How can I update the data from the series for an ApexCharts I have created the following Vue Component using the ApexCharts. This component gets updated from the parent where a bunch of these components are situated. The updated values are coming in through props.

<template>
  <div>
    <apexchart type="line" width="1000px" :options="options" :series="series"></apexchart>
  </div>
</template>

<script>
import Vue from 'vue';
import VueApexCharts from 'vue-apexcharts';

Vue.use(VueApexCharts);
Vue.component('apexchart', VueApexCharts);

export default {
  name: 'EnergyConsumption',
  props: {
    channel1: Number,
    channel2: Number,
  },
  data() {
    return {
      options: {
        chart: {
          id: 'vuechart-example',
        },
        xaxis: {
          categories: ['Channel 1', 'Channel 2'],
        },
      },
      series: [
        {
          name: 'series-1',
          data: [this.channel1, this.channel2],
        },
      ],
    };
  },
  methods: {
    updateSeries() {
      this.series[0].data = [this.channel1, this.channel2];
    },
  },
  watch: {
    channel1: function (_channel1) {
      this.updateSeries();
      //   this.series[0].data[0] = _channel1;
    },
  },
};
</script>

With the Vue DevTools I can see that the data is changing inside the ApexCharts component, but the view is not updated.

If I take a look in the ApexCharts documentation, I see there is a method to update the series

updateSeries (newSeries, animate)

But I need an instance to call the updateSeries from. If I use the template mechanism, I can't have a reference to that module.

What is the best way to solve this issue?

Answer

Patel Pratik picture Patel Pratik · Jan 15, 2020

You need to use ref for updating series.

<template>
  <apexchart
      ref="realtimeChart"
      type="line"
      height="200"
      :options="chartOptions"
      :series="series"
  />
</template>

<script>
export default {
  data() {
    return {
      series: [{
        name: 'Desktops',
        data: [10, 41, 35, 51, 49, 62, 69, 91, 99],
      }],
      chartOptions: {
        colors: ['#FCCF31', '#17ead9', '#f02fc2'],
        chart: {
          height: 350,
        },
        grid: {
          show: true,
          strokeDashArray: 0,
          xaxis: {
            lines: {
              show: true,
            },
          },
        },
        stroke: {
          curve: 'straight',
          width: 5,
        },
        // grid: {
        //   padding: {
        //     left: 0,
        //     right: 0,
        //   },
        // },
        dropShadow: {
          enabled: true,
          opacity: 0.3,
          blur: 5,
          left: -7,
          top: 22,
        },
        dataLabels: {
          enabled: false,
        },
        title: {
          text: 'Line',
          align: 'left',
          style: {
            color: '#FFF',
          },
        },
        xaxis: {
          categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'],
          labels: {
            style: {
              colors: '#fff',
            },
          },
        },
        yaxis: {
          labels: {
            style: {
              color: '#fff',
            },
          },
        },
      },
    };
  },
  mounted() {
    this.setDataLineChart();
  },
  methods: {
    getRandomArbitrary(min, max) {
      return Math.floor(Math.random() * 99);
    },
    setDataLineChart() {
      setInterval(() => {
        this.series[0].data.splice(0, 1);
        this.series[0].data.push(this.getRandomArbitrary(0, 99));
        this.updateSeriesLine();
      }, 3000);
    },
    updateSeriesLine() {
      this.$refs.realtimeChart.updateSeries([{
        data: this.series[0].data,
      }], false, true);
    },
  },
};
</script>