最有效地访问d3树中最右边/最左边的表兄节点

时间:2017-08-16 20:41:53

标签: javascript performance d3.js tree hierarchical-data

D3 JavaScript可视化库拥有自己的hierarchical structurestrees实现。

节点存储对其父节点的引用(node.parent)和对children数组(node.children)的引用,以及它们在树中的深度/高度。

D3还为inorder/preorder/breath-first遍历提供了方法

鉴于此,访问节点最右侧/最左侧表亲的最有效方法是什么?

对于树:

    root
   /    \
 a  b   c d
 /\ /\ /\ /\
e fg hi jk l

f 最左边的表兄 g c 最右边的表兄 > b

1 个答案:

答案 0 :(得分:0)

根据D3树的一个简单特性,有一种简单的方法可以将节点连接到一行中给定节点的左侧和右侧:在该行中,节点遵循序列descendants数组中。

让我们看看使用this bl.ocks。不幸的是,我必须使用bl.ocks,因为如果我尝试console.log D3选择,Stack Overflow片段会冻结(注意:bl.ocks不是我的,我只是在网上找到它。)

所以,在那个bl.ocks中,正如你所看到的,最后一行是:

  

A的儿子 - A的女儿 - B的儿子 - B的儿子 - 儿子#2 of B

让我们得到一个包含这些节点的数组(第三行,深度= 2):

var row = nodes.descendants().filter(function(d) {
    return d.depth === 2
});

现在我们有一个数组,其中包含最后一行中的所有节点(5个元素)。

假设我们想要找到Son of B左侧和右侧的人。首先,我们得到该特定节点:

var sonOfB = row.filter(function(d) {
    return d.data.name === "Son of B"
});

现在是重要的部分:如果我们知道数组中该节点的索引......

row.indexOf(sonOfB[0])

...我们可以将节点放在左侧和右侧:

var toTheLeft = row[row.indexOf(sonOfB[0]) - 1];
//to the left, subtract 1 -------------------^

var toTheRight = row[row.indexOf(sonOfB[0]) +1];
//to the right, add 1 -----------------------^

在那个bl.ocks中查看控制台。你会看到这个:

console.log("To the left: " + toTheLeft.data.name)
    //returns "To the left: Daughter of A"
console.log("To the Right: " + toTheRight.data.name)
    //returns "To the Right: Daughter of B"

PS:这是单向访问左/右节点。我会避免对“最有效”的方式说些什么,因为它看起来非常基于意见。也许“最惯用的”方式是一个更好的问题,但即便如此,这也是值得怀疑的。