21

我正在使用其中一个强制布局示例 ( http://bl.ocks.org/1153292 ) 在我的网站上显示一个网络。

我允许用户在任何给定时间选择要查看的链接类型。我注意到,当我选择查看链接类型 A,然后添加链接类型 B,然后删除链接类型 A 时,类型 B 的剩余链接将显示为 A 颜色。

这是运行以将链接添加到 svg 图的代码。我正在this.links通过添加和删除链接来更改数组。如您所见,我设置了类属性,但它没有更新 - 它仍然是链接 A 的类型。

var path = svg.append("svg:g")
    .selectAll("path")
    .data(this.links)
   .enter()
    .append("svg:path")
    .attr("class", function(d) { return "link " + d.type; })
    .attr("marker-end", function(d) { return "url(#" + d.type + ")"; });

我目前通过更新 tick 函数中的类属性来解决这个问题,但这当然会导致很多不必要的工作。

我读到 enter 操作返回现有元素和新元素的合并选择,因此 attr 操作应该更新现有元素并设置新元素。

我错过了什么?

4

2 回答 2

19

在这篇文章中找到了答案

var circle = svg.selectAll("circle")
    .data(data);

circle.enter().append("circle")
    .attr("r", 2.5);

circle
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; });

circle.exit().remove();

答案是我需要在 selectAll.data 的结果上调用 attr 运算符,而不是在 append 运算符的结果上。

于 2012-10-23T21:26:50.863 回答
4

http://bl.ocks.org/1095795中有一个示例,显示了从强制定向布局中添加和删除节点。必须分别处理链接和节点,然后必须重新启动力布局。

function restart() {
  var link = vis.selectAll("line.link")
      .data(links, function(d) { return d.source.id + "-" + d.target.id; });

  link.enter().insert("svg:line", "g.node")
      .attr("class", "link");

  link.exit().remove();

  var node = vis.selectAll("g.node")
      .data(nodes, function(d) { return d.id;});

  var nodeEnter = node.enter().append("svg:g")
      .attr("class", "node")
      .call(force.drag);

  nodeEnter.append("svg:image")
      .attr("class", "circle")
      .attr("xlink:href", "https://d3nwyuy0nl342s.cloudfront.net/images/icons/public.png")
      .attr("x", "-8px")
      .attr("y", "-8px")
      .attr("width", "16px")
      .attr("height", "16px");

  nodeEnter.append("svg:text")
      .attr("class", "nodetext")
      .attr("dx", 12)
      .attr("dy", ".35em")
      .text(function(d) { return d.id });

  node.exit().remove();

  force.start();
}
于 2012-10-20T21:15:50.087 回答