如何修复Chart.js图表在RTL方向下的文本居中问题
修复RTL/LTR双方向下图表文本居中问题
问题根源在于Canvas文本对齐方式未显式定义,RTL文档环境会改变Canvas默认的文本对齐行为,导致原有的X坐标计算逻辑失效,最终文本偏移。
修改方案
- 在
beforeDraw钩子中添加ctx.textAlign = 'center';,强制文本以指定X坐标为中心对齐 - 简化文本X坐标计算,直接取画布宽度的一半即可,无需手动计算偏移量
修改后的完整代码
JavaScript 代码
var projectProgressChart = document.getElementById("chartProgress"); new Chart(projectProgressChart, { type: 'doughnut', data: { datasets: [{ label: 'Complete', percent: 20, backgroundColor: ['#6690F4'], borderWidth: 0 }] }, plugins: [{ beforeInit: (chart) => { const dataset = chart.data.datasets[0]; chart.data.labels = [dataset.label]; dataset.data = [dataset.percent, 100 - dataset.percent]; } }, { beforeDraw: (chart) => { var width = chart.chart.width, height = chart.chart.height, ctx = chart.chart.ctx; ctx.restore(); ctx.font = 1.5 + "em sans-serif"; ctx.fillStyle = "#9b9b9b"; ctx.textBaseline = "center"; // 强制文本居中对齐,不受文档方向影响 ctx.textAlign = 'center'; var text = chart.data.datasets[0].percent + "%", textX = width / 2, textY = height / 2; ctx.fillText(text, textX, textY); ctx.save(); } } ], options: { maintainAspectRatio: false, cutoutPercentage: 90, rotation: Math.PI / 2, legend: { display: false }, tooltips: { filter: tooltipItem => tooltipItem.index === 0, callbacks: { afterLabel: function (tooltipItem, data) { var dataset = data['datasets'][0]; var percent = Math.round((dataset['data'][tooltipItem['index']] / dataset["_meta"][Object.keys(dataset["_meta"])[0]]['total']) * 100); return '(' + percent + '%)'; } } } } });
HTML 代码
<!-- 无论设置dir="rtl"还是dir="ltr",文本都能正常居中 --> <html lang="en" dir="rtl"> <head> <script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script> </head> <body> <canvas id="chartProgress" width="300px" height="200"></canvas> </body> </html>
原理说明
- 当文档设置为
dir="rtl"时,Canvas默认textAlign会变为right,原有的(width - 文本宽度)/2计算逻辑会导致文本偏移 - 显式设置
ctx.textAlign = 'center'后,文本会以textX为中心点水平对齐,不受文档方向影响 - 此时直接取画布宽度的一半作为
textX,就能保证文本始终处于图表中心位置
内容的提问来源于stack exchange,提问作者Saptam Dev
相关产品推荐
相关产品推荐

