d3.js - v3 和 v4 - 输入和更新差异 [英] d3.js - v3 and v4 - Enter and Update differences
问题描述
我正在尝试获取 x
和 y
的值以使用 d3.js v4 制作圆圈.使用以下代码,我设法创建了类似圆圈行为的图表,但是当我尝试在 v4 中运行相同的代码时,它不再起作用.我知道 v4 的更新存在一些差异,但我没有找到任何有关它的信息.所以我想知道是否有人可以帮助我在 d3.js v4 中运行这段代码.
I'm trying to get the values for x
and y
to make a circles using d3.js v4. With the following code I manage to create the chart like behavior of the circles, but when I try to run the same code in v4 it doesn't work anymore. I know that there are some differences in the update to v4 but I didn't find any information about it. So i was wondering if someone can help me to run this code in d3.js v4.
这是使用 v3 的代码(使用 v4 会中断):
Here is the code using v3 (it will break using 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 d.x;
})
.attr('cy', function(d) {
return d.y;
});
//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>
推荐答案
这是预期的行为,我之前在 这个答案(虽然不是重复的).
This is the expected behaviour, and I've explained this before in this answer (not a duplicate, though).
发生的事情是,D3 创建者 Mike Bostock 在 D3 v2 中引入了一个魔术行为,他在 D3 v3.x 中保留了该行为,但决定在 D3 v4.x 中放弃.要了解更多相关信息,请查看此处:什么使软件优秀? 他是这样说的:
What happened is that Mike Bostock, D3 creator, introduced a magic behaviour in D3 v2, which he kept in D3 v3.x, but decided to abandon in D3 v4.x. To read more about that, have a look here: What Makes Software Good? This is what he says:
D3 2.0 引入了一项更改:添加到输入选择现在会将输入元素复制到更新选择中 [...] D3 4.0 删除了 enter.append 的魔力.(实际上,D3 4.0 完全消除了输入和普通选择之间的区别:现在只有一类选择.)
D3 2.0 introduced a change: appending to the enter selection would now copy entering elements into the update selection [...] D3 4.0 removes the magic of enter.append. (In fact, D3 4.0 removes the distinction between enter and normal selections entirely: there is now only one class of selection.)
让我们看看吧.
这是您使用 D3 v3 的代码:
Here is your code with 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 d.x;
})
.attr('cy', function(d) {
return d.y;
});
//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.它会打破":
Now the same code, with D3 v4. It will "break":
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 d.x;
})
.attr('cy', function(d) {
return d.y;
});
//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>
通过中断"我的意思是圆圈将被附加,但它们不会在输入"选择中接收 x
和 y
属性,并且它们将默认到零.这就是为什么您会在左上角看到所有圆圈的原因.
By "break" I mean the circles will be appended, but they will not receive the x
and y
properties in the "enter" selection, and they will default to zero. That's why you see all circles at the top left corner.
解决方案:合并选择:
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;
});
根据API,合并()
...
... 通常用于在数据连接后合并输入和更新选择.分别修改进入和更新元素后,可以将两个选择合并,对两者进行操作,无需重复代码.
... is commonly used to merge the enter and update selections after a data-join. After modifying the entering and updating elements separately, you can merge the two selections and perform operations on both without duplicate code.
这是带有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 d.x;
})
.attr('cy', function(d) {
return d.y;
});
//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>
这篇关于d3.js - v3 和 v4 - 输入和更新差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!