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

ChartJS 6.2中fillText()始终使用最后设置的ctx.font参数问题

问题描述

我需要用ChartJS在环形图中心绘制多段文本,每段文本使用不同的字体参数(比如字号、样式、颜色)。目前能在中心添加文本,但所有fillText()调用都只会用最后设置的ctx.font值。这个功能在旧版ChartJS里能正常工作,升级到6.2版本后就出现了问题。

解决方案

在ChartJS 6.x版本中,画布上下文的状态管理逻辑有调整,需要通过以下方式确保每段文本的字体参数独立生效:

方法1:使用上下文状态保存/恢复

每次绘制一段文本前,用ctx.save()保存当前上下文状态,绘制完成后用ctx.restore()恢复,避免字体设置互相干扰:

const centerMultiTextPlugin = {
  id: 'centerMultiText',
  afterDatasetsDraw(chart) {
    const ctx = chart.ctx;
    const centerX = chart.chartArea.centerX;
    const centerY = chart.chartArea.centerY;

    // 第一段文本:大号粗体
    ctx.save();
    ctx.font = 'bold 28px sans-serif';
    ctx.fillStyle = '#2c3e50';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('总完成率', centerX, centerY - 20);
    ctx.restore();

    // 第二段文本:超大号高亮色
    ctx.save();
    ctx.font = 'bold 42px sans-serif';
    ctx.fillStyle = '#e74c3c';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('78%', centerX, centerY);
    ctx.restore();

    // 第三段文本:小号灰色
    ctx.save();
    ctx.font = '14px sans-serif';
    ctx.fillStyle = '#95a5a6';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('较上月提升5%', centerX, centerY + 25);
    ctx.restore();
  }
};

// 注册插件并初始化图表
Chart.register(centerMultiTextPlugin);

new Chart(document.getElementById('doughnutChart'), {
  type: 'doughnut',
  data: {
    labels: ['已完成', '未完成'],
    datasets: [{
      data: [78, 22],
      backgroundColor: ['#e74c3c', '#ecf0f1']
    }]
  },
  options: {
    cutout: '70%'
  }
});

方法2:每次绘制前明确重置所有相关属性

如果不想使用save()/restore(),可以在绘制每段文本时,重新设置所有与文本渲染相关的上下文属性(ChartJS可能会在渲染流程中重置部分状态):

afterDatasetsDraw(chart) {
  const ctx = chart.ctx;
  const centerX = chart.chartArea.centerX;
  const centerY = chart.chartArea.centerY;

  // 第一段文本
  ctx.font = 'bold 28px sans-serif';
  ctx.fillStyle = '#2c3e50';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText('总完成率', centerX, centerY - 20);

  // 第二段文本,重新设置所有属性
  ctx.font = 'bold 42px sans-serif';
  ctx.fillStyle = '#e74c3c';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText('78%', centerX, centerY);

  // 第三段文本,重新设置所有属性
  ctx.font = '14px sans-serif';
  ctx.fillStyle = '#95a5a6';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText('较上月提升5%', centerX, centerY + 25);
}
原理说明

ChartJS 6.x对渲染流程做了批量优化,上下文状态可能会被后续的渲染步骤重置,导致之前设置的字体参数被覆盖。通过手动保存/恢复状态,或者每次绘制前明确重置所有必要属性,可以确保每段文本的字体样式独立生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:55:11