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

时间:2019-07-17 20:07:02

标签: 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); })

但是此脚本不会产生任何结果:

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)})


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

提前谢谢!

1 个答案:

答案 0 :(得分:3)

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

  

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

也是

  

选择是不变的。所有影响哪个的选择方法   选择元素(或它们的顺序)返回一个新的选择,而不是   而不是修改当前选择。但是,请注意,元素是   必然是可变的,因为选择会推动变革   文献! (link


按原样,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()
  ...

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)})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>

但是这有点奇怪。