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,提问作者Владислав Погорелов
相关产品推荐
相关产品推荐

