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

Angular 5:从JSON创建数组、求和及生成双折线图数据问题

解决Angular 5中JSON数据转双折线图统计数据的问题

我来帮你搞定这个问题!看起来你需要把包含createdDate和doneDate的JSON数据,转换成适合双折线图展示的两组统计数据(每日创建数、每日完成数),用reduce其实完全能实现,可能之前的写法没踩对关键点。下面一步步给你拆解实现步骤:

1. 先明确需求目标

我们最终要得到三个核心数据:

  • 所有出现过的日期集合(作为折线图的X轴标签)
  • 每个日期对应的创建任务数量(第一条折线数据)
  • 每个日期对应的完成任务数量(第二条折线数据)

2. 用reduce分别统计两类日期的数量

首先我们需要对原始数据做分组统计,用reduce分别累加createdDate和doneDate的每日数量:

// 假设你的原始数据是这样的数组(补全了你示例里的省略部分)
const rawData = [
  { createdDate: "2017-11-17", doneDate: "2017-11-17" },
  { createdDate: "2017-11-17", doneDate: "2017-11-17" },
  { createdDate: "2017-11-17", doneDate: "2017-11-18" },
  { createdDate: "2017-11-18", doneDate: "2017-11-18" },
  { createdDate: "2017-11-19", doneDate: "2017-11-19" },
  { createdDate: "2017-11-19", doneDate: "2017-11-20" }
];

// 统计每日创建数量
const createdCountMap = rawData.reduce((acc, item) => {
  const date = item.createdDate;
  // 如果当前日期已存在就累加,不存在则初始化为1
  acc[date] = (acc[date] || 0) + 1;
  return acc;
}, {} as Record<string, number>);

// 统计每日完成数量
const doneCountMap = rawData.reduce((acc, item) => {
  const date = item.doneDate;
  acc[date] = (acc[date] || 0) + 1;
  return acc;
}, {} as Record<string, number>);

3. 生成折线图所需的标准化数据

接下来需要把上面的统计结果转换成折线图能直接使用的数组格式,还要处理“某个日期只有创建数没有完成数(或反之)”的情况,此时对应位置填0:

// 获取所有唯一日期,并按时间顺序排序(避免X轴日期乱序)
const allDates = [...new Set([...Object.keys(createdCountMap), ...Object.keys(doneCountMap)])]
  .sort((a, b) => new Date(a).getTime() - new Date(b).getTime());

// 生成两条折线的数据数组
const createdSeries = allDates.map(date => createdCountMap[date] || 0);
const doneSeries = allDates.map(date => doneCountMap[date] || 0);

4. 整合为Angular组件可用的折线图数据

最后把这些数据整理成适合Angular折线图组件(比如ng2-charts)的格式,直接在组件中使用:

// 在你的Angular组件类中定义处理方法
processChartData(rawData: Array<{createdDate: string, doneDate: string}>) {
  // 重复上面的统计逻辑
  const createdCountMap = rawData.reduce((acc, item) => {
    const date = item.createdDate;
    acc[date] = (acc[date] || 0) + 1;
    return acc;
  }, {} as Record<string, number>);

  const doneCountMap = rawData.reduce((acc, item) => {
    const date = item.doneDate;
    acc[date] = (acc[date] || 0) + 1;
    return acc;
  }, {} as Record<string, number>);

  const allDates = [...new Set([...Object.keys(createdCountMap), ...Object.keys(doneCountMap)])]
    .sort((a, b) => new Date(a).getTime() - new Date(b).getTime());

  const createdSeries = allDates.map(date => createdCountMap[date] || 0);
  const doneSeries = allDates.map(date => doneCountMap[date] || 0);

  // 返回符合折线图要求的结构
  return {
    labels: allDates,
    datasets: [
      {
        label: '每日创建任务数',
        data: createdSeries,
        borderColor: '#e74c3c',
        tension: 0.1,
        fill: false
      },
      {
        label: '每日完成任务数',
        data: doneSeries,
        borderColor: '#2ecc71',
        tension: 0.1,
        fill: false
      }
    ]
  };
}

// 在组件中调用方法(比如在ngOnInit里)
ngOnInit() {
  const chartData = this.processChartData(rawData);
  // 把chartData传给你的折线图组件即可
}

可能踩坑的关键点

  • 累加器初始化:一定要给reduce的第二个参数指定类型(比如{} as Record<string, number>),Angular的TypeScript环境会更友好,也避免隐式类型错误
  • 日期排序:直接对日期字符串排序可能会出错,一定要转换成Date对象按时间戳排序
  • 空值处理:某个日期没有对应数据时,要返回0,不然折线图会出现断点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:02:37