这让我觉得非常愚蠢,但今天我正在搞乱D3js(v4),我看到一些关于方法链的行为的意外行为。
For this example一切都按预期工作 - 太棒了!
以下是有效代码示例:
function render (data) {
const circles = svg.selectAll('circle').data(data);
circles.enter().append('circle').attr("r", circleRadius)
.attr("class", "vote")
.attr("cx", function (d) { return d.x})
.attr("cy", function (d) { return d.y});
circles.exit().remove();
}
However, in this example,我结束了circle
链,开始了新的一切,一切都破了。
以下是有问题的代码示例:
function render (data) {
const circles = svg.selectAll('circle').data(data);
circles.enter().append('circle').attr("r", circleRadius);
circles
.attr("class", "vote")
.attr("cx", function (d) { return d.x})
.attr("cy", function (d) { return d.y});
circles.exit().remove();
}
我确信这是一个我想念的简单的东西,但我真的觉得我不理解这会让我质疑我对JavaScript的一些基本知识。
更重要的是,我更加困惑,因为我正在关注youtube上的示例教程。以下是这些人工作代码的屏幕截图,它通过打破链条做同样的事情,但他的代码有效:可以在this youtube video.
中看到我在这里错过了什么?
答案 0 :(得分:1)
你不应该感到愚蠢 - 我认为每个使用d3的人都会在某些时候这样做(我反复)。
正在发生的事情是enter()
返回添加数据时所做的选择。 enter()
之后链接的所有内容都会在使用enter()
选区创建的附加圈子上调用。这就是你的第一个例子有效的原因。
但是当您断开链接时,您现在正在原始选择上调用attire()
,这将无效。这相当于这样做:
const circles = svg.selectAll('circle').data(data)
.attr("cx", function (d) { return ( xScale(d.x) )})
.attr("cy", function (d) { return d.y});
要分开它们,您需要进行新的选择:
d3.selectAll('circle')
.attr("cx", function (d) { return ( xScale(d.x) )})
.attr("cy", function (d) { return d.y});
这是分离需要更新的内容的好方法。
P.S。我认为youtube视频的工作原因是因为他使用旧版本的D3。在新版本中,选择是不可变的。请参阅此处的第一部分:https://github.com/d3/d3-selection/releases/tag/v1.0.0