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

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);

关键部分说明

  1. 分组汇总:通过reduce遍历所有支出,生成一个{ 月份: 总金额 }的对象,自动完成同一月份的金额合并。
  2. 月份排序:原始支出数据的顺序可能是混乱的,通过moment的month()方法将月份按时间顺序排序,保证X轴从1月到12月依次展示。
  3. 数据匹配:根据排序后的月份数组提取对应总金额,确保标签和数据完全一一对应,解决了原代码中数据错位的问题。

额外提示

如果你的支出数据跨年度,建议在月份标签中加入年份(比如moment(expense.createdAt).format('YYYY-MMMM')),避免不同年份的同一个月份被错误合并。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:13:26