2012-05-15 3 views
35

Я создал следующий документ:Как получить доступ к parentNode выбора 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> 

Когда я мыши на каждом пути, я хочу, чтобы добавить его в последний раз внутри SVG: г, чтобы он отображался поверх других линий, но я не знаю, как правильно выбрать 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 работает, но я хотел, чтобы убедиться, что «это» является .Строка, поэтому я предпочел использовать current_gene_pcp, но p2 возвращает <html></html> в качестве родителя, даже если p3 возвращает <g></g>. Эта последняя версия выглядит как ошибка, ожидающая появления. Есть ли способ лучше?

ответ

41

Выбор D3 - это всего лишь двойной массив, обернутый вокруг выбранного элемента (ов). Как вы нашли с p3, вы можете разыменовать массивы, чтобы найти свой первый узел, если хотите. Однако, лучший способ действительно существует:

Из документов для selection.node():

Возвращает первый не- null элемент в текущем выборе. Если выбор пуст, возвращается null.

В вашем случае:

var dad = current_gene_pcp.node().parentNode; 

Однако, если вам не нужна строка, кроме DOM ручки, вы можете также просто получить, что непосредственно:

// 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

Вот быстрый способ перемещения элемента мыши на передней панели:

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

См. Также related thread в группе d3-js.

+0

Такое поведение является неустойчивым. Когда я пробую это в Chrome в сочетании с стилями ': hover', стили будут правильно применены. Когда я пытаюсь это сделать в Firefox (v20), стили вообще не применяются. Когда я удаляю этот код «mouseover», стили правильно применяются в Firefox. Я предполагаю, что это вызвано «наведением мыши» элемента, пытающимся удалить себя, прежде чем оно будет присоединено к последнему ребенку его DOM. –

5

Существует два способа доступа к нему.
Либо используйте third variable следующим образом: someNode.attr("someAttrib", function(d, i, j) { console.log(d, i, j); });. j содержит данные, которые вы предоставили родительскому узлу.
или d3.select(this.parentNode).data()[0].id;.

Пример:

<!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> 
Смежные вопросы