问题描述
我在看另一个stackoverflow问题,我尝试以下:
I was looking at another stackoverflow question and I tried the following:
d3.selectAll(links.filter(function(db) {
return db.source.id == 'foo'
})).each(function(p) {
console.log (p.source.id)
})
并发现它返回了一个
作为一个具有.source.id值的正确的对象数组(这个例子使用D3的强制导向网络中的标准链接符号)。
even though the filtered selection comes back as a proper array of objects with .source.id values (this example uses the standard link notation found in D3's force-directed networks).
我只是好奇
推荐答案
确保你清楚你使用以下两种方法中的哪一种:
Make sure you are clear on which of the two following methods you are using:
https://github.com/mbostock/d3/wiki/Selections#wiki-filter
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filterhttps://github.com/mbostock/d3/wiki/Selections#wiki-filter
d3.selectAll函数接受选择器字符串或DOM节点数组。您的情况是哪一种?
The d3.selectAll function accepts a selector string or an array of DOM nodes. Which one is it in your case?
请记住selection.each()回调中的变量p函数对应于绑定到选择中的元素的数据。
Remember that the variable p in the selection.each() callback function corresponds to the datum bound to the elements in the selection.
UPDATE
您的链接变量似乎是一个常规JavaScript对象数组。这不正确,因为 d3.selectAll
函数需要一个DOM节点数组(或一个选择器字符串)。有趣的是,如果你使用常规数组作为参数,它不会抱怨;例如,您仍然可以调用 selection.each
方法:
Your links variable seems to be an array of regular JavaScript objects. This is not correct because the d3.selectAll
function expects an array of DOM nodes (or a selector string). Interestingly, it will not complain if you use a regular array as argument; for example, you can still invoke the selection.each
method:
调用当前
选择中每个元素的指定函数,传递当前数据d和索引i, $ b当前DOM元素的上下文。这个运算符在内部使用
几乎所有其他运算符,并可以用于调用任意
代码为每个选定的元素。每个操作符可以通过在
回调函数中使用d3.select(this)递归地用于
过程选择。
Invokes the specified function for each element in the current selection, passing in the current datum d and index i, with the this context of the current DOM element. This operator is used internally by nearly every other operator, and can be used to invoke arbitrary code for each selected element. The each operator can be used to process selections recursively, by using d3.select(this) within the callback function.
但是,因为选择不是一个真正的DOM节点选择绑定到它们的数据,你会看到函数中的第一个参数(通常为d,在你的情况下为p)将是未定义的。
However, because the selection is not a real selection of DOM nodes with data bound to them, you see that the first argument in the function (normally d, in your case p) will be undefined.
第二个参数,索引i,仍然对应于我们迭代的原始数组的索引。这是为什么 d3.selectAll(links).each(function(p,i){console.log(links [i] .source.id);})
为你工作。它基本上是做这个(非d3)JavaScript表达式: links.forEach(function(v,i){console.log(links [i] .source.id);})
The second argument, the index i, will still correspond to the index of the original array that we are iterating over. That is the reason why d3.selectAll(links).each(function(p, i) { console.log(links[i].source.id); })
worked for you. It is basically doing the same as this (non-d3) JavaScript expression: links.forEach(function(v, i) { console.log(links[i].source.id); })
您正在查看的一个简单示例:
One more simplified example of what you were looking at:
// anti-pattern:
var arr = ['a', 'b', 'c'];
d3.selectAll(arr)
.each(function(d, i) {
console.log(d, i, arr[i]);
});
哪些日志到控制台:
undefined 0 "a"
undefined 1 "b"
undefined 2 "c"
所以,如果你试图检查强制导向布局中的链接,你可以选择代表这些链接的DOM节点。采取D3库中包含的标准力示例:并从控制台运行以下命令:
So, instead, if you're trying to inspect the links in a force-directed layout you could select the DOM nodes that represent those links. Take the standard force example included in the D3 library: http://d3-example.herokuapp.com/examples/force/force.htm and run the following from the console:
d3.selectAll('line')
.each(function(d, i) {
console.log(d.source.index);
});
这篇关于.each()与一个过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!