Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructing Force Directed Graphs From Only Link Data

I am a bit new to d3.js, but I'm having quite a bit of fun with it. So far, I have implemented a force-directed graph that is very close to many of the examples and tutorials out there.

Direct Concern

Like many of the examples, I have a JSON structure like this:

{"nodes": ["node1", "node2",  ... ],
 "links": [{source: 0, target: 1, "field1": 5, ...}, ... ]}

However, I think that it would be easier to construct my data sources like this:

{"links": [
    {source: "node1", target: "node2", "field1": 5, ...},
    {source: "node2", target: "node4", "field1": 1, ...},
    {source: "node3", target: "node4", "field1": 8, ...}
]}

Instead of explicitly defining the nodes in my graph, they are implicitly defined in the link structures.

The Reason

I wanted to list the eventual goal of the project in case someone had some specific example code or idiomatic way of doing this of which I am unaware.

The goal for the project would eventually be a graph that is updating in real-time. The back-end is being developed and is subject to some change and revision.

At the moment, I'm imagining pulling down an update JSON feed every X seconds and updating the structure of that graph with the new information. The pulled feed would only contain the updated structures of the graph, so the script would need to maintain the all of the already pulled nodes and links and add any new ones, if necessary.

Thanks!

I apologize if this has been asked before. I did some searching and didn't find anything. Feel free to insult and berate me if I missed it.

like image 399
user1524220 Avatar asked Jul 13 '12 20:07

user1524220


2 Answers

I've had to do this a few times. The simplest approach I've found has been to simply compute the set of nodes base don the list of links and then turn it into an array for the force graph to use:

var links = [ .... ];
var nodeMap = {};
links.forEach(function(d, i) { 
    nodeMap[d.source] = true;
    nodeMap[d.target] = true;
});

var nodes = [];
for (key in nodeMap)
    nodes.push(key);

d3.layout.force()
         .nodes(nodes)
         .links(links);
like image 133
fozziethebeat Avatar answered Nov 10 '22 05:11

fozziethebeat


I've done just this in the example "D3 Based Force Directed Radial Graph". I do this because I want to understand how the data is used, internally, independent of structures like JSON and CSV, which can always be layered in, later.

Anyhow, I hope the example helps you.

My Best,

Frank

like image 4
Information Technology Avatar answered Nov 10 '22 04:11

Information Technology