从dynamicjson数据更新强制有向图上的链接

我是D3新手,正在研究JSON数据是dynamic的强制有向图。 我可以在接收到新数据的时候改变力图,但是这种情况会发生。 创build我的强制图的代码是:

<div class="graph"></div> <script> var w = 660, h = 700, r = 10; var vis = d3.select(".graph") .append("svg:svg") .attr("width", w) .attr("height", h) .attr("pointer-events", "all") .append('svg:g') .call(d3.behavior.zoom().on("zoom", redraw)) .append('svg:g'); vis.append('svg:rect') .attr('width', w) .attr('height', h) .attr('fill', 'rgba(1,1,1,0)'); function redraw() { console.log("here", d3.event.translate, d3.event.scale); vis.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); }; var force = d3.layout.force() .gravity(.05) .charge(-200) .linkDistance( 260 ) .size([w, h]); var svg = d3.select(".text") .append("svg") .attr("width", w) .attr("height", h); d3.json(graph, function(json) { var nodeList = json.nodes; var link = vis.selectAll("line") .data(json.links) .enter() .append("line") .attr("stroke-opacity", function(d) { if(d.label == 'is a') { return '0.8'; } else { return '0.2'; }; }) .attr("stroke-width", function(d) { if(d.value !== null) { return d.value; } else { return 2; }; }) .style("stroke", function(d) { if(d.color !== null) { return d.color; }; }) .on("mouseover", function() { d3.select(this) .style("stroke", "#999999") .attr("stroke-opacity", "1.0"); }) .on("mouseout", function() { d3.select(this) .style("stroke", function(d) { if(d.color !== null) { return d.color; }; }) .attr("stroke-opacity", function(d) { if(d.label == 'is a') { return '0.8'; } else { return '0.2'; }; }) }); link.append("title") .text(function(d) { return d.label } ); var node = vis.selectAll("g.node") .data(json.nodes) .enter() .append("svg:g") .attr("class","node") .call(force.drag); node.append("svg:circle") .attr("r", function(d) { if (d.size > 0) { return 10+(d.size*2); } else { return 10; } }) .attr("id", function(d) { return "Node;"+d.id; } ) .style("fill", function(d) { if(d.style == 'filled') { return d.color; }; }) .style("stroke", function(d) { if(d.style !== 'filled') { return d.color; }; }) .style("stroke-width", "2") .on("mouseover", function() { d3.select(this).style("fill", "#999"); fade(.1); }) .on("mouseout", function(d) { if (d.style == 'filled') { d3.select(this).style("fill",d.color);fade(1); } else { d3.select(this).style("stroke",d.color); d3.select(this).style("fill","black"); } fade(1); }); node.append("title") .text(function(d) { return d.Location; } ); force.nodes(json.nodes) .links(json.links) .on("tick", tick) .alpha(1) .start(); function tick() { node.attr("cx", function(d) { return dx; }) .attr("cy", function(d) { return dy; }) .attr("transform", function(d) { return "translate(" + dx + "," + dy + ")"; }); link.attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); } }); </script> 

当通过再次调用整个函数来接收新的jsonstring时,我可以创build一个新的graphics。 这创build了一个新的graphics来取代旧的。 在收到值时,我无法用新的一组值更新旧图。 我图中的节点不变,只是它们之间的关系发生变化。

我偶然发现了一个例子( http://bl.ocks.org/1095795 ),其中一个新节点被删除并重新创build,但是实现有点不同。

任何指针或帮助将非常感激。

那么我可以find解决scheme浏览,发布在这里为任何人需要帮助这个话题。 这个想法是创build一个图的对象,并与节点和链接arrays玩耍。 JS代码如下:

 var graph; function myGraph(el) { // Add and remove elements on the graph object this.addNode = function (id) { nodes.push({"id":id}); update(); }; this.removeNode = function (id) { var i = 0; var n = findNode(id); while (i < links.length) { if ((links[i]['source'] == n)||(links[i]['target'] == n)) { links.splice(i,1); } else i++; } nodes.splice(findNodeIndex(id),1); update(); }; this.removeLink = function (source,target){ for(var i=0;i<links.length;i++) { if(links[i].source.id == source && links[i].target.id == target) { links.splice(i,1); break; } } update(); }; this.removeallLinks = function(){ links.splice(0,links.length); update(); }; this.removeAllNodes = function(){ nodes.splice(0,links.length); update(); }; this.addLink = function (source, target, value) { links.push({"source":findNode(source),"target":findNode(target),"value":value}); update(); }; var findNode = function(id) { for (var i in nodes) { if (nodes[i]["id"] === id) return nodes[i];}; }; var findNodeIndex = function(id) { for (var i=0;i<nodes.length;i++) { if (nodes[i].id==id){ return i; } }; }; // set up the D3 visualisation in the specified element var w = 500, h = 500; var vis = d3.select("#svgdiv") .append("svg:svg") .attr("width", w) .attr("height", h) .attr("id","svg") .attr("pointer-events", "all") .attr("viewBox","0 0 "+w+" "+h) .attr("perserveAspectRatio","xMinYMid") .append('svg:g'); var force = d3.layout.force(); var nodes = force.nodes(), links = force.links(); var update = function () { var link = vis.selectAll("line") .data(links, function(d) { return d.source.id + "-" + d.target.id; }); link.enter().append("line") .attr("id",function(d){return d.source.id + "-" + d.target.id;}) .attr("class","link"); link.append("title") .text(function(d){ return d.value; }); link.exit().remove(); var node = vis.selectAll("g.node") .data(nodes, function(d) { return d.id;}); var nodeEnter = node.enter().append("g") .attr("class", "node") .call(force.drag); nodeEnter.append("svg:circle") .attr("r", 16) .attr("id",function(d) { return "Node;"+d.id;}) .attr("class","nodeStrokeClass"); nodeEnter.append("svg:text") .attr("class","textClass") .text( function(d){return d.id;}) ; node.exit().remove(); force.on("tick", function() { node.attr("transform", function(d) { return "translate(" + dx + "," + dy + ")"; }); link.attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); }); // Restart the force layout. force .gravity(.05) .distance(50) .linkDistance( 50 ) .size([w, h]) .start(); }; // Make it all go update(); } function drawGraph() { graph = new myGraph("#svgdiv"); graph.addNode('A'); graph.addNode('B'); graph.addNode('C'); graph.addLink('A','B','10'); graph.addLink('A','C','8'); graph.addLink('B','C','15'); } 

我拿Rahuls做了一个很好的例子,做了一些改变,并且随着时间的推移,发布了一个带animation的bl.ock,如果有人对一个function完整的例子感兴趣的话。 添加/删除链接/节点应该比这更容易,但仍然非常酷。

http://bl.ocks.org/ericcoopey/6c602d7cb14b25c179a4

在这里输入图像说明

除了在ready函数中调用drawGraph() ,还可以将发布的代码embedded到内联<script></script>块中。

这是d3网站上的大多数教程处理它的方式。