javascript - 将平面表转换为层次结构
问题描述
我想将表从 csv 转换为层次结构。该表具有以下格式:
lvl1 lvl2 lvl3 size
A a 1 1
A a 2 2
A b 1 3
A b 2 4
B a 1 5
B a 2 6
B b 1 7
B b 2 8
转换为下面的 JSON 对象。
我d3.nest
是这样使用的:
var n = d3.nest()
.key(d => d.lvl1)
.key(d => d.lvl2)
.key(d => d.lvl3)
.entries(d)
这导致以下格式几乎是我想要传递给的格式d3.hierarchy
:
[{
"key": "A",
"values": [{
"key": "a",
"values": [{
"key": "1",
"values": [{
"lvl1": "A",
"lvl2": "a",
"lvl3": 1,
"size": 1
}]
},
{
"key": "2",
"values": [{
"lvl1": "A",
"lvl2": "a",
"lvl3": 2,
"size": 2
}]
}
]
}]
}
//...
]
但是,这增加了太多级别,理想情况下我希望得到以下输出:
[{
"key": "A",
"values": [{
"key": "a",
"values": [{
"key": "1",
"size": 1
},
{
"key": "2",
"size": 2
}
]
}]
} //,...
]
这种格式我可以方便地传递给d3.hierarchy(n, d => d.values)
. 如何做到这一点?
注意 我不在乎叶子中是否有其他字段,因此,只要叶子不再嵌套,这样的输出也可以:
[{
"key": "A",
"values": [{
"key": "a",
"values": [{
"key": "1",
"lvl1": "A",
"lvl2": "a",
"lvl3": 1,
"size": 1
},
{
"key": "2",
"lvl1": "A",
"lvl2": "a",
"lvl3": 2,
"size": 2
}
]
}]
} //,...
]
JSON
[{
"lvl1": "A",
"lvl2": "a",
"lvl3": 1,
"size": 1
},
{
"lvl1": "A",
"lvl2": "a",
"lvl3": 2,
"size": 2
},
{
"lvl1": "A",
"lvl2": "b",
"lvl3": 1,
"size": 3
},
{
"lvl1": "A",
"lvl2": "b",
"lvl3": 2,
"size": 4
},
{
"lvl1": "B",
"lvl2": "a",
"lvl3": 1,
"size": 5
},
{
"lvl1": "B",
"lvl2": "a",
"lvl3": 2,
"size": 6
},
{
"lvl1": "B",
"lvl2": "b",
"lvl3": 1,
"size": 7
},
{
"lvl1": "B",
"lvl2": "b",
"lvl3": 2,
"size": 8
}
]
解决方案
你可以得到你想要的rollup
:
const n = d3.nest()
.key(d => d.lvl1)
.key(d => d.lvl2)
.rollup(d => d.map(e => ({
key: e.lvl3,
size: e.size
})))
.entries(data);
这是演示:
const data = [{
"lvl1": "A",
"lvl2": "a",
"lvl3": 1,
"size": 1
},
{
"lvl1": "A",
"lvl2": "a",
"lvl3": 2,
"size": 2
},
{
"lvl1": "A",
"lvl2": "b",
"lvl3": 1,
"size": 3
},
{
"lvl1": "A",
"lvl2": "b",
"lvl3": 2,
"size": 4
},
{
"lvl1": "B",
"lvl2": "a",
"lvl3": 1,
"size": 5
},
{
"lvl1": "B",
"lvl2": "a",
"lvl3": 2,
"size": 6
},
{
"lvl1": "B",
"lvl2": "b",
"lvl3": 1,
"size": 7
},
{
"lvl1": "B",
"lvl2": "b",
"lvl3": 2,
"size": 8
}
];
var nested = d3.nest()
.key(d => d.lvl1)
.key(d => d.lvl2)
.rollup(d => d.map(e => ({
key: e.lvl3,
size: e.size
})))
.entries(data);
console.log(nested);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
推荐阅读
- scala - 循环遍历多图值
- intellij-idea - 手动运行流类型检查器
- c++ - 从模板检查成员函数重载是否存在
- powerbi - 是否可以忽略 Power Query 中列标题的区分大小写?
- angular - Angular 对象中的多态性和继承
- aframe - safari 不会在 A-Frame 中加载具有跨源的动态资产
- c++ - 如何打破 Arduino 中的循环?
- java - 如何同步使用多个线程?
- postgresql - Using regexp_replace how do t replace a string with an exception
- python - 在 venv 中启动并运行通过“setuptools”打包的项目,满足所有要求