1

I'm trying to change my visualization script to be more like the Modifying a Force Layout Example. Since I don't have fixed nodes like a, b and c to add I read a json file to fill the nodes and links array.

d3.json("mock.json", function(error, json) {
    if (error)
        throw error;
    nodes = nodes.concat(json.nodes);
    links = links.concat(json.links);
    start();
});

nodes and links have the right size, meaning nodes contains 26 nodes and links 37 links. Now I want to simply visualize them using line and circle elements.

function start() {
    link = link.data(force.links(), function(d) { return d.source.id + "-" + d.target.id; });
    link.enter().append("line").attr("class", "link");
    link.exit().remove();

    node = node.data(force.nodes(), function(d) { return d.id;});
    node.enter().append("circle").attr("class", "node").attr("r", 8);
    node.exit().remove();
    force.start();
}

This is very simular to the example and I don't really understand why this won't work. I provide a demo with the mock. Is there an issue because I use concat() and not push() or is there anything else wrong?

Peter
  • 1,844
  • 2
  • 31
  • 55

1 Answers1

1

Your code:

d3.json("mock.json", function(error, json) {

    if (error)
        throw error;
    nodes = nodes.concat(json.nodes);
    links = links.concat(json.links);
    start();
});

Had to be like this (reason else force.nodes() will be empty array set initially):

d3.json("mock.json", function(error, json) {

    if (error)
        throw error;
    nodes = nodes.concat(json.nodes);
    links = links.concat(json.links);

    force.nodes(nodes); //else force.nodes() will be empty array set initially
    force.links(links)

    start();
});

Next:

Your Code:

link = link.data(force.links(), function(d) { return d.source.id + "-" + d.target.id; });

Corrected code:

link = link.data(force.links(), function(d) { return d.source + "-" + d.target; });

Working code here

Hope this helps!

Cyril Cherian
  • 32,177
  • 7
  • 46
  • 55
  • Jup, works now, but why do I have to use`force.nodes(nodes);`? In the example it works without it, eventhough I wondered how he made the force know about the nodes and links. – Peter Jan 22 '16 at 07:48
  • 1
    yes because `nodes.concat(json.nodes)` will return a new object while `force.nodes()` will be holding to the old object..so when you do force.nodes() in your code it returns an empty array that is the reason why you don't see anything. – Cyril Cherian Jan 22 '16 at 07:56
  • Thank you! :) Now it makes sense to me. `push()` in this case didn't work for me because it would only push the array inside the other array. – Peter Jan 22 '16 at 08:00
  • yes after push you will need to flatten it like this http://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays-in-javascript – Cyril Cherian Jan 22 '16 at 08:02