tree.sort真的有用吗?

时间:2014-04-22 14:49:06

标签: javascript d3.js

我的根节点有未分类的子节点 我使用tree.nodes(treeData)来获取节点列表并构建一个分层列表,我想要对它进行排序。请参阅jsfiddle或以下的示例代码:

/// define data
var treeData = {
    name: 'root',
    children: [
        { name: 1 },
        { name: 5 },
        { name: 2 },
        { name: 6 },
        { name: 4 },
        { name: 3, children: [ {name: 33 }, {name: 31 }, {name: 32 } ] },
        { name: 7 }
    ]
};

/// init tree
var tree = d3.layout.tree()
    .sort(function(a, b) { return d3.ascending(a.name, b.name); });
var nodes = tree.nodes(treeData); // nodes unsorted now
// uncomment this to get sorted nodes
// nodes = tree.nodes(treeData);

/// build hierarchy
var li = d3.select('ul').selectAll('li').data(nodes);
li.enter().append('li')
    .html(function(d) {
        return Array(d.depth).join('∣  ') + (d.depth ? '↳ ' : '') + "<b>"+d.name+"</b>" + " x: " + Math.round(d.x*100)/100 });

定义tree.sort()时,treeData.children数组已排序,但tree.nodes(treeData)返回未排序的节点数组。

此外,我发现如果我两次调用tree.nodes(),则会返回已排序的节点:

nodes = tree.nodes(treeData) // returns unsorted: 1, 5, 2... but treeData.children is now sorted
nodes = tree.nodes(treeData) // returns sorted: 1, 2, 3...

似乎tree.sort()会影响treeData.children数组以及node.xnode.y值,但不会影响tree.nodes()结果中的节点顺序功能。

所以问题是tree.sort()tree.nodes()一起使用的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

d3.layout.tree().sort()d3.layout.hiearchy()的一部分。

在版本3.5.6(我看过的那个)中,d3.layout.hierarchy函数按照root树提供的顺序构建一个节点数组,按照已由{定义的顺序{1}}。

树的每个节点都按此顺序插入到返回的节点数组中。

构建数组后,node.children树按root排序,但这只对树的d3_layout_hierarchyVisitAfter进行排序,而不是节点数组。

节点数组本身永远不会排序。节点数组中节点的顺序基于node.children树及其root顺序的顺序。因此,建议先对它进行排序(或者为什么第二次调用node.children有效 - 因为孩子们现在已经分类了)

D3 4.x documentation for sort它说的最后一件事是

  

如果您要调用分层布局,则必须调用node.sort   希望新的排序顺序影响布局;请参阅node.sum   示例

因此虽然3文档没有明确说明这一点,但看起来代码就是这样编写的。

答案 1 :(得分:0)

正如您在source code上看到的那样,d3只会再现array sort method ...

所以问题在于你需要先对它们进行排序......它们&#34;追加&#34;到树上。

查看解决方案:http://jsbin.com/sonil/1/edit

////sort the data
treeData.children.sort(function(a, b) { return d3.ascending(a.name, b.name); });
/// init tree
var tree = d3.layout.tree();//.sort(function(a, b) { return d3.ascending(a.name, b.name); });
var nodes = tree.nodes(treeData); // nodes sorted

答案 2 :(得分:0)

您可以按

对分层数据进行排序
var partition = d3.layout.partition().value(function(d) { return d.size; });

partition(data);

由此它将共享数据存储器