Javascript 如何访问 d3.js 选择的 parentNode?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10607732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:06:16  来源:igfitidea点击:

How to access the parentNode of a d3.js selection?

javascriptd3.js

提问by nachocab

I've created the following document:

我创建了以下文档:

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

When I mouse over each path I want to append it last inside the svg:g so it appears on top of the other lines, but I don't know how to properly select the parentNode:

当我将鼠标悬停在每条路径上时,我想将它最后附加到 svg:g 中,以便它出现在其他行的顶部,但我不知道如何正确选择 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 works, but I wanted to make sure that "this" is a .line, so I preferred to use current_gene_pcp, but p2 returns <html></html>as the parent, even though p3 returns the proper <g></g>. This last version seems like a bug waiting to happen. Is there a better way?

p1 有效,但我想确保“this”是一个 .line,所以我更喜欢使用 current_gene_pcp,但 p2<html></html>作为父级返回,即使 p3 返回正确的<g></g>. 最后一个版本似乎是一个等待发生的错误。有没有更好的办法?

回答by Phrogz

A D3 selection is just a double-array wrapped around the element(s) selected. As you found with p3, you can dereference the arrays to find your first node, if you want. However, a better method does exist:

D3 选择只是一个环绕所选元素的双数组。正如您在 中发现的那样p3,如果需要,您可以取消对数组的引用以找到您的第一个节点。但是,确实存在更好的方法:

From the docs for selection.node():

从文档中selection.node()

Returns the first non-nullelement in the current selection. If the selection is empty, returns null.

返回null当前选择中的第一个非元素。如果选择为空,则返回null

In your case:

在你的情况下:

var dad = current_gene_pcp.node().parentNode;

However, if you don't need the line other than the DOM handle, you might as well just get that directly:

但是,如果您不需要 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 + "]");

回答by mbostock

Here's a quick way to move the mouseover element to the front:

这是将鼠标悬停元素移到前面的快速方法:

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

See also a related threadin the d3-js group.

另请参阅d3-js 组中的相关线程

回答by Nav

There are two ways to access it.
Either use the third variablelike this: someNode.attr("someAttrib", function(d, i, j) { console.log(d, i, j); });. The jcontains the data you supplied to the parent node.
or use d3.select(this.parentNode).data()[0].id;.

有两种方法可以访问它。
无论是使用第三个变量是这样的:someNode.attr("someAttrib", function(d, i, j) { console.log(d, i, j); });。在j包含您提供给父节点的数据。
或使用d3.select(this.parentNode).data()[0].id;.

An example:

一个例子:

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

回答by Jason

For some reason, I had to go up 2x levels: console.log(">>"+my_chart.node().parentNode.parentNode.id+"<<")

出于某种原因,我不得不上升 2 倍: console.log(">>"+my_chart.node().parentNode.parentNode.id+"<<")