繁体   English   中英

d3.js - v3 和 v4 - 输入和更新差异

[英]d3.js - v3 and v4 - Enter and Update differences

我正在尝试获取xy的值以使用 d3.js v4 制作圆圈。 使用以下代码,我设法创建了类似圆圈行为的图表,但是当我尝试在 v4 中运行相同的代码时,它不再起作用。 我知道 v4 的更新存在一些差异,但我没有找到任何有关它的信息。 所以我想知道是否有人可以帮助我在 d3.js v4 中运行这段代码。

这是使用 v3 的代码(使用 v4 会中断):

 var svg = d3.select('body').append('svg') .attr('width', 250) .attr('height', 250); //render the data function render(data) { //Bind var circles = svg.selectAll('circle').data(data); //Enter circles.enter().append('circle') .attr('r', 10); //Update circles .attr('cx', function(d) { return dx; }) .attr('cy', function(d) { return dy; }); //Exit circles.exit().remove(); } var myObjects = [{ x: 100, y: 100 }, { x: 130, y: 120 }, { x: 80, y: 180 }, { x: 180, y: 80 }, { x: 180, y: 40 }]; render(myObjects);
 <script src='https://d3js.org/d3.v3.min.js'></script>

这是预期的行为,我之前在这个答案对此进行了解释(虽然不是重复的)。

发生的事情是,D3 创建者 Mike Bostock 在 D3 v2 中引入了一个魔法行为,他保留在 D3 v3.x 中,但决定在 D3 v4.x 中放弃。 要了解更多相关信息,请查看此处: 什么让软件变得优秀? 他是这样说的:

D3 2.0 引入了一个变化:附加到输入选择现在会将输入元素复制到更新选择中 [...] D3 4.0 删除了 enter.append 的魔力。 (实际上,D3 4.0 完全消除了输入和普通选择之间的区别:现在只有一类选择。)

让我们来看看它。

这是您使用 D3 v3 的代码:

 var svg = d3.select('body').append('svg') .attr('width', 250) .attr('height', 250); //render the data function render(data) { //Bind var circles = svg.selectAll('circle').data(data); //Enter circles.enter().append('circle') .attr('r', 10); //Update circles .attr('cx', function(d) { return dx; }) .attr('cy', function(d) { return dy; }); //Exit circles.exit().remove(); } var myObjects = [{ x: 100, y: 100 }, { x: 130, y: 120 }, { x: 80, y: 180 }, { x: 180, y: 80 }, { x: 180, y: 40 }]; render(myObjects);
 <script src='https://d3js.org/d3.v3.min.js'></script>

现在使用相同的代码,使用 D3 v4。 它会“打破”:

 var svg = d3.select('body').append('svg') .attr('width', 250) .attr('height', 250); //render the data function render(data) { //Bind var circles = svg.selectAll('circle').data(data); //Enter circles.enter().append('circle') .attr('r', 10); //Update circles .attr('cx', function(d) { return dx; }) .attr('cy', function(d) { return dy; }); //Exit circles.exit().remove(); } var myObjects = [{ x: 100, y: 100 }, { x: 130, y: 120 }, { x: 80, y: 180 }, { x: 180, y: 80 }, { x: 180, y: 40 }]; render(myObjects);
 <script src='https://d3js.org/d3.v4.min.js'></script>

“中断”是指圆圈将被附加,但它们不会在“输入”选择中接收xy属性,并且它们将默认为零。 这就是为什么您会在左上角看到所有圆圈的原因。

解决方案:合并选择:

circles.enter().append('circle')
  .attr('r', 10)
  .merge(circles) //from now on, enter + update
  .attr('cx', function(d) {
    return d.x;
  })
  .attr('cy', function(d) {
    return d.y;
  });

根据APImerge() ...

... 通常用于在数据连接后合并输入和更新选择。 分别修改进入和更新元素后,可以合并两个选择并对其进行操作,无需重复代码。

这是带有merge()的代码:

 var svg = d3.select('body').append('svg') .attr('width', 250) .attr('height', 250); //render the data function render(data) { //Bind var circles = svg.selectAll('circle').data(data); //Enter circles.enter().append('circle') .attr('r', 10) .merge(circles) //from now on, enter + update .attr('cx', function(d) { return dx; }) .attr('cy', function(d) { return dy; }); //Exit circles.exit().remove(); } var myObjects = [{ x: 100, y: 100 }, { x: 130, y: 120 }, { x: 80, y: 180 }, { x: 180, y: 80 }, { x: 180, y: 40 }]; render(myObjects);
 <script src='https://d3js.org/d3.v4.min.js'></script>

d3v4 中的更新模式已更改。 文档摘录:

此外, selection.append 不再将进入的节点合并到更新选择中; 使用 selection.merge 在数据连接后组合输入和更新。

你应该这样重写你的代码:

 var svg = d3.select('body').append('svg') .attr('width', 250) .attr('height', 250); //render the data function render(data){ //Bind var circles = svg.selectAll('circle').data(data); //Enter circles.enter().append('circle') .attr('r', 10).merge(circles) // <== !!! .attr('cx', function(d) { return dx; }) .attr('cy', function(d) { return dy; }); //Exit circles.exit().remove(); } var myObjects = [ {x: 100, y: 100}, {x: 130, y: 120}, {x: 80, y: 180}, {x: 180, y: 80}, {x: 180, y: 40} ]; render(myObjects);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM