React Chart JS 2动态数据展示问题:按月汇总支出折线图实现
解决React Chart JS 2中按月汇总支出的折线图问题
我来帮你搞定这个折线图的金额汇总问题!你现在的代码只是把每笔支出的金额和对应月份单独提取成数组,导致同一个月份会重复出现在标签里,数据也没有合并——这就是图表展示异常的核心原因。下面是调整后的完整解决方案:
核心思路
我们需要先把所有支出按月份分组,对每个月份的金额求和,再把整理好的有序月份标签和对应总金额传给Chart.js。这里用JavaScript的reduce方法完成分组汇总,同时还要确保月份按时间顺序排列,让折线图的X轴逻辑更合理。
修改后的完整代码
import React from 'react'; import { connect } from 'react-redux'; import { Line } from 'react-chartjs-2'; import moment from 'moment'; const Chart = (props) => { // 第一步:按月份分组并汇总金额 const monthlyExpenses = props.expenses.reduce((acc, expense) => { // 获取完整月份名称(例:"May"、"April") const month = moment(expense.createdAt).format('MMMM'); // 初始化未记录过的月份金额为0 if (!acc[month]) { acc[month] = 0; } // 累加当前支出的金额到对应月份 acc[month] += expense.amount; return acc; }, {}); // 第二步:将月份按时间顺序排序(避免标签乱序) const sortedMonths = Object.keys(monthlyExpenses).sort((a, b) => { return moment(a, 'MMMM').month() - moment(b, 'MMMM').month(); }); // 第三步:生成排序后的总金额数组,与月份标签一一对应 const summedAmounts = sortedMonths.map(month => monthlyExpenses[month]); const data = { labels: sortedMonths, // 使用排序后的月份作为X轴标签 datasets: [ { label: '月度支出汇总', fill: false, lineTension: 0.1, backgroundColor: 'rgba(75,192,192,0.4)', borderColor: 'rgba(75,192,192,1)', borderCapStyle: 'butt', borderDash: [], borderDashOffset: 0.0, borderJoinStyle: 'miter', pointBorderColor: 'rgba(75,192,192,1)', pointBackgroundColor: '#fff', pointBorderWidth: 1, pointHoverRadius: 5, pointHoverBackgroundColor: 'rgba(75,192,192,1)', pointHoverBorderColor: 'rgba(220,220,220,1)', pointHoverBorderWidth: 2, pointRadius: 1, pointHitRadius: 10, data: summedAmounts // 使用汇总后的金额数据 } ] }; return ( <div> <div className="page-header"> <div className="content-container"> <h1 className="page-header__title">CHART</h1> </div> </div> <div className="content-container"> <h2>月度支出折线图</h2> <Line data={data} /> </div> </div> ) }; const mapStateToProps = (state) => { return { expenses: state.expenses }; } export default connect(mapStateToProps)(Chart);
关键部分说明
- 分组汇总:通过
reduce遍历所有支出,生成一个{ 月份: 总金额 }的对象,自动完成同一月份的金额合并。 - 月份排序:原始支出数据的顺序可能是混乱的,通过
moment的month()方法将月份按时间顺序排序,保证X轴从1月到12月依次展示。 - 数据匹配:根据排序后的月份数组提取对应总金额,确保标签和数据完全一一对应,解决了原代码中数据错位的问题。
额外提示
如果你的支出数据跨年度,建议在月份标签中加入年份(比如moment(expense.createdAt).format('YYYY-MMMM')),避免不同年份的同一个月份被错误合并。
内容的提问来源于stack exchange,提问作者Sujan Shrestha
相关产品推荐
相关产品推荐

