如何在d3js版本4中将节点和链接附加到模拟力?

时间:2018-01-04 19:14:05

标签: d3.js

我尝试移植到d4.v4.js一些使用版本3构建的图形绘图。 我完全不了解如何使用atlas force附加svg节点和链接到模拟。 使用d3.v3的简化版本在fiddle上共享,请注意所有节点都分组在<g>元素中,并且在此示例中简化为圆形的每个节点都插入<g>元素也是。同样,链接分组在<g>元素中。我需要那些来绘制更复杂的网络。

svg.append("g").attr("class", "links");
svg.append("g").attr("class", "nodes");

var force = d3.layout.force()
.gravity(.15)
.distance(100)
.charge(-1200)
.friction(0.8)
.size([width, height]);

// push initial sets of nodes and links
var nodes = force.nodes(), links = force.links();
Array.prototype.push.apply(nodes, data.nodes);
Array.prototype.push.apply(links, data.edges);

我在fiddle as well共享中使用d3.v4绘制网络的参考,它确实有效,但是对于我更复杂的图形,每个节点都不在<g>元素中(如我所知)

这个last fiddle显示了简化图的d3.v4版本,可以看到,节点保留在左上角,只有缩放工作。

var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.call(zoom);

var simulation = d3.forceSimulation()
.force("link", d3.forceLink()
       .id(function(d) { return d.id; })
       .distance(function(d) { return (1-d.value*d.value*d.value)*20; }))
.force("charge", d3.forceManyBody().strength(-200))
.force("center", d3.forceCenter(width / 2, height / 2));

var pane = svg.append("g");

var link = pane.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return d.value*d.value*d.value*10; });

var node = pane.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", function(d) { return d.value*5   })
.style("fill", function(d) { return color(d.group); })

我的问题是我应该如何附加节点(<g>)并链接到&#34;模拟&#34;?我的剧本有什么问题? 非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

让我们来看看d3v4实现的最后一个小提琴。 2个更改,它将起作用。

1)移动元素的ticked函数。由于节点现在是svg组,因此您无法使用cxcy属性(适用于圈子)。你需要像这样使用transform translate

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

2)node变量仅包含更新选择,因为您调用输入选择 nodeEnter。由于所有元素都在输入选择中(刚刚创建),因此您不会移动任何内容。 所以你只需要合并这两个选项:

nodeEnter.append("circle")
  .attr("r", function(d) { return d.value*10 })
node.exit().remove();
node = nodeEnter.merge(node);

您可以在Mike Bostock documentation中了解更多详情。同时检查this和其他类似的bl.ocks。

要正确定位ticked中的链接,您还应该以相同的方式合并输入和更新链接选择。

作为旁注,您不需要像在getGraph函数中那样链接链接中的源对象和目标对象,因为这已经由d3 simulation完成。因此,您可以将json对象用作数据。

这是working fiddle。 希望更清楚如何将d3 v3力导向布局升级到d3 v4力模拟:D