Updating links on a force directed graph from dynamic json data Updating links on a force directed graph from dynamic json data json json

Updating links on a force directed graph from dynamic json data


Well I could find the solution browsing through, posting it here for anyone needing help on this topic. The idea is to create an object of the graph and playing around with the nodes and links arrays.The JS code goes as:

var graph;function myGraph(el) {// Add and remove elements on the graph objectthis.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 elementvar 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(" + d.x + "," + d.y         + ")"; });        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 goupdate();}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');}


I took Rahuls great example, made some changes, and posted a bl.ock complete with animation over time if anyone is interested in a fully functioning example. Adding/removing links/nodes really should be easier than this, but still pretty cool.

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

enter image description here


In addition to calling drawGraph() in the ready function, you can also embed the posted code inside an inline <script></script>block.

This is how most of the tutorials on the d3 site handle it.