D3 force layout shall add nodes and links when clicking a node

I have a working D3 example. I use the force and everything works fine. But I have a small issue. Let's say I have 4 Nodes. Just see this picture: http://i.imgur.com/J0P4I0n.png and now when I click on the Node "AKZO NV" then I want to get: http://i.imgur.com/fGXVGMd.png with the old nodes and links.

So at the end I want to have 7 Nodes. And the "AKZO NV" shall be focused. All Nodes still have their links and the "AKZO NV" shall have two. I think you now know what I want.

So I already have this code. Working like a charm but it's not properly adding the new nodes and links. I think there is a small issue with the order of the commands.

Any ideas are welcome:

var alreadyThere = false;
var nodeCircles = {};
var svg, link, node;
var force = d3.layout.force();
var nodes, links;
var width = 700, height = 400;
var boxIDName = "#main-rightinfo";
var JSONFORMERGING;

function createRealGraph(jsonData){
    //console.log(jsonData);
    if (alreadyThere == false){
        JSONFORMERGING=jsonData;
        initializeGraph(jsonData);
    }else{
        update(JSONFORMERGING.concat(jsonData));
    }
    alreadyThere = true;
}
function update(jsonData) {
    console.log(jsonData);
    jsonData.forEach(function(link) {
      link.source = nodeCircles[link.source] || (nodeCircles[link.source] = {name: link.sourceName, ID: link.source, class: link.sourceClass});
      link.target = nodeCircles[link.target] || (nodeCircles[link.target] = {name: link.targetName, ID: link.target, class: link.targetClass});
    });

    link = link.data(links);
    link.enter().insert("line")
      .attr("class", "link");

    node = node.data(nodes);
    node.enter().append("g")
        .attr("class", "node")
      .attr("r", 5)
      .call(force.drag);

    force 
        .nodes(d3.values(nodeCircles))
        .links(jsonData)
        .start();
    nodes = force.nodes();
    links = force.links();
}
function initializeGraph(jsonData){
    jsonData.forEach(function(link) {
      link.source = nodeCircles[link.source] || (nodeCircles[link.source] = {name: link.sourceName, ID: link.source, class: link.sourceClass});
      link.target = nodeCircles[link.target] || (nodeCircles[link.target] = {name: link.targetName, ID: link.target, class: link.targetClass});
    });

    force 
        .nodes(d3.values(nodeCircles))
        .links(jsonData)
        .size([width, height])
        .linkDistance(60)
        .charge(-200)
        .on("tick", tick)
        .start();

    nodes = force.nodes();
    links = force.links();

    svg = d3.select("#main-right")
        .append("svg")
        .attr("width", width)
        .attr("height", height);
    svg
        .append("svg:defs").selectAll("marker")
        .data(["end"]) 
        .enter().append("svg:marker")   
        .attr("id", String)
        .attr("viewBox", "0 -5 10 10")
        .attr("refX", 27)
        .attr("refY", -0.5)
        .attr("markerWidth", 6)
        .attr("markerHeight", 6)
        .attr("orient", "auto")
        .append("svg:path")
        .attr("d", "M0,-5L10,0L0,5")
        .attr('fill', '#00b');

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

    node = svg.selectAll(".node")
        .data(nodes)
        .enter().append("g")
        .attr("class", "node")
        .on("mouseover", mouseover)
        .on("mouseout", mouseout)
        .on("click", function(d) {click(d);})
        .on("dblclick", function(d) {dblclick(d);})
        .call(force.drag);
    node
        .append("image")
        .attr("xlink:href",  function(d) {if (d.class == "Person") {return "pics/node_person.png";} else {return "pics/node_appln.png";} })
        .attr("x", -20)
        .attr("y", -20)
        .attr("width", 40)
        .attr("height", 40);
    node
        .append("text")
        .attr("x", 19)
        .attr("dy", ".25em")
        .text( function(d) {return d.name; });

    function tick() {
      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; });
      node
          .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    }
}

Answers


You just need to test if it's NOT an object. That works like a charm:

jsonData.forEach(function(link) {
        if (typeof(link.source) != "object"){
            link.source = nodeCircles[link.source] || (nodeCircles[link.source] = {name: link.sourceName, ID: link.source, class: link.sourceClass});
        }
        if (typeof(link.target) != "object"){
            link.target = nodeCircles[link.target] || (nodeCircles[link.target] = {name: link.targetName, ID: link.target, class: link.targetClass});
        } 
    });   

Need Your Help

copying pointer characters not working as expected

c eclipse string pointers mingw

In the following code, what am I doing wrong? I run the code in eclipse and using MinGW C compiler. When I run it eclipse stops responding. When I debug the code, it breaks on the line

Self modifying code, copy/jump in the heap failed

c assembly gdb objdump self-modifying

First I am sorry about the length of this post, but I wanted to explain the problem clearly.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.