基于现有数据重组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
相关产品推荐
相关产品推荐

