1

假设我想使用 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。

提前致谢!

4

1 回答 1

0

您的代码有两个问题。第一个问题,也是您没有看到所有数据点的原因,是您的外部 SVG 包含g您正在选择的元素。这意味着在您第一次添加元素之后,任何后续.selectAll("g")选择都将包含来自这些外部 SVG 的元素。这反过来意味着您传递给的数据.data()与这些数据相匹配,因此您的选择不包含您期望的内容。g通过向您显式添加的元素添加一个类并相应地选择,可以轻松解决此问题。

第二个问题是您正在执行将外部 SVG 作为更新选择的一部分附加的代码。这意味着这些元素会被多次添加——这不是你会注意到的(因为它们重叠),但也不是可取的。这很容易通过将调用克隆到.enter()选择中来解决。

在这里完成 jsfiddle 。至于你关于cxand的问题cy,你真的不需要它们。您可以使用该属性设置您附加的任何元素的位置transform,就像您在代码中所做的那样。

于 2013-09-07T22:32:19.993 回答