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

基于现有数据重组JSON以适配D3堆叠柱状图需求

没问题,我帮你搞定这个D3堆叠柱状图的数据重组需求!其实核心就是先拿到所有唯一的ename,再给每个数据对象补全所有ename对应的字段——匹配的用自身的total,不匹配的就设为0。下面是具体的实现步骤和代码示例:

步骤1:提取所有唯一的ename

首先,我们需要从原始数据里把所有不重复的ename捞出来,用JS的Set就能轻松去重:

// 假设你的原始数据存在rawData变量里
const rawData = [
  {"id":"1", "month":"1", "total":"10", "year":"2012", "ename":"Alice"},
  {"id":"2", "month":"1", "total":"15", "year":"2012", "ename":"Bob"},
  {"id":"3", "month":"2", "total":"8", "year":"2012", "ename":"Alice"},
  {"id":"4", "month":"2", "total":"12", "year":"2012", "ename":"Charlie"},
];

// 提取所有唯一ename,转成数组
const uniqueEnames = [...new Set(rawData.map(item => item.ename))];
// 结果:["Alice", "Bob", "Charlie"]
步骤2:重组每个数据对象

接下来遍历每个原始数据对象,复制它原有字段的同时,为每个唯一ename添加对应的字段。这里要注意把字符串类型的total转成数字——毕竟D3堆叠图需要数值类型来计算高度:

const processedData = rawData.map(item => {
  // 先复制原始对象的所有属性(保留id、month、year这些)
  const newItem = {...item};
  
  // 给每个唯一ename添字段,匹配的用自身total转数字,否则设0
  uniqueEnames.forEach(name => {
    newItem[name] = item.ename === name ? Number(item.total) : 0;
  });
  
  // 如果你不需要原来的ename和total字段,可以删掉
  // delete newItem.ename;
  // delete newItem.total;
  
  return newItem;
});
额外优化:处理重复分组的情况

如果你的原始数据里,同一个month+year+ename组合有多个条目(比如同一个月同一年同一个人有多条记录),那得先把这些记录的total聚合求和,不然处理后会有重复的分组,堆叠图会出错。用D3的d3.group就能搞定:

// 先聚合相同(month, year, ename)的total之和
const aggregatedData = Array.from(
  d3.group(rawData, d => `${d.month}-${d.year}-${d.ename}`),
  ([key, values]) => {
    const [month, year, ename] = key.split('-');
    // 把所有total转数字后求和
    const total = values.reduce((sum, item) => sum + Number(item.total), 0);
    // 保留第一条的id,或者你可以自己生成新id
    return {id: values[0].id, month, year, ename, total: String(total)};
  }
);

// 然后再对aggregatedData执行步骤2的重组操作就行
最终效果示例

处理后的数据会变成这样,完全符合D3堆叠柱状图的要求:

[
  {"id":"1", "month":"1", "total":"10", "year":"2012", "ename":"Alice", "Alice":10, "Bob":0, "Charlie":0},
  {"id":"2", "month":"1", "total":"15", "year":"2012", "ename":"Bob", "Alice":0, "Bob":15, "Charlie":0},
  {"id":"3", "month":"2", "total":"8", "year":"2012", "ename":"Alice", "Alice":8, "Bob":0, "Charlie":0},
  {"id":"4", "month":"2", "total":"12", "year":"2012", "ename":"Charlie", "Alice":0, "Bob":0, "Charlie":12},
]

这样处理后,你直接把processedData喂给d3.stack()就能生成堆叠图需要的结构啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:50:05