动态清除并更新d3.js强制定向布局更改

时间:2014-05-08 22:55:03

标签: javascript d3.js

the Mobile Patent Suit example by Mike Bostock为例,我可以使用自己的数据重新创建,但我想更进一步,并在下拉更改中动态更新节点关系。代码几乎每次都有效,但偶尔我会得到一个没有关系的单个节点(见下图),即使数据可用。我认为在清除选择更改时更新节点然后更新节点时我可能做错了什么,但对我来说这很奇怪,它在某些时候是有效的。非常感谢任何帮助。

http://jsfiddle.net/calanoue/r6BRr/

var selectedCode = '0';

function updateNodes() {
   // Update the links and the nodes any time the data changes
   svg.selectAll('g').remove();

   links = allData[0][selectedCode];

   // Compute the distinct nodes from the links.
   links.forEach(function (link) {
    link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
    link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
   });

   force = d3.layout.force()
        .nodes(d3.values(nodes))
        .links(links)
        .size([width, height])
        .linkDistance(80)
        .charge(-400)
        .on("tick", tick)
        .start();

   path = svg.append("g").selectAll("path")
        .data(force.links())
        .enter().append("path")
        .attr("class", "link relationship")
        .attr("marker-end", "url(#relationship)");

   circle = svg.append("g").selectAll("circle")
        .data(force.nodes())
        .enter().append("circle")
        .attr('class', "generic")
        .attr("r", 8)
        .call(force.drag);
}

function tick() {
   // Use elliptical arc path segments to doubly-encode directionality.
   path.attr("d", linkArc);
   circle.attr("transform", transform);
}

function linkArc(d) {
   var dx = d.target.x - d.source.x,
        dy = d.target.y - d.source.y,
        dr = Math.sqrt(dx * dx + dy * dy);
   return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}

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

function clearNodes() {
   nodes = {};
   links = [];
   force.start();
   d3.timer(force.resume);
}

function codeChange() {
   selectedCode = this.value;
   clearNodes();
   updateNodes();
}

缺少节点关系图像:

missing node relationships

1 个答案:

答案 0 :(得分:3)

您遇到的问题是原始数据allData正在通过每次数据更改迭代时链接和节点的计算进行更改。毕竟,您设置了links = cloneData[0][selectedCode];。您需要在每次数据更改之前克隆allData

function codeChange() {
    selectedCode = this.value;
    cloneData = clone(allData); // added
    clearNodes();
    updateNodes();
}

这是一个FIDDLE,其中包含所有更改以使其正常工作。我从这个SO question借用了克隆函数。

注意:我还删除了您的一个下拉选项,因为allData中只有3组数据。根据上述情况,这不是导致问题的原因,但每当您选择不存在的集合时,它就会抛出错误。