假设我想使用d3动态更新页面上的圆圈位置和数量。我可以使用.data(),. enter(),. exit()模式来完成此操作。这是一个有效的例子。 http://jsfiddle.net/csaid/MFBye/6/
function updatePositions(data) {
var circles = svg.selectAll("circle").data(data);
circles.enter().append("circle");
circles.exit().remove();
circles.attr("r", 6)
.attr("cx", 50)
.attr("cy", function (d) {
return 20 * d
});
}
但是,当我尝试使用外部SVG而不是圆圈执行相同操作时,第一次更新后的许多新数据点都不会显示在页面上。例: http://jsfiddle.net/csaid/bmdQz/8/
function updatePositions(data) {
var gs = svg.selectAll("g")
.data(data);
gs.enter().append("g");
gs.exit().remove();
gs.attr("transform", function (d, i) {
return "translate(50," + d * 20 + ")";
})
.each(function (d, i) {
var car = this.appendChild(importedNode.cloneNode(true));
d3.select(car).select("path")
});
}
我怀疑这与用于附加外部SVG对象的.each()有关,但我对如何解决这个问题感到茫然。此外,“cx”和“cy”属性是特定于圆圈的,因此我无法想象它们如何用于外部SVG。
提前致谢!
答案 0 :(得分:0)
您的代码存在两个问题。第一个问题以及您没有看到所有数据点的原因是您的外部SVG包含您正在选择的g
个元素。这意味着,在您首次添加元素之后,任何后续.selectAll("g")
选项都将包含来自这些外部SVG的元素。这反过来意味着您传递给.data()
的数据与那些数据匹配,因此您的选择不包含您的期望。通过向您明确添加的g
元素添加一个类并相应地进行选择,可以轻松解决此问题。
第二个问题是您正在执行将外部SVG作为更新选择的一部分附加的代码。这意味着这些元素会被多次添加 - 不是你会注意到的(因为它们重叠),但也不是可取的。通过移动调用以将节点克隆到.enter()
选择,可以轻松解决此问题。
完成jsfiddle here。至于您关于cx
和cy
的问题,您并不真正需要它们。您可以使用transform
属性设置您追加的任何元素的位置,就像您在代码中已经做的那样。