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

基于数组创建Chart.js堆叠图表的技术咨询

基于每日奶瓶喂养数据构建Chart.js堆叠图表的问题解答

a. 当前数据格式是否正确?

严格来说,你的JSON数据格式虽然能被JavaScript解析,但并不规范,还会给后续处理添不少麻烦。核心问题有两个:

  • 对象的键包含空格和冒号(比如"2017-12-19 22:46:00"),虽然JS允许这种键,但不符合常规结构化数据的规范,读写和操作都很别扭;
  • 喂养记录和日期字段混在同一个对象里,没有统一的结构化嵌套,提取数据时需要额外做过滤处理。

更合理的格式应该把每个日期的喂养记录整理成嵌套数组/对象,比如:

const formattedData = [
  {
    date: "2017-12-19",
    feedings: [
      { time: "2017-12-19 22:46:00", amount: 341 }
    ]
  },
  {
    date: "2017-12-30",
    feedings: [
      { time: "2017-12-30 10:30:00", amount: 199 },
      { time: "2017-12-30 14:00:00", amount: 142 },
      { time: "2017-12-30 17:00:00", amount: 200 },
      { time: "2017-12-30 19:18:00", amount: 199 }
    ]
  },
  {
    date: "2017-12-31",
    feedings: [
      { time: "2017-12-31 15:43:00", amount: 341 },
      { time: "2017-12-31 16:30:00", amount: 199 }
    ]
  },
  {
    date: "2018-01-01",
    feedings: [
      { time: "2018-01-01 06:00:00", amount: 170 },
      { time: "2018-01-01 09:00:00", amount: 170 },
      { time: "2018-01-01 11:30:00", amount: 170 },
      { time: "2018-01-01 19:09:00", amount: 199 }
    ]
  }
];

这种结构清晰直观,后续处理数据时会轻松很多。

b. 如何将该数据动态导入Chart.js?能否通过循环批量添加?

当然可以通过循环批量处理数据,不管你用原始格式还是上面推荐的结构化格式,都能实现动态生成堆叠图表。下面分两种情况说明:

情况1:基于你提供的原始数据处理

首先需要把原始数据转换成Chart.js堆叠柱状图需要的结构(x轴标签、多个堆叠数据集),代码示例如下:

// 你的原始数据
const rawData = [
  {date: "2017-12-19", "2017-12-19 22:46:00": 341},
  {date: "2017-12-30", "2017-12-30 10:30:00": 199, "2017-12-30 14:00:00": 142, "2017-12-30 19:18:00": 199, "2017-12-30 17:00:00": 200},
  {date: "2017-12-31", "2017-12-31 15:43:00": 341, "2017-12-31 16:30:00": 199},
  {date: "2018-01-01", "2018-01-01 19:09:00": 199, "2018-01-01 06:00:00": 170, "2018-01-01 11:30:00": 170, "2018-01-01 09:00:00": 170}
];

// 1. 提取x轴标签(所有日期)
const labels = rawData.map(item => item.date);

// 2. 整理每日喂养量,先按时间排序再提取数值
const dailyFeedings = rawData.map(item => {
  // 过滤掉date字段,提取所有喂养记录
  const feedEntries = Object.entries(item).filter(([key]) => key !== 'date');
  // 按时间排序(避免原始数据中时间顺序混乱)
  feedEntries.sort(([timeA], [timeB]) => new Date(timeA) - new Date(timeB));
  // 只保留喂养量数值
  return feedEntries.map(([_, amount]) => amount);
});

// 3. 找出单日最多喂养次数,确定需要多少个数据集
const maxFeedCount = Math.max(...dailyFeedings.map(feeds => feeds.length));

// 4. 循环生成堆叠数据集
const datasets = [];
for (let i = 0; i < maxFeedCount; i++) {
  datasets.push({
    label: `第${i+1}次喂养`,
    // 对每个日期,取第i次喂养量,没有则填0
    data: dailyFeedings.map(feeds => feeds[i] || 0),
    // 随机生成背景色(也可以自定义固定颜色)
    backgroundColor: `rgba(${Math.floor(Math.random()*255)}, ${Math.floor(Math.random()*255)}, ${Math.floor(Math.random()*255)}, 0.7)`,
    stack: 'feed-stack' // 关键:所有需要堆叠的数据集必须用同一个stack值
  });
}

// 5. 初始化Chart.js图表
const ctx = document.getElementById('feedingChart').getContext('2d');
new Chart(ctx, {
  type: 'bar',
  data: {
    labels: labels,
    datasets: datasets
  },
  options: {
    responsive: true,
    scales: {
      x: { stacked: true }, // x轴堆叠
      y: { 
        stacked: true, // y轴堆叠
        title: { display: true, text: '喂养量' }
      }
    }
  }
});

情况2:基于推荐的结构化数据处理

如果用我之前推荐的formattedData格式,代码会更简洁,因为不需要额外过滤和排序:

// 推荐的结构化数据
const formattedData = [/* 内容同上 */];

const labels = formattedData.map(item => item.date);
const dailyFeedings = formattedData.map(item => item.feedings.map(feed => feed.amount));
const maxFeedCount = Math.max(...dailyFeedings.map(feeds => feeds.length));

const datasets = [];
for (let i = 0; i < maxFeedCount; i++) {
  datasets.push({
    label: `第${i+1}次喂养`,
    data: dailyFeedings.map(feeds => feeds[i] || 0),
    backgroundColor: `rgba(${Math.floor(Math.random()*255)}, ${Math.floor(Math.random()*255)}, ${Math.floor(Math.random()*255)}, 0.7)`,
    stack: 'feed-stack'
  });
}

// 初始化图表的代码和上面完全一致

不管哪种方式,都能轻松支持30个甚至更多日期的数据,循环会自动处理所有的喂养记录,不需要手动逐个添加。

内容的提问来源于stack exchange,提问作者Matchew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:25:03