Chartjs-How to update chart.js in vue

2👍

This issue mainly happening because you are drawing multiple charts on the same canvas on calling the createChart() method. You just need to call the .destroy() method to destroy any chart instances that were created. This will clean up any references stored to the chart object within Chart.js, along with any associated event listeners attached by Chart.js. This must be called before the canvas is reused for a new chart.

So, simply add a new data option to store current chart instance like:

data(){
  return{
    chart: null
  }
},

then store the chart instance like:

 createChart() {
    this.chart = new Chart(document.getElementById("chart"), {
    ...

and inside watch before calling this.createChart(); use:

  this.chart.destroy();
  this.createChart();

Working Demo:

Vue.component('chart', {
  template: '<canvas id="chart"></canvas>',
  props: {
    savings: Object,
  },
  data(){
    return{
      chart: null
    }
  },
  watch: {
    savings: {
      deep: true,
      handler() {
        console.clear();
        console.log('Update Chart');
        this.chart.destroy();
        this.createChart();
      }
    }
  },
  methods: {
    createChart() {
      this.chart = new Chart(document.getElementById("chart"), {
        type: 'bar',
        data: {
          datasets: [{
            label: 'Bar Dataset',
            data: [...this.savings.annual]
          }, {
            label: 'Line Dataset',
            data: [...this.savings.cumulative],
            type: 'line'
          }],
          labels: ['Year One', 'Year Two', 'Year Three', 'Year Four', 'Year Five']
        }
      });
    }
  },
  mounted() {
    this.createChart();
    //console.log(this.totals);
  }
});

var app1 = new Vue({
  el: '#savings_calculator',
  data: {
    savings: {
      annual: [123, 345, 234, 234, 523],
      cumulative: [234, 523, 234, 423, 100],
    }
  },
  methods: {
    changeData() {
      for (let i = 0; i < 5; i++) {
        Vue.set(this.savings.annual, i, Math.floor((Math.random() * 1000) + 1));
        Vue.set(this.savings.cumulative, i, Math.floor((Math.random() * 1000) + 1));
      }

    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="savings_calculator">
  <div class="input container">
    <button v-on:click="changeData">Change Data</button>
    <chart v-bind:savings="savings" />
  </div>
</div>

Leave a comment