9

我正在将节点添加到这样的力布局图中:

var node = vis.selectAll("circle.node")
    .data(nodes)
    .enter()
    .append("circle")
    .attr("class", "node")
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .attr("r", 5)
    .style("fill", function(d) { return fill(d.group); })
    .call(force.drag);

有没有办法将复合 SVG 元素添加为节点?即我想为每个圈子添加一个超链接,所以我需要这样的东西:

<a href="whatever.com"><circle ...></circle></a>

4

2 回答 2

33

创建“复合”元素就像将一个或多个子元素附加到另一个元素一样简单。在您的示例中,您希望将数据绑定到一系列<a>元素,并为每个元素提供<a>一个<circle>子元素。

首先,您需要选择"a.node"而不是"circle.node". 这是因为您的超链接将成为父元素。如果没有明显的父元素,而您只想为每个数据添加多个元素,请使用<g>SVG 的 group 元素。

然后,您希望将一个<a>元素附加到输入选择中的每个节点。这将创建您的超链接。设置每个超链接的属性后,您想给它一个<circle>孩子。简单:只需调用.append("circle").

var node = vis.selectAll("a.node")
    .data(nodes);

// The entering selection: create the new <a> elements here.
// These elements are automatically part of the update selection in "node".
var nodeEnter = node.enter().append("a")
    .attr("class", "node")
    .attr("xlink:href", "http://whatever.com")
    .call(force.drag);

// Appends a new <circle> element to each element in nodeEnter.
nodeEnter.append("circle")
    .attr("r", 5)
    .style("fill", function(d) { return fill(d.group); })

node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

请记住,D3 主要对节点的选择进行操作。所以调用.append()进入选择意味着选择中的每个节点都有一个新的孩子。强大的东西!

还有一件事:SVG 有自己的<a>element,这就是我上面提到的。这与 HTML 不同!通常,您仅将 SVG 元素与 SVG 一起使用,而将 HTML 与 HTML 一起使用。

感谢@mbostock 建议我澄清变量命名。

于 2012-02-11T11:34:22.590 回答
11

回复 Jason Davies(因为 stackoverflow 限制了回复评论的长度……):很好的答案。不过要小心方法链;通常您希望node引用外部锚元素而不是内部圆元素。所以我推荐一个小的变化:

var node = vis.selectAll("a.node")
    .data(nodes)
  .enter().append("a")
    .attr("class", "node")
    .attr("xlink:href", "http://whatever.com")
    .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
    .call(force.drag);

node.append("circle")
    .attr("r", 5)
    .style("fill", function(d) { return fill(d.group); });

我还用包含锚元素的变换替换了圆的 cx 和 cy 属性;任何一个都可以。您可以将 svg:a 元素视为 svg:g (两者都是容器),如果您想稍后添加标签,这很好。

于 2012-02-11T16:28:12.890 回答