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
相关产品推荐
相关产品推荐

