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

如何对d3.rollup分组后的数据按年累计并绘制分年度折线图

D3 按年统计累计折线图实现方案

你可以在d3.rollup完成分组求和后,遍历每个年份的分组数据,使用d3.cumsum计算当年累计值即可,具体修改步骤如下:

1. 调整数据处理逻辑

修改原有的数据处理代码,在分组后新增累计值计算逻辑:

data = {
  const sortedData = rawdata.sort((a, b) => d3.ascending(a.date, b.date));
  // 先按「年份-日期」两层分组,计算单日求和值
  const yearDateSum = d3.rollup(
    sortedData,
    (v) => d3.sum(v, (d) => d.value),
    (d) => d.date.getFullYear(),
    (d) => d.date
  );
  // 按年份计算累计值
  const cumulativeByYear = new Map();
  for (const [year, dateMap] of yearDateSum) {
    // 将内层日期-值Map转为有序数组
    const dateValues = Array.from(dateMap, ([date, value]) => ({date, value}));
    // 计算当前年份的累计值序列
    const cumulativeValues = d3.cumsum(dateValues, d => d.value);
    // 拼接累计值到原始数据条目
    const yearCumData = dateValues.map((item, index) => ({
      ...item,
      cumValue: cumulativeValues[index]
    }));
    cumulativeByYear.set(year, yearCumData);
  }
  return cumulativeByYear;
}

2. 调整折线生成器取值

修改你的d3.line折线生成器配置,将y轴的取值从单日值改为累计值即可,原有join渲染逻辑无需修改:

// 仅需修改y字段的映射规则即可
const line = d3.line()
  .x(d => xScale(d.date))
  .y(d => yScale(d.cumValue)); // 替换原有d.value取值逻辑

可选:年份折线日期对齐

如果你需要所有年份的折线都在同一个x轴区间(1月1日-12月31日)对齐展示,可以在生成yearCumData时额外计算当年日序字段:

const yearCumData = dateValues.map((item, index) => ({
  ...item,
  cumValue: cumulativeValues[index],
  // 计算当前日期是当年的第几天
  dayOfYear: d3.timeDayOfYear(item.date)
}));
// 对应调整x轴比例尺和折线生成器的x取值
const xScale = d3.scaleLinear()
  .domain([1, 366])
  .range([0, chartWidth]);
const line = d3.line()
  .x(d => xScale(d.dayOfYear))
  .y(d => yScale(d.cumValue));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 05:36:00