Evite la superposición de nodos en el diseño de árbol en d3.js
tree nodes (2)
Yo tuve el mismo problema. Así es como lo resolví. Tengo el ancho asignado a cada nodo, la altura por el momento es la misma para todos los nodos (básicamente, los nodos con una altura menor que el nodo Height, se centran verticalmente):
var tree = d3.layout.tree().nodeSize([1, nodeHeight])
.separation(function(a, b) {
var width = a.width + b.width,
distance = width / 2 + 16; // horizontal distance between nodes = 16
return distance;
}),
nodes = tree.nodes(data),
links = tree.links(nodes);
Espero que esto ayude.
Creé un árbol plegable para representar algunos datos biológicos.
En este árbol, el tamaño del nodo representa la importancia del nodo. Como tengo una gran cantidad de datos y también los tamaños de los nodos varían, se superponen uno sobre el otro. Necesito especificar la distancia entre los nodos hermanos.
Intenté el método tree.separation () pero no funcionó.
El código es el siguiente:
tree.separation(seperator);
function seperator(a, b)
{
if(a.parent == b.parent)
{
if((a.abundance == (maxAbd)) || (b.abundance == (maxAbd)))
{
return 2;
}
else
{
return 1;
}
}
}
Esto me está dando error diciendo:
Unexpected value translate(433.33333333333337,NaN) parsing transform attribute.
Entiendo que después de agregar el método de separación no se puede calcular la coordenada x para los nodos. ¿Puede alguien ayudarme con cómo hacer esto?
También intenté modificar el código fuente como se sugiere en https://groups.google.com/forum/#!topic/d3-js/7Js0dGrnyek, pero tampoco funcionó.
Por favor sugiera alguna solución.
¡La respuesta de SiegS
simplemente funciona bien!
Mi situación es que: Mi nodo es en realidad un texto, que puede tener varios anchos, que no sé de antemano. Entonces, primero necesito calcular el ancho de cada nodo.
Tengo un objeto JSON json_data
como mis datos.
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.
...
Espero que esto ayude