Vue Chart.js - Chart does not update when data changes

I use Vue.js and Chart.js to draw a chart. Each time I call the generateChart() function, the chart does not update automatically. When I check the data in VueDevTools , they are correct, but the diagram does not represent them.

Interesting fact: the chart is updated when I resize the window.

  • What is wrong with what I'm doing?
  • How to update a chart every time I call generateChart() ?

I feel this will be due to object and array changing the detour bypass, but I'm not sure what to do.

https://codepen.io/anon/pen/bWRVKB?editors=1010

  <el-dialog title="Chart" v-model="showGeneratedChart"> <line-chart :chartData="dataChart"></line-chart> </el-dialog> export default{ data (){ const self = this; return { dataChart : { labels : [], datasets: [{ label: 'label', backgroundColor: '#FC2525', data: [0, 1, 2, 3, 4], }] } } } generateChart() { this.dataChart['labels'] = []; this.dataChart['datasets'] = []; ... compute datasets and formattedLabels this.dataChart['labels'] = formattedLabels; this.dataChart['datasets'] = datasets; } 

LineChart.js

 import { Line, mixins } from 'vue-chartjs' export default Line.extend({ mixins: [mixins.reactiveProp], props: ["options"], mounted () { this.renderChart(this.chartData, this.options) } }) 
+4
source share
3 answers

Use computed property for chart data. And instead of calling this.renderChart on the watch, wrap it in a method and reuse this method on mounted and in watch .

 Vue.component("line-chart", { extends: VueChartJs.Line, props: ["data", "options"], mounted() { this.renderLineChart(); }, computed: { chartData: function() { return this.data; } }, methods: { renderLineChart: function() { this.renderChart( { labels: [ "January", "February", "March", "April", "May", "June", "July" ], datasets: [ { label: "Data One", backgroundColor: "#f87979", data: this.chartData } ] }, { responsive: true, maintainAspectRatio: false } ); } }, watch: { data: function() { this._chart.destroy(); //this.renderChart(this.data, this.options); this.renderLineChart(); } } }); var vm = new Vue({ el: ".app", data: { message: "Hello World", dataChart: [10, 39, 10, 40, 39, 0, 0], test: [4, 4, 4, 4, 4, 4] }, methods: { changeData: function() { this.dataChart = [6, 6, 3, 5, 5, 6]; } } }); 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>Vue.jS Chart</title> </head> <body> <div class="app"> {{ dataChart }} <button v-on:click="changeData">Change data</button> <line-chart :data="dataChart" :options="{responsive: true, maintainAspectRatio: false}"></line-chart> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script> <script src="https://unpkg.com/ vue-chartjs@2.5.7-rc3 /dist/vue-chartjs.full.min.js"></script> </body> </html> 

You can also make the parameters a computed property, and if the parameter does not change much, you can set the default details. https://vuejs.org/v2/guide/components.html#Prop-Validation

Here is the working code https://codepen.io/azs06/pen/KmqyaN?editors=1010

+6
source

I have never used vue-chartjs before, but it seems like your only problem is that you forgot to explicitly get chartData as a support in your line chart component:

Edit

 export default Line.extend({ mixins: [mixins.reactiveProp], props: ["options"], mounted () { this.renderChart(this.chartData, this.options) } }) 

with

 export default Line.extend({ mixins: [mixins.reactiveProp], props: ["chartData", "options"], mounted () { this.renderChart(this.chartData, this.options) } }) 

Also, be aware of problems with vue reaction when changing objects, this will not work:

 this.dataChart['datasets'] = datasets; 

you need to do something like this:

 Vue.set(this.dataChart, 'datasets', datasets); 

so that Vue detects changes in your object.

Additional reactivity information: https://vuejs.org/v2/guide/reactivity.html

Additional reactivity information in charts: http://vue-chartjs.org/#/home?id=reactive-data

+1
source
 watch: { chartData: function (newData, oldData) { // let ctx = document.getElementById('doughnut-chart').getContext('2d') // console.log(ctx) // var chart = new Chart(ctx, {type: 'doughnut', data:, options: self.options}) // // chart.config.data.datasets.push(newData) // chart.config.options.animation = false // console.log(chart) // chart.config.data.datasets.push(newData) // chart.config.optionsNoAnimation = optionsNoAnimation // console.log(chart.config.data.datasets.push(newData)) // this.dataset = newData // chart.update() // console.log('options', this.data) console.log('new data from watcher', newData) this.data.datasets[0].data = newData this.renderChart(this.data, this.options) } } 

add a custom observer to update any vue chart graph

0
source

All Articles