2012-09-07 23 views
8

Creo un gráfico de diseño de árbol usando d3js. Se puede hacer clic en los nodos para alternar mostrando los niños. El nodo hijo debe insertarse en una posición predefinida y luego hacer la transición a la ubicación deseada. El problema es que las coordenadas de inserción están siempre apagadas. Al depurar con Firebug, muestra que directamente después de agregar el nuevo nodo sus coordenadas son x = 51.42857142857142 yy = 200.0 aunque la línea
.attr("transform", "translate(90,100)") debería alterarlas (utilizo valores fijos aquí, para precisar mejor el problema.d3.tree => transformación parece no funcionar

¿Dónde está mi error

código completo:?

// Toggle children. 
function toggle(d) { 
    if (d.children) { 
    d._children = d.children; 
    d.children = null; 
    } else { 
    d.children = d._children; 
    d._children = null; 
    } 
} 

function toggleAll(d) { 
    if (d.children) { 
     d.children.forEach(toggleAll); 
     toggle(d); 
    } 
} 

function update(source) { 
    // Node movement delay 
    var duration = d3.event && 1500; 

    // Compute the new tree layout. 
    var nodes = tree.nodes(root).reverse(); 

    // Normalize for fixed-depth. 
    nodes.forEach(function(d) { d.y = d.depth * 100; }); 

    // Update the nodes… 
    var node = vis.selectAll("g.node") 
    .data(nodes, function(d) { return d.id || (d.id = ++i); }); 

    // Enter any new nodes at the parent's previous position. 
    var nodeEnter = node.enter().append("svg:g") 
    .attr("class", "node") 
    .attr("transform", "translate(90,100)") 
    .on("click", function(d) { toggle(d); update(d); }); 

    nodeEnter.append("svg:circle") 
    .attr("r", 1e-6); 


    // Transition nodes to their new position. 
    var nodeUpdate = node.transition() 
    .duration(duration) 
    .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; }) 

    nodeUpdate.select("circle") 
    .attr("r", 4.5) 
    .style("fill", function(d) { return d._children ? "red" : "#fff"; }); 



    // Transition exiting nodes to the parent's new position. 
    var nodeExit = node.exit().transition() 
    .duration(duration) 
    .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) 
    .remove(); 

// While moving the nodes, they need to shrink 
nodeExit.select("circle") 
    .attr("r", 1e-6); 


    // Stash the old positions for transition. 
    nodes.forEach(function(d) { 
    d.x0 = d.x; 
    d.y0 = d.y; 
    }); 
} 


var i = 0, root; 
var radius = 960/2; 
var tree = d3.layout.tree() 
    .size([360, radius - 120]); 
var diagonal = d3.svg.diagonal.radial() 
    .projection(function(d) { return [d.y, d.x/180 * Math.PI]; }); 

var vis = d3.select("#body").append("svg:svg") 
    .attr("width", radius * 2) 
    .attr("height", radius * 2 - 50) 
    .append("g") 
    .attr("transform", "translate(" + radius + "," + radius + ")"); 

d3.json("flare.json", function(json) { 
    root = json; 
    root.x0 = 0; 
    root.y0 = 0; 


    // Initialize the display to show a few nodes. 
    root.children.forEach(toggleAll); 
    toggle(root.children[1]); 

    update(root); 
}); 

+1

'transform's no altera las coordenadas que verás en el inspector DOM - ¿cómo estás determinando dónde está el nuevo nodo? | JSfiddles son importantes si desea aumentar sus posibilidades de obtener ayuda en SO. – ZachB

+0

aquí está un violín http://jsfiddle.net/94EWe/ –

+0

¿Puede ser más específico sobre lo que está tratando de hacer? Usted violó es una gran cantidad de datos sin explicación de cuál es su problema real. Tal vez incluya un árbol mucho más pequeño y una explicación del comportamiento deseado. –

Respuesta

1

cambia la inserción de coordenadas mediante el ajuste de la inicial transform, es decir, cambiar

.attr("transform", "translate(90,100)") 

Por ejemplo, si desea insertar los nuevos nodos en la posición de su nodo padre, puede hacer esto pasando una referencia al elemento padre a la función update y conseguir su transform valor:

var sourceNode = d3.select(parentElement); 

// Enter any new nodes at the parent's previous position. 
var nodeEnter = node.enter().append("svg:g") 
    .attr("class", "node") 
    .attr("transform", parentElement ? sourceNode.attr("transform") : "translate(90,100)") 
    .on("click", function (d) { 
    toggle(d); 
    update(d, this); 
}); 

Completa jsfiddle here.

Cuestiones relacionadas