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

如何在Blazor WASM中复用Chart.js图表?解决画布销毁报错

Blazor WASM中Chart.js图表复用与更新方案

问题根源

你每次调用setup都会新建一个Chart实例,但未销毁之前的实例,导致Chart.js检测到画布已被占用,抛出需销毁画布的报错。

方案1:销毁旧实例后重建

通过全局对象存储每个Canvas对应的Chart实例,每次创建新图表前先销毁旧实例:

修改JavaScript代码

// 全局存储Chart实例,以Canvas ID为键
window.chartInstances = {};

window.setup = (id, config) => {
    // 销毁已存在的图表实例
    if (window.chartInstances[id]) {
        window.chartInstances[id].destroy();
        delete window.chartInstances[id];
    }

    const ctx = document.getElementById(id).getContext('2d');
    // 创建新图表并保存实例
    const newChart = new Chart(ctx, config);
    window.chartInstances[id] = newChart;
};

Blazor调用方式不变

await JSRuntime.InvokeVoidAsync("setup", Id, config);

方案2:直接更新现有图表(无需销毁)

如果只是更新数据或配置,无需销毁重建,直接更新现有实例性能更优。注意:Chart.js不支持动态切换图表类型,如果需要改类型,仍需用方案1销毁重建:

新增JavaScript更新函数

window.chartInstances = {};

window.updateChart = (id, config) => {
    const existingChart = window.chartInstances[id];
    if (existingChart) {
        // 若图表类型改变,必须销毁重建
        if (existingChart.config.type !== config.type) {
            existingChart.destroy();
            const ctx = document.getElementById(id).getContext('2d');
            window.chartInstances[id] = new Chart(ctx, config);
        } else {
            // 更新数据与配置
            existingChart.config.data = config.data;
            existingChart.config.options = config.options;
            // 触发图表更新
            existingChart.update();
        }
    } else {
        // 首次创建图表
        const ctx = document.getElementById(id).getContext('2d');
        window.chartInstances[id] = new Chart(ctx, config);
    }
};

Blazor调用更新函数

await JSRuntime.InvokeVoidAsync("updateChart", Id, config);

关键注意事项

  • 确保每个Canvas的id唯一,避免实例存储冲突
  • 若需动态切换图表类型(如从柱状图变折线图),必须销毁旧实例再创建新的
  • 传递的config需包含完整的data和options结构,更新时Chart.js会覆盖原有配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:15:36