2012-05-15 10 views
35

He creado el siguiente documento:¿Cómo acceder al parentNode de una selección d3.js?

<g> 
    <path class=​"line" name=​"gene_1" stroke=​"#aec7e8" d=​"M10.47...">​</path>​ 
    <path class=​"line" name=​"gene_2" stroke=​"#aec7e8" d=​"M10.47...">​</path>​ 
    <path class=​"line" name=​"gene_3" stroke=​"#aec7e8" d=​"M10.47...">​</path>​ 
    ... 
</g> 

Cuando ratón sobre cada camino que quiero para anexar la última en el interior del SVG: g por lo que aparece en la parte superior de las otras líneas, pero no sé cómo seleccionar adecuadamente el parentNode:

function onmouseover(d, i){ 
    var current_gene_name = d3.select(this).attr("name"), 
     current_gene_pcp = d3.select(".line[name=" + current_gene_name + "]"); 

    p1 = this.parentNode 

    p2 = current_gene_pcp[0].parentNode 

    p3 = current_gene_pcp[0][0].parentNode 

    //p.appendChild(this); 
} 

P1 funciona, pero quería asegurarse de que "este" es un .line, por lo que he preferido utilizar current_gene_pcp, pero p2 devuelve <html></html> como el padre, a pesar de que p3 devuelve el número correcto <g></g>. Esta última versión parece un error esperando a suceder. ¿Hay una mejor manera?

Respuesta

41

Una selección D3 es solo una matriz doble envuelta alrededor de los elementos seleccionados. Como encontró en p3, puede desreferenciar las matrices para encontrar su primer nodo, si lo desea. Sin embargo, un método mejor sí existe:

A partir de los documentos de selection.node():

Devuelve el primer elemento no null en la selección actual. Si la selección está vacía, devuelve null.

En su caso:

var dad = current_gene_pcp.node().parentNode; 

Sin embargo, si usted no necesita la línea que no sea el asa DOM, puede ser que también acaba de obtener que directa:

// Search document-wide... 
var dad = document.querySelector(".line[name=" + current_gene_name + "]"); 

// ...or only as a child of the current DOM element 
var dad = this.querySelector(".line[name=" + current_gene_name + "]"); 
32

Aquí hay una forma rápida de mover el elemento mouseover al frente:

selection.on("mouseover", function() { this.parentNode.appendChild(this); }); 

Vea también un related thread en el grupo d3-js.

+0

Este comportamiento es inestable. Cuando pruebo esto en Chrome en combinación con los estilos ': hover', los estilos se aplican correctamente. Cuando intento esto en Firefox (v20), los estilos no se aplican en absoluto. Cuando elimino este código 'mouseover', los estilos se aplican correctamente en Firefox. Supongo que esto es causado por el mouseover de un elemento que intenta eliminarse antes de volverse a unir como el último hijo de su DOM. –

5

Hay dos formas de acceder a ella.
O utilice el third variable de esta manera: someNode.attr("someAttrib", function(d, i, j) { console.log(d, i, j); });. El j contiene los datos que ha proporcionado al nodo padre.
o use d3.select(this.parentNode).data()[0].id;.

Un ejemplo:

<!DOCTYPE html> 
<meta charset="utf-8"> 
<body> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<div id="area", width="1000px" height="1000px"></div> 
<script> 
var GAP = 10, NODE_RADIUS = 14; 

    var nodes = [ 
    {id: 1, prop: [{id: 1, something: 1}], abc: 1}, 
    {id: 2, prop: [{id: 1, something: 1}, {id: 2, something: 1}, {id: 3, something: 1}], abc: 2}, 
    {id: 3, prop: [{id: 1, something: 1}, {id: 2, something: 1}], abc: 3}, 
    {id: 4, prop: [{id: 1, something: 1}], abc: 4}, 
    {id: 5, prop: [{id: 1, something: 1}], abc: 5}, 
    {id: 6, prop: [], abc: 6} 
    ]; 

var nodeLayer = d3.select("#area").selectAll(".node").data(nodes, function(d) {return d.id; }); 
var iNodes = nodeLayer.enter().append("svg").attr("class", "node"); 
    //append the black circle 
    iNodes.append("circle") 
       .style("fill", "black") 
       .attr("r", NODE_RADIUS) 
       .attr("cx", function(d) {return 10 + d.id * 10;}) 
       .attr("cy", 100); 

    iNodes.append("g").selectAll(".prop").data(function(d) {return d.prop;}).enter() 
      .append("text") 
       .text(function(d,i,j){console.log("parent id="+j); return d3.select(this.parentNode).data()[0].id;}) 
       .attr("dx", 50) 
       .attr("dy", 50) 
       .style("font-size", "8px") 
       .style("fill", d3.rgb(180,0,0)) 
       .style("text-anchor", "middle"); 

</script> 
</body>