javascript - 如何在 vue 中更新 chart.js
问题描述
我创建了一个 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 中工作,我通过将代码复制到我的一个 js 文件中包含了 chart.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>
推荐阅读
- javascript - 如何在这个项目上添加响应式新闻卡片
- php - 将数组中的时间戳分组为唯一实例并通过 php 对其进行计数
- c# - 是否可以使用 .Net Framework 应用程序中的 .Net5(核心)库?
- javascript - 有什么方法可以通过 Filereader 自动重新加载从“InputFile”中选择的文件?
- python - 将 python 输出打印到 CGI 网页
- google-bigquery - Bigquery - 选择一个列而不将它们分组在按子句中
- java - 如何使用 javaee、javafx、jpa 正确设置应用程序层?
- reactjs - 在反应本机应用程序中将内容居中放在屏幕中间
- r - 删除 R 中的撤销交易对
- python - 根据名称列表重新排列 DataFrame 列