You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在draw()函数中实现Chart.js销毁以更新环形图?

问题

我有一个环形图(doughnut Chart),希望每次在下拉菜单选择不同选项时,用新的数据集stats更新图表。但代码写在draw()函数里,导致图表重复绘制,一直收到错误提示:

Canvas is already in use. Chart with ID '0' must be destroyed before the canvas with ID 'myChart' can be reused.

相关代码如下:

var config = {
            type: 'doughnut',
            data: {
                labels: legend,
                datasets: [{
                    backgroundColor: ['rgb(204,0,0)', 'rgb(241,194,50)', 'rgb(41,134,204)', 'rgb(106,168,79)', 'rgb(255,62,153)'],
                    data: stats,
                }]
            },
            plugins: [hoverLabel],
            options: {
                radius: this.radius,
                hoverOffset: 30,
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    title: {
                        display: true,
                        text: "Top 5 causes of death in " + country,
                        color: 'rgb(0,0,0)',
                        align: 'center',
                        padding: 15,
                        font: {
                            size: 25
                        }
                    },
                    legend: {
                        position: 'right',
                        title: {
                            display: true,
                            color: 'rgb(0,0,0)',
                            text: 'Legend',
                            font: {
                                weight: 'bold',
                                size: 20
                            },
                        },
                        labels: {
                            color: 'rgb(0,0,0)',
                            usePointStyle: true,
                            padding: 15,
                            font: {
                                size: 15,
                                weight: 'bold'
                            }
                        }
                    }
                }

            }
        };


        let mychart = new Chart('myChart', config);

环形图

解决方案

核心问题是每次调用draw()都会创建新的Chart实例,但Canvas已被旧实例占用。推荐两种解决方式:

方式1:复用实例更新数据(性能更优)

把图表实例变量提升到draw()函数外的作用域,避免每次调用重新声明,后续直接更新实例数据并渲染:

// 将实例变量放在全局/外部作用域,保留引用
let mychart = null;

function draw() {
    var config = {
        type: 'doughnut',
        data: {
            labels: legend,
            datasets: [{
                backgroundColor: ['rgb(204,0,0)', 'rgb(241,194,50)', 'rgb(41,134,204)', 'rgb(106,168,79)', 'rgb(255,62,153)'],
                data: stats,
            }]
        },
        plugins: [hoverLabel],
        options: {
            radius: this.radius,
            hoverOffset: 30,
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                title: {
                    display: true,
                    text: "Top 5 causes of death in " + country,
                    color: 'rgb(0,0,0)',
                    align: 'center',
                    padding: 15,
                    font: {
                        size: 25
                    }
                },
                legend: {
                    position: 'right',
                    title: {
                        display: true,
                        color: 'rgb(0,0,0)',
                        text: 'Legend',
                        font: {
                            weight: 'bold',
                            size: 20
                        },
                    },
                    labels: {
                        color: 'rgb(0,0,0)',
                        usePointStyle: true,
                        padding: 15,
                        font: {
                            size: 15,
                            weight: 'bold'
                        }
                    }
                }
            }
        }
    };

    if (mychart) {
        // 更新核心数据
        mychart.data.labels = legend;
        mychart.data.datasets[0].data = stats;
        // 更新标题文本
        mychart.options.plugins.title.text = "Top 5 causes of death in " + country;
        // 重新渲染图表
        mychart.update();
    } else {
        // 首次创建图表实例
        mychart = new Chart('myChart', config);
    }
}

方式2:销毁旧实例后重建

如果不需要复用实例,每次创建新图表前先销毁旧实例:

let mychart = null;

function draw() {
    // 存在旧实例则销毁
    if (mychart) {
        mychart.destroy();
    }

    var config = {
        // 原config内容不变
    };

    // 创建新的图表实例
    mychart = new Chart('myChart', config);
}

注意点

  • 优先用方式1,销毁重建会带来额外性能开销;
  • 确保legend、stats、country在draw()调用时已更新为最新值;
  • 若需修改其他配置(比如颜色、图例位置),可直接修改实例属性后调用update()。

内容的提问来源于stack exchange,提问作者wubberlublub

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 09:18:30