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

Chart.js自定义环形仪表盘主题切换时颜色不更新及指针颜色修改问题

问题修复方案

1. 修复主题切换颜色反向问题

出现反向的核心原因有两个:

  • 点击切换按钮后没有先切换body的dark-theme类,读取CSS变量时拿到的还是切换前的旧值
  • changeColor函数内用var重新声明了gaugeColor、gaugeColorBorder,属于局部变量,没有更新全局作用域下的对应值,导致自定义插件读取的还是旧颜色
    修改后的changeColor函数如下:
function changeColor() {
  // 先切换主题类,再读取变量
  document.body.classList.toggle('dark-theme');
  const gaugeStyle = getComputedStyle(document.body);
  const latestGaugeColor = gaugeStyle.getPropertyValue("--gauge-color").trim();
  const latestGaugeBorder = gaugeStyle.getPropertyValue("--gauge-color-border").trim();
  // 更新图表配置
  myGauge.options.plugins.tooltip.backgroundColor = latestGaugeColor;
  myGauge.options.plugins.tooltip.bodyColor = latestGaugeBorder;
  myGauge.data.datasets[0].borderColor = latestGaugeBorder;
  myGauge.update();
}

2. 动态修改指针颜色

不需要专门找插件的配置路径,直接修改自定义gaugeNeedle插件的逻辑,每次渲染时实时读取当前的CSS变量值,自动适配最新主题色即可,修改后的插件代码如下:

const gaugeNeedle = {
  id: "gaugeNeedle",
  afterDatasetDraw(chart) {
    // 每次渲染时读取最新的主题色
    const currentStyle = getComputedStyle(document.body);
    const currentGaugeColor = currentStyle.getPropertyValue("--gauge-color").trim();
    const {
      ctx,
      data,
      chartArea: { width, height },
    } = chart;
    ctx.save();
    const needleValue = data.datasets[0].needleValue;
    let angle;
    if (needleValue <= 100) {
      angle = Math.PI + (1 / 200) * needleValue * Math.PI;
    } else if (needleValue <= 10000) {
      angle =
        Math.PI +
        (1 / 200) * 100 * Math.PI +
        ((1 / 200) * needleValue * Math.PI * 65) / 10000;
    } else if (needleValue <= 1000000) {
      angle =
        Math.PI +
        (1 / 200) * 100 * Math.PI +
        ((1 / 200) * 10000 * Math.PI * 65) / 10000 +
        ((1 / 200) * needleValue * Math.PI * 35) / 1000000;
    } else {
      angle = 0;
    }
    const cx = width / 2;
    const cy = chart._metasets[0].data[0].y;
    // 指针
    ctx.translate(cx, cy);
    ctx.rotate(angle);
    ctx.beginPath();
    ctx.moveTo(0, -2);
    ctx.lineTo(height - ctx.canvas.offsetTop - 130, 0);
    ctx.lineTo(0, 2);
    ctx.fillStyle = currentGaugeColor;
    ctx.fill();
    // 指针圆点
    ctx.translate(-cx, -cy);
    ctx.beginPath();
    ctx.arc(cx, cy, 5, 0, 10);
    ctx.fillStyle = currentGaugeColor;
    ctx.fill();
    ctx.restore();
    // 文本
    ctx.font = "20px Ubuntu";
    ctx.fillStyle = currentGaugeColor;
    ctx.fillText(needleValue + " CPM", cx, cy + 50);
    ctx.font = "10px Ubuntu";
    ctx.fillStyle = currentGaugeColor;
    ctx.fillText(0, 3, cy + 20);
    ctx.fillText(100, cx, 50);
    ctx.fillText("10k", cx + 115, 115);
    ctx.fillText("1M", cx + 118, 205);
    ctx.textAlign = "center";
    ctx.restore();
  },
};

可选优化

你可以删掉原来全局声明的gaugeColor、gaugeColorBorder变量,所有需要用颜色的地方都实时读取CSS变量即可,避免多场景下的值不同步问题。

内容的提问来源于stack exchange,提问作者Ahnaf Tahmid Chowdhury

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:15:00