.each()带过滤器

Eli*_*jah 3 typeerror d3.js

我正在查看另一个stackoverflow问题,我尝试了以下内容:

d3.selectAll(links.filter(function(db) {
  return db.source.id == 'foo'
})).each(function(p) {
      console.log (p.source.id)
    })
Run Code Online (Sandbox Code Playgroud)

并发现它返回了一个

TypeError:无法读取未定义的属性"source"

即使过滤后的选择返回为具有.source.id值的对象的正确数组(此示例使用D3的强制定向网络中的标准链接符号).

我只是好奇为什么这不起作用.

nau*_*tat 7

确保您清楚使用以下两种方法中的哪一种:

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


UPDATE

您的links变量似乎是常规JavaScript对象的数组.这是不正确的,因为该d3.selectAll函数需要一个DOM节点数组(或选择器字符串).有趣的是,如果你使用常规数组作为参数,它不会抱怨; 例如,您仍然可以调用该selection.each方法:

selection.each(功能)

为当前选择中的每个元素调用指定的函数,使用当前DOM元素的this上下文传入当前数据d和索引i.几乎所有其他运算符都在内部使用此运算符,并且可以使用该运算符为每个选定元素调用任意代码.通过在回调函数中使用d3.select(this),可以使用每个运算符递归地处理选择.

但是,因为选择不是实际选择的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]);
    });
Run Code Online (Sandbox Code Playgroud)

哪些日志到控制台:

undefined 0 "a"
undefined 1 "b"
undefined 2 "c"
Run Code Online (Sandbox Code Playgroud)

因此,相反,如果您尝试检查强制定向布局中的链接,则可以选择代表这些链接的DOM节点.采用D3库中包含的标准力示例:http://d3-example.herokuapp.com/examples/force/force.htm并从控制台运行以下命令:

d3.selectAll('line')
    .each(function(d, i) {
      console.log(d.source.index);
    });
Run Code Online (Sandbox Code Playgroud)