Friday, May 17, 2024
 Popular · Latest · Hot · Upcoming
96
rated 0 times [  103] [ 7]  / answers: 1 / hits: 62281  / 11 Years ago, wed, april 17, 2013, 12:00:00

I need to be able to draw graphs like the following in JavaScript:



crazy



I know about the Raphael library, but it's only for drawing arbitrary shapes.



I have a few predefined node types (the colored nodes on the image) and text nearby/inside every node. This library doesn't seem to handle that case. How do I do this in JavaScript? If this has been accomplished already by another library, how can I use that library to solve this problem?


More From » charts

 Answers
5

The web is a fast moving world, and so this answer was somewhat out of date. With that in mind, I've refreshed this answer to make it applicable in 2016.




  • D3.js - This would still be my recommendation. It's under active development and has a vibrant community.

  • Vega - An expressive language (less powerful than D3)

  • Cytoscape.js

  • Spring.js

  • cola.js



I would add that I've only used D3.js in this new list, it's power and flexibility are such that I've never needed to find an alternative. Here is an example implementation of a force directed.





var width = 960,
height = 500;

var color = d3.scale.category20();

var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);

var svg = d3.select(body).append(svg)
.attr(width, width)
.attr(height, height);

d3.json(https://gist.githubusercontent.com/mbostock/4062045/raw/4176c7d0c0c5ce15630d16072da0af67bb50eb6a/miserables.json, function(error, graph) {
if (error) throw error;

force
.nodes(graph.nodes)
.links(graph.links)
.start();

var link = svg.selectAll(.link)
.data(graph.links)
.enter().append(line)
.attr(class, link)
.style(stroke-width, function(d) { return Math.sqrt(d.value); });

var node = svg.selectAll(.node)
.data(graph.nodes)
.enter().append(circle)
.attr(class, node)
.attr(r, 5)
.style(fill, function(d) { return color(d.group); })
.call(force.drag);

node.append(title)
.text(function(d) { return d.name; });

force.on(tick, function() {
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(cx, function(d) { return d.x; })
.attr(cy, function(d) { return d.y; });
});
});

.node {
stroke: #fff;
stroke-width: 1.5px;
}

.link {
stroke: #999;
stroke-opacity: .6;
}

<script src=https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js></script>








There are a number of libraries for drawing this sort of output in a browser, you've mentioned Raphael, others include:




  • Sigma.js

  • Processing.js

  • jit.js - Sold to SenchaLabs. The solo developer appeared to stop working on it.

  • D3.js

  • Raphael.js - Seems to have disappeared, their main site has gone



I personally would recommend the latter, D3 depending on the number of items you wish to display and the browser support you need as it's well documented, powerful and faily easy to use. Check out this Github project for an example of a force-directed library.



The changes that you would need to make to accomplish the task you've set out would be to:



1) Change where the data is coming from by modifying the following function:



d3.json(flare.json, function(json) {
root = json;
root.fixed = true;
root.x = w / 2;
root.y = h / 2 - 80;
update();
});


Change the d3.json(flare.json) to point to a different file/URL on your server. It is possible to do the same thing with jQuery if you wished and use a similar callback approach.



2) To colour your nodes based on different categories you'll want to change the following section:



// Update the nodes…
node = vis.selectAll(circle.node)
.data(nodes, function(d) { return d.id; })
.style(fill, color);


Change the .style(fill, color); to something along the lines of:



.style(fill, function(d) { 
switch(d.category) {
case A: return #FF0000;
case B: return #00FF00;
default: return #0000FF;
}
});


Where category is a property on the JSON data object that you want to vary by.


[#78840] Tuesday, April 16, 2013, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
taylert

Total Points: 627
Total Questions: 91
Total Answers: 108

Location: Mayotte
Member since Mon, Sep 12, 2022
2 Years ago
taylert questions
;