ChartJS配合try catch使用时无数据场景下的图表重置销毁问题
问题核心原因
你当前代码无法正常销毁实例的问题来自两点:
myChart在try代码块内部声明,仅在try块成功执行完全程时才会被赋值,catch块无法正常访问到有效的实例对象- 每次新建图表前没有先销毁旧实例,才会触发ID已被占用的报错
修改方案
你可以通过全局存储图表实例的方式解决作用域问题,每次函数调用前先统一销毁已存在的实例,即可避免冲突,修改后代码如下:
// 全局存储图表实例,所有代码块均可访问 let myChart = null; function chartJSLoad(json_data) { // 调用时先销毁已存在的实例,避免ID占用 if (myChart) { myChart.destroy(); myChart = null; } try { let labels = json_data.data.map(e => e.StartTime); let data = json_data.data.map(e => e.StatusId); console.log(labels); console.log(data); const ctx = document.getElementById('canvaschartjs').getContext('2d'); // 实例赋值给全局变量 myChart = new Chart(ctx, { data: { datasets: [{ type: 'bar', label: 'Bar Dataset', data: data, backgroundColor: 'rgba(0, 150, 90)', borderColor: 'rgba(0, 255, 90)', order: 2 }, { type: 'line', label: 'Line Dataset', data: data, backgroundColor: 'rgba(150, 0, 90)', borderColor: 'rgba(255, 0, 90)', order: 1 }], labels: labels }, options: { maintainAspectRatio: false, responsive: true, scales: { x: { stacked: true, }, y: { stacked: true } } } }); } catch (error) { if (typeof json_data !== 'undefined') { // 额外清空画布内容 const ctx = document.getElementById('canvaschartjs').getContext('2d'); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); alert(json_data.message); } } }
如果你不想声明全局变量,也可以把实例挂载到canvas元素的自定义属性上,读取和销毁都直接从元素属性操作即可。
内容的提问来源于stack exchange,提问作者Mads Sander Høgstrup
相关产品推荐
相关产品推荐

