在 Vue 应用程序中尝试更新 Chart.js 中的图表数据时出现意外错误
我正在使用 Chart.js 3.5 和 Vue 3。 我成功地绘制了一个图表,并试图在 Vue 方法中触发数据更改。不幸的是,我遇到了以下问题:“未捕获的 TypeError:无法设置未定义的属性‘fullSize’”。
编辑 2:添加了一个遗漏的 }。代码现在应该可以运行了
MyChart.vue:
<template>
<canvas id="chartEl" width="400" height="400" ref="chartEl"></canvas>
<button @click="addData">Update Chart</button>
</template>
<script>
import Chart from 'chart.js/auto';
export default {
name: "Raw",
data() {
return {
chart: null
}
},
methods: {
createChart() {
this.chart= new Chart(this.$refs["chartEl"], {
type: 'doughnut',
data: {
labels: ['VueJs', 'EmberJs', 'ReactJs', 'AngularJs'],
datasets: [
{
backgroundColor: [
'#41B883',
'#E46651',
'#00D8FF',
'#DD1B16'
],
data: [100, 20, 80, 20]
}
]
},
options: {
plugins: {}
}
})
},
addData() {
const data = this.chart.data;
if (data.datasets.length > 0) {
data.labels.push('data #' + (data.labels.length + 1));
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(123);
}
// Edit2: added missed }
this.chart.update(); } // this line seems to cause the error}
}
},
mounted () {
this.createChart()
},
}
</script>
编辑 1:将以下内容添加到选项中可使图表成功更新,但错误仍然存​​在,动画不起作用。图表闪烁并显示最终(更新)状态。其他动画(例如隐藏/显示弧线)似乎不受影响
options: {
responsive: true,
}
Edit3:添加“maintainAspectRatio:false”选项似乎再次停止图表更新(上述错误仍然存​​在)
通过调试器,'chart.esm.js'中的以下函数似乎被成功调用了几次,然后在最后一次调用时出错:
beforeUpdate(chart, _args, options) {
const title = map.get(chart); // this returns null, which will cause the next call to error with the above mentioned exception.
layouts.configure(chart, title, options);
title.options = options;
},
//////////////////////
configure(chart, item, options) {
item.fullSize = options.fullSize;
item.position = options.position;
item.weight = options.weight;
},
这可能是一篇过时的帖子,但我刚刚花了几个小时来解决看似相同的问题。也许这会对您和/或未来遇到此问题的人有所帮助:
在将 Chart 对象分配为 Vue 组件的属性之前,请对其调用
Object.seal(...)
。
例如:
const chartObj = new Chart(...);
Object.seal(chartObj);
this.chart = chartObj;
这对我有用。Vue 积极地改变其权限范围内的对象的属性以增加反应性,据我所知,这会阻止 Chart 的内部识别这些对象以在需要时从其内部映射中检索其配置。
Object.seal
通过禁止对象添加任何新属性来防止这种情况。我指望 Chart 在初始化时添加了它需要的所有属性 - 如果我注意到任何奇怪的行为,我会更新这篇文章。
1 年后,Alan 的回答也帮助了我,但我的代码在调用
chart.destroy()
时失败了。
因此我搜索并找到了似乎是“vue 方式”来处理它:
markRaw
,这里有一个使用选项 API 的示例:
import { markRaw } from 'vue'
// ...
export default {
// ...
beforeUnmount () {
if (this.chart) {
this.chart.destroy()
}
},
methods: {
createChart() {
const chart = new Chart(this.$refs["chartEl"], {
// ... your chart data and options
})
this.chart = markRaw(chart)
},
addData() {
// ... your update
this.chart.update()
},
},
}