How does d3.js allow us to use second parameter of function as index of dataset?

Shi*_*chi 3 javascript d3.js

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")
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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实现来深入挖掘,试图了解它们如何允许这样一个可选参数。但我很难理解是什么传递了数据集的当前项目以及它的索引。

Ger*_*ado 5

归根结底,您的问题是关于一个众所周知的 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;
}
Run Code Online (Sandbox Code Playgroud)

最重要的部分是这个:

callback.call(node, node.__data__, i, group);
Run Code Online (Sandbox Code Playgroud)

如您所见,回调被传递(通过callnodeas 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;
}
Run Code Online (Sandbox Code Playgroud)

这是一个传递比参数少的参数:

callback.call(node, node.__data__, i, group);
Run Code Online (Sandbox Code Playgroud)