var arrays = [[1,2,3,4,5],[1,6,7,5]]
我想使用d3.nest()或者甚至只是标准的javascript来将这些数据转换成一个嵌套的数据结构,我可以使用d3.partition.具体来说,我想创建这里找到的flare.json
data format.
要使用d3.nest()创建的json对象的级别对应于数组中的索引位置.请注意,在上述示例数据中,1位于所有子阵列的第一个位置;因此,它是在树的根.在阵列中的下一个位置有三个值2,3和7,因此根值1有3个子节点.在这一点上,树看起来像这样:
1 / | \ 2 3 7
在子阵列中的第三个位置有四个值,即3,5和6.这些子节点将放在树中,如下所示:
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": 3,"children": [ {"label": 6,"children": [ {"label": 5} ]} ]} ]},{"label": 7,"children": [ {"label": 5} ]},{"label": 5} ]} ]} ]}
我试图使用这样的东西来转换我的数组数据结构(非常错误):
var data = d3.nest() .key(function(d,i) { return d.i; }) .rollup(function(d) { return d.length; })
我一直在敲打我的头一个星期,尝试了解如何从一系列阵列生成这种层次结构的数据结构.如果有人能帮助我,我将非常感激.
@queryamit在评论中的答案是好的,但在我的情况下,我的树太深了,不能重复地使用.keys()到数据,所以我不能手动编写一个这样的函数.
解决方法
为了更容易地找到带有给定标签的子元素,我已经将子元素实现为数据对象/关联数组,而不是编号的数组.如果你想要真正强壮,可以使用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);