You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chart.js中如何展示时间戳数量不同的两组折线数据集?

问题描述

我有两组时间序列数据:

  • 过去三天内约800个带时间戳的数据点
  • 过去三天内仅3个午夜时间戳的数据点

想在Chart.js的同一折线图中展示这两组数据,要求第二组数据的点能精准匹配第一组对应时间戳的位置。查文档得知所有数据集需拥有相同数量的标签,但旧版本的解决方案已经失效,请问有没有可行方案?还是必须对第二组数据插值补全到第一组的每个数据点?

示例代码

let labels = []

let date = new Date();
date.setDate(date.getDate() - 10);

const tenDays = [];
for (let i = 0; i < 10; i++) {
  const dateToDisplay = date.setDate(date.getDate() + 1);
  labels.push(new Date(dateToDisplay).toISOString());
  
  //array of 10 days in history from now
  tenDays.push({
    time: dateToDisplay,
    value: Math.floor(Math.random() * 10)
  })
}

date = new Date();
date.setDate(date.getDate() - 10);

//array of only three days, in tenDays array that is 1st, 5th and 10th day   
const threeDays = [
  {time: date, value: 6 },
  {time: date.setDate(date.getDate() + 5), value: 4 },
  {time: date.setDate(date.getDate() + 5), value: 5 },
];

var dataset1 = {
  label: 'dataset1',
  data: tenDays.map(data => data.value)
}

var dataset2 = {
  label: 'dataset2',
  data: threeDays.map(data => data.value)
}

//create Chart
new Chart(document.querySelector('#chart') as HTMLCanvasElement, {
  type: 'line',
  data: {
    labels: labels,
    datasets: [dataset1, dataset2],
  },
  options: {
    responsive: true,
    maintainAspectRatio: false,
  },
});

当前效果

第二组的3个数据点会依次对应到图表的前3个标签位置,无法匹配其实际时间戳对应的位置。

期望效果

第二组的3个数据点精准对应到各自时间戳匹配的标签位置,其余无数据的位置留空,折线仅在有数据的点之间连接。


可行方案:使用对象格式的数据点

Chart.js 支持直接使用包含x(时间)和y(数值)的对象作为数据点,不需要强制所有数据集和标签数量一致,只要将x轴配置为时间轴即可实现数据点的精准匹配。

修改后的代码示例

let date = new Date();
date.setDate(date.getDate() - 10);

const tenDays = [];
for (let i = 0; i < 10; i++) {
  const dateToDisplay = date.setDate(date.getDate() + 1);
  
  // 生成10天的历史数据
  tenDays.push({
    x: new Date(dateToDisplay), // 直接使用Date对象作为x值
    y: Math.floor(Math.random() * 10)
  })
}

date = new Date();
date.setDate(date.getDate() - 10);

// 仅包含3个特定日期的数据
const threeDays = [
  {x: new Date(date), y: 6 },
  {x: new Date(date.setDate(date.getDate() + 5)), y: 4 },
  {x: new Date(date.setDate(date.getDate() + 5)), y: 5 },
];

var dataset1 = {
  label: '数据集1',
  data: tenDays
}

var dataset2 = {
  label: '数据集2',
  data: threeDays,
  // 可选:配置折线样式,比如虚线连接空值
  borderDash: [5, 5],
  pointRadius: 5 // 放大第二组的点,方便查看
}

// 创建图表
new Chart(document.querySelector('#chart'), {
  type: 'line',
  data: {
    datasets: [dataset1, dataset2], // 不再需要单独的labels数组
  },
  options: {
    responsive: true,
    maintainAspectRatio: false,
    scales: {
      x: {
        type: 'time', // 关键:将x轴设置为时间轴
        time: {
          unit: 'day', // 根据数据粒度调整单位
          tooltipFormat: 'YYYY-MM-DD'
        },
        title: {
          display: true,
          text: '日期'
        }
      },
      y: {
        title: {
          display: true,
          text: '数值'
        }
      }
    }
  },
});

方案说明

  1. 数据格式调整:将每个数据点改为{x: Date对象, y: 数值}的格式,Chart.js会自动识别时间并匹配到对应位置。
  2. 时间轴配置:在options.scales.x中设置type: 'time',确保x轴按照时间顺序渲染,无需手动维护labels数组。
  3. 无需补全数据:第二组数据只需要保留有值的点,无数据的位置Chart.js会自动留空,折线会跳过空值(或通过spanGaps: true配置强制连接空值)。

备选方案:补全空值

如果必须使用数组索引匹配标签的方式,可以遍历第一组的labels,为第二组数据填充对应位置的null值:

// 生成dataset2的数据数组,匹配labels的每个位置
const dataset2Data = labels.map(label => {
  const match = threeDays.find(item => new Date(item.time).toISOString() === label);
  return match ? match.value : null;
});

var dataset2 = {
  label: '数据集2',
  data: dataset2Data,
  spanGaps: true // 可选:连接空值之间的折线
}

这种方法需要确保时间戳的字符串格式完全一致,适合数据量较小的场景。


内容的提问来源于stack exchange,提问作者Radek Šťasta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 08:27:05