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

Chart JS柱状图数值显示错位问题解决方法咨询

问题原因

问题核心是ChartJSNodeCanvas实例复用导致的状态残留,加上插件重复注册引发的内部状态混乱。每次请求复用同一canvas实例时,ChartJS会保留上一次请求的配置或计算状态,导致后续请求的数据标签位置计算错误。

解决步骤
  • 每次请求创建全新的ChartJSNodeCanvas实例,彻底隔离不同请求的状态
  • 将插件注册移到实例初始化的回调中,避免全局重复注册冲突
修正后的完整代码
const { ChartJSNodeCanvas } = require('chartjs-node-canvas');
const ChartDataLabels = require('chartjs-plugin-datalabels');
const moment = require('moment');

async function generateSalesChart(salesTarget, monthSum, monthForcastSum, currentMonth) {
    // 每次请求都创建新的画布实例,避免状态污染
    const width = 600;
    const height = 400;

    const chartCallback = (ChartJS) => {
        ChartJS.defaults.font.size = 14;
        // 在实例回调中注册插件,确保每个实例独立初始化插件
        ChartJS.register(ChartDataLabels);
    };

    const canvas = new ChartJSNodeCanvas({ width, height, chartCallback });

    const chartData = {
        labels: ['План', 'Факт', 'Прогноз'],
        datasets: [
            {
                label: 'Сумма',
                data: [salesTarget, monthSum, monthForcastSum],
                backgroundColor: 'rgba(54, 162, 235, 0.5)',
                borderColor: 'rgba(54, 162, 235, 1)',
                borderWidth: 1,
            },
        ],
    };

    const chartOptions = {
        responsive: false,
        scales: {
            y: {
                beginAtZero: true,
                ticks: {
                    callback: (value) => value.toLocaleString('ru-RU'),
                },
            },
        },
        plugins: {
            datalabels: {
                anchor: 'end',
                align: 'top',
                font: {
                    size: 20,
                    weight: 'bold',
                },
                formatter: (value) => value.toLocaleString('ru-RU'),
                color: 'rgba(54, 162, 235, 1)',
                textAlign: 'center',
            },
            title: {
                display: true,
                text: `Продажи за ${currentMonth} ${moment().format('YYYY')} (${moment().format('DD.MM - HH:mm')})`,
                color: 'rgba(54, 162, 235, 1)',
                font: {
                    size: 20,
                    weight: 'bold',
                    lineHeight: 1.2,
                },
            }
        },
    };

    const configuration = {
        type: 'bar',
        data: chartData,
        options: chartOptions,
        // 移除重复的插件数组,避免重复注册
    };

    return await canvas.renderToBuffer(configuration);
}
关键说明
  • 实例隔离:每次请求新建画布实例,确保ChartJS的计算上下文完全干净,没有上一次请求的残留数据
  • 插件实例化注册:在chartCallback中注册插件,每个画布实例都会独立初始化插件,避免全局重复注册导致的逻辑冲突
  • 清理冗余配置:移除configuration中的plugins数组,因为已经在实例回调中完成注册,防止重复加载插件引发异常

内容的提问来源于stack exchange,提问作者Владислав Погорелов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:44:54