复杂d3.nest()操作 [英] Complex d3.nest() manipulation

查看:136
本文介绍了复杂d3.nest()操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数组数组,如下所示:

I have an array of arrays that looks like this:

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 数据格式

I want to use d3.nest() or even just standard javascript to convert this data into a nested data structure that I can use with d3.partition. Specifically, I want to create the flare.json data format found here.

我想用d3.nest对应于数组中的索引位置。注意, 1 在上面示例数据中的所有子数组中位于第一个位置;因此,它在树的根。在数组中的下一个位置有三个值, 2 3 7 ,因此,根值 1 有3个子项。此时树的样子如下:

The levels of the json object I want to create with d3.nest() correspond to the index positions in the array. Notice that 1 is in the first position in all the subarrays in the example data above; therefore, it is at root of the tree. At the next positions in the arrays there are three values, 2, 3, and 7, therefore, the root value 1 has 3 children. At this point the tree looks like this:

      1
    / | \
   2  3  7

在子阵列的第三个位置有四个值, 3 5 6 。这些孩子将成为树中的地方如下:

At the third position in the subarrays there are four values, 3, 5, and 6. These children would be places into the tree as follows:

            1
        ____|___
       /    |    \
      2     3     7
     / \   /     / \
    3   6 6     3   5

如何使用d3.nest()产生这个数据结构?上面显示的示例数据的完整数据结构应如下所示:

How can I produce this data structure using d3.nest()? The full data structure with the example data I showed above should look like this:

   {"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}
        ]}
      ]}
    ]}


$ b b

我试图转换我上面的数组数据结构使用这样(非常错误):

I'm trying to convert my array data structure above using something like this (very wrong):

var data = d3.nest()
  .key(function(d, i) { return d.i; })
  .rollup(function(d) { return d.length; })

我一直在敲我的头一个星期,试图了解我如何从数组数组生成这种层次结构。如果有人能帮助我,我会非常感谢。

I've been banging my head for a week to try and understand how I can produce this hierarchal data structure from an array of arrays. I'd be very grateful if someone could help me out.

@ meetamit在评论中的答案是好的,但在我的情况下,我的树太深,无法重复申请 .keys()到数据,所以我不能手动写这样的函数。

@meetamit's answer in the comments is good, but in my case my tree is too deep to repeatedly apply .keys() to the data, so I cannot manually write a function like this.

推荐答案

这里有一个更简单的函数,它使用嵌套的 - 循环遍历每个数组的所有路径指令。

Here's a more straightforward function that just uses nested for-loops to cycle through all the path instructions in each of your set of arrays.

为了更容易找到具有给定标签的子元素,我已将 children 实现为数据对象/关联数组,而不是编号数组。如果您想要非常强大,可以使用 d3.map 了解该链接中描述的原因,但如果你的标签实际上是整数,那不会是一个问题。无论如何,它只是意味着当你需要访问孩子作为一个数组(例如,对于d3布局函数),你必须指定一个函数,使数组的对象的值 - d3.values(object) 效用函数

To make it easier to find the child element with a given label, I have implemented children as a data object/associative array instead of a numbered array. If you want to be really robust, you could use a d3.map for the reasons described at that link, but if your labels are actually integers than that's not going to be a problem. Either way, it just means that when you need to access the children as an array (e.g., for the d3 layout functions), you have to specify a function to make an array out of the values of the object -- the d3.values(object) utility function does it for you.

关键代码:

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.        
    }    
}

基本集群树状图图表方法:

http://fiddle.jshell.net/KWc73/

Implemented with your sample data array and a basic cluster dendogram charting method:
http://fiddle.jshell.net/KWc73/

已编辑以添加:

Edited to add: As mentioned in the comments, to get the output looking exactly as requested:


  1. 从默认根对象的children数组访问数据的根对象。
  1. Access the data's root object from the default root object's children array.
  2. Use a recursive function to cycle through the tree, replacing the children objects with children arrays.

像这样:

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);

更新的小提琴:

http://fiddle.jshell.net/KWc73/1/

这篇关于复杂d3.nest()操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆