[Vuejs]-Updating a chart from chart.js in vue

2👍

I think the only problem with your code is that you’re not updating the dataset correctly.
With myChart.data.datasets.data = ... your adding data to datasets object – it should be myChart.data.datasets[0].data = ....

I’ve also added the chart object to Vue.js model in startChart with-out reactivity because it needs to be updated manually. Just don’t add it to data hook. So you can reference the chart with this.myChart in your updating method.

I’ve renamed getRowIndex in the demo because rowIndex is more readable – you could do the same with the getAnalyticsLists. I would name it with get-prefix if it’s a method that is getting something.

Scroll down in the demo to toggle the data with the next button. That button increments rowIndex and rolls over at the end.

Please have a look at the demo below or at this jsfiddle.

const chartComponent = {
  data() {
      return {
        //myChart: undefined, // don't add chart here -> reactivity could be a problem
        getAnalyticList: [{
          chartNames: [
            'Red',
            'Yellow',
            'Blue'
          ],
          chartData: [10, 20, 30]
        },
        {
          chartNames: [
            'Red',
            'Yellow',
            'Blue'
          ],
          chartData: [40, 10, 20]
        }
        ],
        rowIndex: 0
      }
    },
    template: `
    <div>
  	<canvas id="myChart" width="200px" height="200px"></canvas>
    <button @click="incRow">next</button>
    {{rowIndex}}
    </div>
  `,
    methods: {
      startChart: function() {
        var ctx = document.getElementById("myChart");
        var myDoughnut = this.myChart =  new Chart(ctx, {
          type: 'doughnut',
          data: {
            labels: this.getAnalyticList[this.rowIndex].chartNames,
            datasets: [{
              data: this.getAnalyticList[this.rowIndex].chartData,
              backgroundColor: [
                'rgba(255, 99, 132, 0.6)',
                'rgba(54, 162, 235, 0.6)',
                'rgba(255, 206, 86, 0.6)',
                'rgba(75, 192, 192, 0.6)',
                'rgba(153, 102, 255, 0.6)',
                'red',
                'yellow',
                'blue',
                'green',
                'orange',
                'teal',
                'violet',
                'pink',
                'purple'
              ]
            }]
          },
          options: {
            responsive: true,
            defaultFontColor: '#ffffff',
						
          }
        })
      },
      incRow () {
      	if (this.rowIndex < this.getAnalyticList.length - 1) {
        	this.rowIndex++;
        }
        else {
        	this.rowIndex = 0;
        }
        this.changeData()
      },
      changeData () {
      	this.myChart.data.datasets[0].data =
        	this.getAnalyticList[this.rowIndex].chartData;
        this.myChart.data.labels = this.getAnalyticList[this.rowIndex].chartNames;
        this.myChart.update();
        console.log('changed', this.myChart.data)
      }
    },
    mounted() {
      console.log('started')
      this.startChart();
    }
}

new Vue({
  el: '#app',
  components: {
    chart: chartComponent
  }
})
div {
   width: 400px;
   height: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.bundle.min.js"></script>
<div id="app">
  <chart></chart>
</div>
👤AWolf

Leave a comment