我有一个数组,看起来像这样:
var arrays = [[1,2,3,4,5],
[1,2,6,4,5],
[1,3,6,4,5],
[1,2,3,6,5],
[1,7,5],
[1,7,3,5]]
我想用
d3.nest()
甚至只是标准的 javascript 将这些数据转换为我可以与 d3.partition
一起使用的嵌套数据结构。 .具体来说,我想创建这个
flare.json
数据格式。我想用
d3.nest()
创建的 json 对象的级别对应于数组中的索引位置。请注意 1
在上面的示例数据中位于所有子数组的第一个位置;因此,它位于树的根部。在数组的下一个位置有三个值,2
, 3
, 和 7
,因此,根值 1
有3个 child 。此时树看起来像这样: 1
/ | \
2 3 7
在子数组的第三个位置有四个值,
3
, 5
, 和 6
.这些 child 将被放入树中,如下所示: 1
____|___
/ | \
2 3 7
/ \ / / \
3 6 6 3 5
如何使用
d3.nest()
生成此数据结构?带有我上面显示的示例数据的完整数据结构应如下所示: {"label": 1,
"children": [
{"label": 2, "children": [
{"label": 3, "children": [
{"label": 4, "children": [
{"label": 5}
]},
{"label": 6, "children": [
{"label": 5}
]}
]},
{"label": 6, "children": [
{"label": 4, "children": [
{"label": 5}
]}
]},
{"label": 3, "children": [
{"label": 6, "children": [
{"label": 4, "children": [
{"label": 5}
]}
]}
]},
{"label": 7, "children": [
{"label": 3, "children": [
{"label": 5}
]},
{"label": 5}
]}
]}
]}
我正在尝试使用这样的东西(非常错误)转换上面的数组数据结构:
var data = d3.nest()
.key(function(d, i) { return d.i; })
.rollup(function(d) { return d.length; })
一个星期以来,我一直在绞尽脑汁,试图了解如何从数组数组中生成这种分层数据结构。如果有人可以帮助我,我将不胜感激。
@meetamit 在评论中的回答很好,但就我而言,我的树太深而无法重复应用
.keys()
到数据,所以我不能手动编写这样的函数。
最佳答案
这是一个更直接的函数,它只使用嵌套 for
-loops 循环遍历每组数组中的所有路径指令。
为了更容易找到具有给定标签的子元素,我实现了 children
作为数据对象/关联数组而不是编号数组。如果你想变得非常健壮,你可以使用 d3.map由于该链接中描述的原因,但如果您的标签实际上是整数,那么这不会成为问题。无论哪种方式,这都意味着当您需要将子项作为数组访问时(例如,对于 d3 布局函数),您必须指定一个函数来从对象的值中创建一个数组—— d3.values(object)
效用函数为您完成。
关键代码:
var root={},
path, node, next, i,j, N, M;
for (i = 0, N=arrays.length; i<N; i++){
//for each path in the data array
path = arrays[i];
node = root; //start the path from the root
for (j=0,M=path.length; j<M; j++){
//follow the path through the tree
//creating new nodes as necessary
if (!node.children){
//undefined, so create it:
node.children = {};
//children is defined as an object
//(not array) to allow named keys
}
next = node.children[path[j]];
//find the child node whose key matches
//the label of this step in the path
if (!next) {
//undefined, so create
next = node.children[path[j]] =
{label:path[j]};
}
node = next;
// step down the tree before analyzing the
// next step in the path.
}
}
使用您的示例数据数组和基本 cluster dendogram 实现制图方法:
http://fiddle.jshell.net/KWc73/
编辑添加:
如评论中所述,要使输出看起来完全符合要求:
像这样:
root = d3.values(root.children)[0];
//this is the root from the original data,
//assuming all paths start from one root, like in the example data
//recurse through the tree, turning the child
//objects into arrays
function childrenToArray(n){
if (n.children) {
//this node has children
n.children = d3.values(n.children);
//convert to array
n.children.forEach(childrenToArray);
//recurse down tree
}
}
childrenToArray(root);
更新的 fiddle :
http://fiddle.jshell.net/KWc73/1/
关于d3.js - 复杂的 d3.nest() 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20913689/