确保您清楚您正在使用以下两种方法中的哪一种:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter
https://github.com/mbostock/d3/wiki/Selections#wiki-filter
d3.selectAll 函数接受选择器字符串或 DOM 节点数组。你的情况是哪一个?
https://github.com/mbostock/d3/wiki/Selections#wiki-d3_selectAll
请记住, selection.each() 回调函数中的变量 p 对应于绑定到选择中的元素的数据。
https://github.com/mbostock/d3/wiki/Selections#wiki-each
更新
您的 links 变量似乎是一组常规 JavaScript 对象。这是不正确的,因为该d3.selectAll
函数需要一个 DOM 节点数组(或选择器字符串)。有趣的是,如果您使用常规数组作为参数,它不会抱怨;例如,您仍然可以调用该selection.each
方法:
selection.each(函数)
为当前选择中的每个元素调用指定的函数,传入当前数据 d 和索引 i,以及当前 DOM 元素的 this 上下文。几乎所有其他运算符都在内部使用此运算符,并可用于为每个选定元素调用任意代码。通过在回调函数中使用 d3.select(this),可以使用 each 运算符递归处理选择。
但是,因为选择不是真正选择绑定了数据的 DOM 节点,所以您会看到函数中的第一个参数(通常为 d,在您的情况下为 p)将是未定义的。
第二个参数,索引 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); })
您正在查看的另一个简化示例:
// 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 库中包含的标准力示例为例:http: //d3-example.herokuapp.com/examples/force/force.htm并从控制台运行以下命令:
d3.selectAll('line')
.each(function(d, i) {
console.log(d.source.index);
});