How should I refer to the chart in a vue chart instance and destroy it? I've tried:
var chartVue = new Vue({
el: '#chart',
extends: VueChartJs.Line,
data: {
chartData: {...},
options: {...}
},
mounted() {
this.renderMyChart()
},
methods: {
renderMyChart: function() {
this.renderChart(
this.chartData,
this.options
);
}
},
watch: {
chartData: function() {
this._chart.destroy();
this.renderMyChart();
}
}
});
But it plains
TypeError: Cannot read property 'destroy' of undefined
So it seems this._chart
is not the right way to refer to the current chart, anybody knows what is the right way to do this? The idea es from this stack overflow answer.
How should I refer to the chart in a vue chart instance and destroy it? I've tried:
var chartVue = new Vue({
el: '#chart',
extends: VueChartJs.Line,
data: {
chartData: {...},
options: {...}
},
mounted() {
this.renderMyChart()
},
methods: {
renderMyChart: function() {
this.renderChart(
this.chartData,
this.options
);
}
},
watch: {
chartData: function() {
this._chart.destroy();
this.renderMyChart();
}
}
});
But it plains
TypeError: Cannot read property 'destroy' of undefined
So it seems this._chart
is not the right way to refer to the current chart, anybody knows what is the right way to do this? The idea es from this stack overflow answer.
-
this._chart
is the correct reference, so I'm not sure why it would beundefined
at that point. But also, you can just use thereactiveData
mixin, which does exactly what you're trying to do: vue-chartjs/#/home?id=reactive-data – thanksd Commented Oct 25, 2017 at 19:58 -
Hi @thanksd, thanks for the reply. I've looked into
mixin
s but not sure how to use it directly in a vue instance. The example shows how to use it in a vue ponent. Do you how how I can use reactiveProp here? – akuiper Commented Oct 25, 2017 at 20:04 -
1
Just add
mixins: [ VueChartJs.mixins.reactiveData ],
. And note that it does need to bereactiveData
and notreactiveProp
since you've definedchartData
in your data object and not as a passed in prop. Example: jsfiddle/fuj4yqke – thanksd Commented Oct 25, 2017 at 20:08 -
@thanksd Excellent. I think that's the trick I am missing. I was trying
reactiveProp
all the time. It's working perfectly now. If you don't mind post as an answer, I'll upvote and accept it. The documentation does not seem very clear about this. – akuiper Commented Oct 25, 2017 at 20:13
2 Answers
Reset to default 4It seems this._chart
has been moved to this._data._chart
, so for instance to make the options reactive, add a watcher as follows:
watch: {
options: function() {
this._data._chart.destroy();
this.renderChart(this.chartData, this.options);
}
}
The Chart
object accessible via this._chart
is not set until after the renderChart
method is called. What's most likely happening is that your chartData
is somehow being updated before that renderChart
method has been called. So, the watcher for chartData
is referencing this._chart
before it has been defined.
However, vue-chartjs
has a baked-in way to re-render the chart when the dependant data change: the reactiveData
and reactiveProp
mixins. By adding either of these mixins, the changes to the chartData
(data-property or prop, respectively) will re-render the chart to reflect the updated data.
You should use the reactiveData
mixin instead:
var chartVue = new Vue({
el: '#chart',
extends: VueChartJs.Line,
mixins: [ VueChartJS.mixins.reactiveData ],
data() {
return {
chartData: {...},
options: {...}
}
},
mounted() {
this.renderChart(this.chartData, this.options);
},
});