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

