Let's say I have svg with circles in there.
let svg = d3.select("body").append("svg").attr("width", 600).attr("height", 100)
let dataset = [5, 10, 20]
let circles = svg.selectAll("circle").data(dataset).enter().append("circle")
and I want to make circle's location dynamic by the index of the dataset and radius with dataset's values
circles.attr("cx", (d,i)=>(i*50)+25)
       .attr("cy", 50)
       .attr("r", (d)=>d)
I technically could pass in i for the "r"'s function. But I do not have to. That makes this optional parameter. I get that.
但我想了解这在 javascript 语言中是如何实现的。所以我通过查看d3.js的实现来深入挖掘,试图了解它们如何允许这样一个可选参数。但我很难理解是什么传递了数据集的当前项目以及它的索引。
归根结底,您的问题是关于一个众所周知的 Javascript 功能:在 Javascript 中,您可以传递比参数少的参数,或者比参数多的参数。在前者中,没有参数的参数是undefined,在后者中,额外的参数被简单地忽略。
如果您查看共享的源代码,您会看到selection.attr()内部使用了selection.each,这就是:
export default function(callback) {
  for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
    for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
      if (node = group[i]) callback.call(node, node.__data__, i, group);
    }
  }
  return this;
}
最重要的部分是这个:
callback.call(node, node.__data__, i, group);
如您所见,回调被传递(通过call)nodeas this,然后是 3 个参数:
node.__data__: 这是数据i: 这是索引group: 这是当前组。因此,即使attr方法中的函数没有第二个参数,它仍然会传递第二个(和第三个)参数,无论如何。
这是一个传递比参数更多的参数的示例:
export default function(callback) {
  for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
    for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
      if (node = group[i]) callback.call(node, node.__data__, i, group);
    }
  }
  return this;
}
这是一个传递比参数少的参数:
callback.call(node, node.__data__, i, group);
| 归档时间: | 
 | 
| 查看次数: | 69 次 | 
| 最近记录: |