为什么在输入时分离 d3 方法链会改变结果?

jay*_*o03 1 javascript d3.js

我正在学习 D3.js 并对方法链感到好奇

此脚本有效:

var data = [32, 57, 112, 250]

var svg = d3.select("svg")

svg.selectAll("circle")
    .data(data)
    .enter()
    .append("circle")
    .attr("cy", 60)
    .attr("cx", function(d, i) { return i * 100 + 30 })
    .attr("r", function(d) { return Math.sqrt(d); })
Run Code Online (Sandbox Code Playgroud)

但是这个脚本没有任何结果:

var data = [32, 57, 112, 250]

var circles = d3.select("svg").selectAll("circle");
circles.data(data);

var circlesEnter = circles
    .enter()
    .append("circle")
    .attr("cy", 60)
    .attr("cx", function(d, i) { return i * 100 + 30})
    .attr("r", function (d) { return Math.sqrt(d)})
Run Code Online (Sandbox Code Playgroud)


我没有看到对这两种不同方法的不同影响。谁能告诉我这两者的区别?

提前致谢!

And*_*eid 5

问题是selection.data()不修改现有选择,它返回一个新选择:

[selection.data] 将指定的数据数组与所选元素绑定,返回一个代表更新选择的新选择:成功绑定到数据的元素。还定义了返回选择的进入和退出选择,可用于添加或删除元素以对应新数据。(来自文档

还,

选择是不可变的。所有影响选择哪些元素(或它们的顺序)的选择方法都会返回一个新的选择,而不是修改当前的选择。但是,请注意元素必须是可变的,因为选择会驱动文档的转换!(链接


原样,circles包含一个空的圆选择(大小:0),没有关联的数据数组。因为它是不可变的,所以调用circles.data(data)不会改变那个选择,并且circles.enter()会保持为空。同时,由创建的选择circles.data()会丢失,因为它没有分配给变量。

我们可以像在您的第一个代码块中那样将方法链接在一起,因为在使用、 或时.data(),链中返回的选择是一个新选择。方法链中的每个方法都使用上一行返回的选择,这是正确的。.enter()selectAll()

为了.data()脱离链条,我们需要使用 selection.data() 创建一个新的中间选择来访问输入选择:

var circles = d3.select("svg").selectAll("circle");   

var circlesData = circles.data(data);

var circlesEnter = circlesData
  .enter()
  ...
Run Code Online (Sandbox Code Playgroud)

var circles = d3.select("svg").selectAll("circle");   

var circlesData = circles.data(data);

var circlesEnter = circlesData
  .enter()
  ...
Run Code Online (Sandbox Code Playgroud)
var data = [32, 57, 112, 250]

var circles = d3.select("svg").selectAll("circle");

var circlesData = circles.data(data);

var circlesEnter = circlesData
    .enter()
    .append("circle")
    .attr("cy", 60)
    .attr("cx", function(d, i) { return i * 100 + 30})
    .attr("r", function (d) { return Math.sqrt(d)})
Run Code Online (Sandbox Code Playgroud)

但这将是一个有点奇怪的方法。