Chart.js 3.8.0 渐进折线图坐标轴标题无法显示问题
Chart.js 渐进式折线图坐标轴标题不显示修复方案
- 适用场景:基于Chart.js开发传感器数据渐进式(Progressive Line)折线图时,参照官方轴标签文档、渐进折线图示例配置后,坐标轴标题始终无法渲染,导致图表可读性差的问题。
问题根因
两个容易被忽略的配置冲突点:
- Chart.js 3.x及以上版本中,当存在自定义动画、自定义渲染插件时,坐标轴标题不会默认开启显示,必须显式声明
display: true - 照搬官方渐进折线图的自定义裁剪插件时,裁剪范围误覆盖了坐标轴所在区域,导致已经渲染的轴标题被画布裁剪,视觉上表现为不显示
存在问题的初始代码
// 存在坐标轴标题不显示问题的代码 const ctx = document.getElementById('sensorChart').getContext('2d'); // 传感器测试数据 const timeList = Array.from({length: 100}, (_,i) => `${i}s`); const tempData = Array.from({length: 100}, () => Math.random()*15 + 20); new Chart(ctx, { type: 'line', data: { labels: timeList, datasets: [{ label: '温度传感器数值', data: tempData, borderColor: '#2563eb', tension: 0.2, fill: false }] }, options: { animation: { // 渐进渲染动画配置(摘自官方示例) x: { type: 'number', easing: 'linear', duration: 2000, from: NaN, delay(ctx) { if (ctx.type !== 'data' || ctx.xStarted) return 0; ctx.xStarted = true; return ctx.index * 10; } } }, scales: { x: { title: { // 仅配置文本,未显式开启显示 text: '采集时间' } }, y: { title: { text: '温度(℃)' } } } }, // 自定义渐进渲染裁剪插件(摘自官方示例,未做范围限制) plugins: [{ id: 'progressiveRender', beforeDatasetsDraw(chart) { const ctx = chart.ctx; ctx.save(); ctx.beginPath(); // 裁剪范围覆盖整个画布,包含坐标轴区域 ctx.rect(0, 0, chart.width, chart.height); ctx.clip(); }, afterDatasetsDraw(chart) { chart.ctx.restore(); } }] });
修复后可正常运行的完整代码
const ctx = document.getElementById('sensorChart').getContext('2d'); // 传感器测试数据 const timeList = Array.from({length: 100}, (_,i) => `${i}s`); const tempData = Array.from({length: 100}, () => Math.random()*15 + 20); new Chart(ctx, { type: 'line', data: { labels: timeList, datasets: [{ label: '温度传感器数值', data: tempData, borderColor: '#2563eb', tension: 0.2, fill: false, radius: 0 }] }, options: { responsive: true, animation: { x: { type: 'number', easing: 'linear', duration: 2000, from: NaN, delay(ctx) { if (ctx.type !== 'data' || ctx.xStarted) return 0; ctx.xStarted = true; return ctx.index * 10; } } }, scales: { x: { title: { display: true, // 显式开启X轴标题显示 text: '采集时间', font: {weight: 'bold', size: 12}, padding: {top: 10} } }, y: { title: { display: true, // 显式开启Y轴标题显示 text: '温度(℃)', font: {weight: 'bold', size: 12}, padding: {right: 10} } } } }, // 修复裁剪范围的渐进渲染插件 plugins: [{ id: 'progressiveRender', beforeDatasetsDraw(chart) { const {ctx, chartArea} = chart; ctx.save(); ctx.beginPath(); // 裁剪范围严格限定在数据绘制区,不触碰坐标轴所在区域 ctx.rect( chartArea.left, chartArea.top, chartArea.width * (chart.getAnimationProgress('x') || 1), chartArea.height ); ctx.clip(); }, afterDatasetsDraw(chart) { chart.ctx.restore(); } }] });
注意事项
- 不要随意修改插件的裁剪边界,所有和数据绘制相关的裁剪逻辑都要以
chartArea的坐标为基准,避免覆盖坐标轴、图例、标题等其他组件的渲染区域 - 如果后续需要给图表加主标题、图例等组件,只要不修改插件的裁剪范围,都可以正常显示
- 轴标题的颜色、字号、边距等样式都可以在对应scale的
title配置项内直接调整,不需要额外写自定义渲染逻辑
内容的提问来源于stack exchange,提问作者Dash
相关产品推荐
相关产品推荐

