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

