Chart.js时间序列(timeseries)X轴添加折线注释的正确配置
在Chart.js时间序列(timeseries)X轴图表中添加折线注释的正确配置
当Chart.js图表的X轴设置为timeseries类型时,原本能正常工作的折线注释(line annotation)无法渲染,以下是问题场景及解决方案:
正常工作的非时间序列代码
function average(ctx) { const values = ctx.chart.data.datasets[0].data; return values.reduce((a, b) => a + b, 0) / values.length; } const ctx = document.getElementById('chart'); const mean = { type: 'line', drawTime: 'afterDraw', label: { display: true, content: (ctx) => average(ctx).toFixed(2), }, scaleID: 'y', value: (ctx) => average(ctx) }; const chart = new Chart(ctx, { type: 'line', data: { labels: ['', '', '', '', '', '', '', '', '', '', '', '', '', ''], datasets: [ { data: [42, 129, 53, 55, 52, 62, 68, 55, 61, 58, 66, 63, 53, 69] } ] }, options: { plugins: { annotation: { annotations: { mean } } } } });
无法渲染注释的时间序列代码
function average(ctx) { const values = ctx.chart.data.datasets[0].data; return values.reduce((a, b) => a + b, 0) / values.length; } const ctx = document.getElementById('chart'); const mean = { type: 'line', drawTime: 'afterDraw', label: { display: true, content: (ctx) => average(ctx).toFixed(2), }, scaleID: 'y', value: (ctx) => average(ctx) }; const chart = new Chart(ctx, { type: 'line', data: { datasets: [ { data: [ { x: '2023-04-03 10:32:09', y: 42 }, { x: '2023-04-03 10:32:16', y: 129 }, { x: '2023-04-03 10:32:29', y: 53 }, { x: '2023-04-03 10:32:37', y: 55 }, { x: '2023-04-03 10:32:44', y: 52 }, { x: '2023-04-03 10:32:51', y: 62 }, { x: '2023-04-03 10:33:04', y: 68 }, { x: '2023-04-03 10:33:12', y: 55 }, { x: '2023-04-03 10:33:26', y: 61 }, { x: '2023-04-03 10:34:11', y: 58 }, { x: '2023-04-03 10:34:27', y: 66 }, { x: '2023-04-03 10:34:34', y: 63 }, { x: '2023-04-03 10:34:48', y: 53 }, { x: '2023-04-03 10:34:55', y: 69 } ] }, ] }, options: { scales: { x: { type: 'timeseries', time: { unit: 'hour' }, ticks: { beginAtZero: true } } }, plugins: { annotation: { annotations: { mean } } } } });
问题原因与修正方案
问题核心在于**average函数的数值提取逻辑错误**:当X轴为时间序列时,数据集的data是包含x和y属性的对象数组,原代码直接累加数组元素(即对象)会导致计算结果为NaN,进而使注释的value失效,无法渲染。另外,时间序列X轴的ticks.beginAtZero配置无意义,可移除。
修正后的完整代码
function average(ctx) { // 提取每个数据点的y值进行平均值计算 const values = ctx.chart.data.datasets[0].data.map(item => item.y); return values.reduce((a, b) => a + b, 0) / values.length; } const ctx = document.getElementById('chart'); const mean = { type: 'line', drawTime: 'afterDraw', label: { display: true, content: (ctx) => average(ctx).toFixed(2), }, scaleID: 'y', value: (ctx) => average(ctx) }; const chart = new Chart(ctx, { type: 'line', data: { datasets: [ { data: [ { x: '2023-04-03 10:32:09', y: 42 }, { x: '2023-04-03 10:32:16', y: 129 }, { x: '2023-04-03 10:32:29', y: 53 }, { x: '2023-04-03 10:32:37', y: 55 }, { x: '2023-04-03 10:32:44', y: 52 }, { x: '2023-04-03 10:32:51', y: 62 }, { x: '2023-04-03 10:33:04', y: 68 }, { x: '2023-04-03 10:33:12', y: 55 }, { x: '2023-04-03 10:33:26', y: 61 }, { x: '2023-04-03 10:34:11', y: 58 }, { x: '2023-04-03 10:34:27', y: 66 }, { x: '2023-04-03 10:34:34', y: 63 }, { x: '2023-04-03 10:34:48', y: 53 }, { x: '2023-04-03 10:34:55', y: 69 } ] }, ] }, options: { scales: { x: { type: 'timeseries', time: { unit: 'hour' } } }, plugins: { annotation: { annotations: { mean } } } } });
关键修改点
- 在
average函数中,通过map(item => item.y)提取数据点的y属性值,确保平均值计算正确 - 移除X轴配置中无效的
ticks.beginAtZero配置
内容的提问来源于stack exchange,提问作者Sig
相关产品推荐
相关产品推荐

