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
相关产品推荐
相关产品推荐

