2012-08-13 46 views
7

我确信有一个非常简单而优雅的方法可以做到这一点,但我无法弄清楚。我有一个看起来像这样的一些输入数据:D3:使用嵌套函数将父数据的平面数据转化为层次结构

[ 
{id: 1, name: "Peter"}, 
{id: 2, name: "Paul", manager: 1}, 
{id: 3, name: "Mary", manager: 1}, 
{id: 4, name: "John", manager: 2}, 
{id: 5, name: "Jane", manager: 2} 
] 

如果可能的话,我想用d3.js鸟巢运营得到一个结构层次结构中的布局中使用。是这样的:在输出层级的数量是一样的,你指定按键功能的数量:

[ 
    {name: "Peter", children: [ 
      {name:"Paul", children: [ 
       {name:"John"}, 
       {name:"Jane"} 
      ]}, 
      {name:"Mary"} 
     ] 
    } 
] 

回答

12

因为嵌套产生一个固定层次你不能在这里使用鸟巢运营。

也就是说,你可以编写自己的函数来生成一棵树。假设根节点是输入数组中的第一个节点,您可以创建一个从ID到节点的映射,然后构造一棵懒惰的树。

function tree(nodes) { 
    var nodeById = {}; 

    // Index the nodes by id, in case they come out of order. 
    nodes.forEach(function(d) { 
    nodeById[d.id] = d; 
    }); 

    // Lazily compute children. 
    nodes.forEach(function(d) { 
    if ("manager" in d) { 
     var manager = nodeById[d.manager]; 
     if (manager.children) manager.children.push(d); 
     else manager.children = [d]; 
    } 
    }); 

    return nodes[0]; 
} 

如果您知道节点顺序列出,使得管理者他们的报告出现之前,您可以简化代码只有一次迭代。

+1

非常感谢,这非常有帮助。 (1)创建一个基于管理器(数组字典)的查找,(2)从一个已知的根开始,递归地向每个报表添加子元素。 – prauchfuss 2012-08-15 04:17:13

相关问题