我的根节点有未分类的子节点
我使用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.x
和node.y
值,但不会影响tree.nodes()
结果中的节点顺序功能。
所以问题是tree.sort()
与tree.nodes()
一起使用的正确方法是什么?
答案 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);
由此它将共享数据存储器