繁体   English   中英

如何在D3强制布局中添加复合节点?

[英]How to add compound node in a D3 force layout?

我正在将节点添加到力布局图中,如下所示:

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>

创建“复合”元素就像将一个或多个子代添加到另一元素一样简单。 在您的示例中,您想将数据绑定到选择的<a>元素,并为每个<a>赋予一个单独的<circle>子元素。

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

然后,您要向输入选择中的每个节点附加一个<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>元素 ,这就是我上面所指的。 这与HTML不同! 通常,您仅将SVG元素与SVG一起使用,将HTML与HTML一起使用。

感谢@mbostock建议我阐明变量命名。

回复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(均为容器),如果您以后要添加标签,则很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM