我创建了一个chart.js vue组件,它通过道具传递给它一些数据来渲染。现在,我希望能够在数据变化时调用图表上的update()方法。我的问题是,根据我的代码结构,我不能使用通常的chart.update()方法,因为我不能从它被创建的函数之外访问图表变量。我如何调整我的代码结构,使我能够调用图表上的更新方法?
此刻当数据发生变化时,我只是调用了初始渲染函数,这就会导致图表互相分层。当你改变数据然后悬停在图表上时,可以看到这一点。
Vue.component('chart', {
template: '<canvas id="chart"></canvas>',
props: {
savings: Object,
},
watch: {
savings: {
deep: true,
handler() {
console.log('Update Chart');
this.createChart();
}
}
},
methods: {
createChart() {
new Chart(document.getElementById("chart"), {
type: 'bar',
data: {
datasets: [{
label: 'Bar Dataset',
data: [
this.savings.annual[0],
this.savings.annual[1],
this.savings.annual[2],
this.savings.annual[3],
this.savings.annual[4]
]
}, {
label: 'Line Dataset',
data: [
this.savings.cumulative[0],
this.savings.cumulative[1],
this.savings.cumulative[2],
this.savings.cumulative[3],
this.savings.cumulative[4]
],
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.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>
我是在WordPress中工作的,我已经把chart.js库的代码复制到我的一个js文件中,这些文件都会被gulp压缩成一个文件。我之所以提到这一点,只是因为我看到有人使用import来包含库的例子。我确实下载了库到我的node_modules中,但我无法在我的js文件中导入。它给了我以下错误。
“Uncaught SyntaxError: Cannot use import statement outside a module”
这个问题的发生主要是由于你在同一张图上绘制了多个图表。canvas
召见 createChart()
方法。你只需要调用 .destroy()
方法来销毁任何已创建的图表实例。这将清理任何存储在Chart.js中对图表对象的引用,以及任何由Chart.js附加的相关事件监听器。在画布被重新用于新的图表之前,必须调用这个方法。
因此,简单地添加一个新的数据选项来存储当前的图表实例,如:。
data(){
return{
chart: null
}
},
然后像这样存储图表实例。
createChart() {
this.chart = new Chart(document.getElementById("chart"), {
...
然后在里面 watch
呼叫前 this.createChart();
使用。
this.chart.destroy();
this.createChart();
工作示范:
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>