Javascript 从数据访问 d3.js 元素属性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11336251/
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 05:29:42  来源:igfitidea点击:

Accessing d3.js element attributes from the datum?

javascriptsvgd3.js

提问by Mike Winter

I'm trying to access the cx & cy attributes of some specific svg circles which i have already drawn to the screen using d3.js's .data() function, can anyone help out? The code that's trying to access it is below.

我正在尝试访问我已经使用 d3.js 的 .data() 函数绘制到屏幕上的某些特定 svg 圆圈的 cx 和 cy 属性,有人可以帮忙吗?试图访问它的代码如下。

d3.selectAll(".mynode").each( function(d, i){
  if(d.someId == targetId){
    console.log( d.attr("cx") );    // just trying to demo my point, doesn't work
  }
}

I'm quite new to d3.js & javascript, so i'm not sure if i'm approaching this back to front anyways or perhaps i may have missed an inbuilt solution?

我对 d3.js 和 javascript 很陌生,所以我不确定我是否正在接近这个问题,或者我可能错过了一个内置的解决方案?

回答by Josh

Your code is trying to get an svg attribute from an item of data, when what you really want is to get that attribute from the svg DOM element, as in:

您的代码试图从数据项中获取 svg 属性,而您真正想要的是从 svg DOM 元素中获取该属性,如下所示:

console.log(d3.selectAll(".mynode").attr("cx"));

This will only give you the attribute for the first non-null element of your selection; You can also filteryour selection to get the DOM element you are looking for:

这只会为您提供选择的第一个非空元素的属性;您还可以过滤您的选择以获取您正在寻找的 DOM 元素:

console.log(d3.selectAll(".mynode").filter(_conditions_).attr("cx"));

Or, if you'd like to access the attributes of all selected elements, use thisin your each function:

或者,如果您想访问所有选定元素的属性,请this在您的 each 函数中使用:

d3.selectAll(".mynode").each( function(d, i){
  if(d.someId == targetId){
    console.log( d3.select(this).attr("cx") );
  }
}

回答by VividD

There is even simpler way: (providing index iis given)

还有更简单的方法:(提供索引i

d3.selectAll("circle")[0][i].attributes.cx.value

as it can be seen here.

正如它可以在这里看到的。

回答by mathheadinclouds

The filter method in the accepted answer is correct. The second approach in the accepted answer (using .each) is incorrect, and contains the same error as the questioner was making: if .data() is not called (which is the case here), then first argument d passed to .each will be undefined (and not the "current dom node", as all newbies, including myself, would expect); the current dom node you get via d3.select(this), which is correct within the if statement at the very end - the error is in the if test condition. Correct version follows.

接受的答案中的过滤方法是正确的。接受的答案中的第二种方法(使用 .each)是不正确的,并且包含与提问者相同的错误:如果 .data() 没有被调用(这里就是这种情况),则第一个参数 d 传递给 .each将是未定义的(而不是“当前的 dom 节点”,正如所有新手,包括我自己所期望的那样);您通过 d3.select(this) 获得的当前 dom 节点,这在最后的 if 语句中是正确的 - 错误在 if 测试条件中。正确版本如下。

d3.selectAll(".mynode").each(function(d,i){
    var elt = d3.select(this);
    if (elt.attr("id") == "yourTargetIdGoesHere"){
        console.log( elt.attr("cx") );
    }
});

fiddle: fiddle(containing code for both versions, i.e. filter and each)

小提琴:小提琴(包含两个版本的代码,即过滤器和每个)

UPDATE: my answer was assuming that you didn't use .data(), since you did not give the code for that; later I saw that you wrote that you did use .data()

更新:我的回答是假设您没有使用 .data(),因为您没有为此提供代码;后来我看到你写道你确实使用了 .data()

in that case, depending on your data structure, replacing d.attr("cx") by plain d.cx might work.

在这种情况下,根据您的数据结构,用普通 d.cx 替换 d.attr("cx") 可能会起作用。