避免d3.js中树布局中的节点重叠

避免d3.js中树布局中的节点重叠,d3.js,tree,nodes,hierarchy,D3.js,Tree,Nodes,Hierarchy,我创建了一个可折叠的树来表示一些生物数据 在该树中,节点的大小表示节点的重要性。由于我有大量的数据,而且节点的大小也各不相同,所以它们相互重叠。我需要指定同级节点之间的距离 我尝试了tree.separation()方法,但没有成功 代码如下: tree.separation(seperator); function seperator(a, b) { if(a.parent == b.parent) { if((a.abundance == (maxAbd))

我创建了一个可折叠的树来表示一些生物数据

在该树中,节点的大小表示节点的重要性。由于我有大量的数据,而且节点的大小也各不相同,所以它们相互重叠。我需要指定同级节点之间的距离

我尝试了tree.separation()方法,但没有成功

代码如下:

tree.separation(seperator);

function seperator(a, b)
{
    if(a.parent == b.parent)
    {
        if((a.abundance == (maxAbd)) || (b.abundance == (maxAbd)))
        {
            return 2;
        }
        else
        {
            return 1;
        }
    }
}
这给了我一个错误的说法:

Unexpected value translate(433.33333333333337,NaN) parsing transform attribute.
我理解,添加分离方法后,无法计算节点的x坐标。有谁能帮我做这件事吗

我还尝试按照中的建议修改源代码,但也不起作用


请提出一些解决方案。

我也有同样的问题。我就是这样解决的。我为每个节点指定了宽度,目前所有节点的高度都相同(基本上是高度小于节点高度的节点,垂直居中):


希望这有帮助。

SiegS的答案很好

我的情况是:我的节点实际上是一些文本,可能有不同的宽度,我事先不知道。所以我需要先计算每个节点的宽度

我有一个JSON对象
JSON\u data
作为我的数据

var tree = d3.layout.tree()
.sort(null)
.size([500,500])
.children( some_function_identify_children );

var nodes = tree.nodes(json_data); //which doesn't consider the node's size;
var links = tree.links(nodes);

// append a svg;
var layoutRoot = d3.select("body")
.append("svg:svg").attr("width","600").attr("height","600")
.append("svg:g")
.attr("class","container");

var nodeGroup = layoutRoot.selectAll("g.node")
.data(nodes)
.enter().append("text").text(function(d){return d.text;});
// now we knows the text of each node. 

//calculate each nodes's width by getBBox();
nodeGroup.each(function(d,i){d["width"] = this.getBBox().width;})

//set up a new tree layout which consider the node width. 
var newtree = d3.layout.tree()
.size([500,500])
.children(function(d) {return d.children;})
.separation(function(a,b){
  return (a.width+b.width)/2+2;
});

//recalcuate the node's x and y by newtree
newtree.nodes(nodes[0]); //nodes[0] is the root
links = newtree.links(nodes);

//redraw the svg using new nodes and links.
...
希望这会有所帮助

var tree = d3.layout.tree()
.sort(null)
.size([500,500])
.children( some_function_identify_children );

var nodes = tree.nodes(json_data); //which doesn't consider the node's size;
var links = tree.links(nodes);

// append a svg;
var layoutRoot = d3.select("body")
.append("svg:svg").attr("width","600").attr("height","600")
.append("svg:g")
.attr("class","container");

var nodeGroup = layoutRoot.selectAll("g.node")
.data(nodes)
.enter().append("text").text(function(d){return d.text;});
// now we knows the text of each node. 

//calculate each nodes's width by getBBox();
nodeGroup.each(function(d,i){d["width"] = this.getBBox().width;})

//set up a new tree layout which consider the node width. 
var newtree = d3.layout.tree()
.size([500,500])
.children(function(d) {return d.children;})
.separation(function(a,b){
  return (a.width+b.width)/2+2;
});

//recalcuate the node's x and y by newtree
newtree.nodes(nodes[0]); //nodes[0] is the root
links = newtree.links(nodes);

//redraw the svg using new nodes and links.
...