如何遍历D3嵌套对象创建数组 提取多条形图subgroups变量
D3分组多条形图子分组提取方案
问题场景
使用d3-fetch从API获取多层嵌套JSON结构数据,示例数据如下:
{ "researcher": { "deployment": 3.55974264705882, "collaboration": 2.33547794117647, "supportlevel": 3.19944852941176 }, "data": { "deployment": 3.34428879310345, "collaboration": 2.08836206896552, "supportlevel": 2.953125 } }
已通过以下代码提取父级分组存入groups变量,用于X轴定位:
var groups = d3.map(data, function(d) {return(d)}).keys()
需要提取子级属性deployment、collaboration、supportlevel存入subgroups变量,适配如下分组条形图渲染逻辑:
// 渲染条形 svg.append("g") .selectAll("g") // 遍历每个父级分组 .data(data) .enter() .append("g") .attr("transform", function(d) { return "translate(" + x(d.group) + ",0)"; }) .selectAll("rect") .data(function(d) { return subgroups.map(function(key) { return {key: key, value: d[key]}; }); }) .enter().append("rect") .attr("x", function(d) { return xSubgroup(d.key); }) .attr("y", function(d) { return y(d.value); }) .attr("width", xSubgroup.bandwidth()) .attr("height", function(d) { return height - y(d.value); }) .attr("fill", function(d) { return color(d.key); });
实现步骤
- 转换原始数据为D3兼容的数组格式
原始数据是对象结构,D3的data()方法默认接收数组类型,先做格式转换,匹配渲染逻辑里的d.group字段调用:const chartData = Object.entries(data).map(([groupName, subProps]) => { return { group: groupName, ...subProps } }) - 提取子分组键存入
subgroups
所有父级分组的子属性完全一致,直接取第一个父级分组的属性键即可:
如果接口返回存在父级分组子属性不一致的边缘情况,使用去重版本的通用提取逻辑:// 最终得到 ["deployment", "collaboration", "supportlevel"] const subgroups = Object.keys(data[groups[0]])const subgroups = Array.from( new Set(Object.values(data).flatMap(item => Object.keys(item))) ) - 替换渲染逻辑的数据源
将原代码中.data(data)修改为.data(chartData),其余代码无需调整,即可正常渲染每个分类下3个条形的分组柱状图。
内容的提问来源于stack exchange,提问作者Rachel
相关产品推荐
相关产品推荐

