Skip to content

Instantly share code, notes, and snippets.

@beshur
Forked from mbostock/.block
Last active December 1, 2015 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beshur/e8a55a47b900096eea3b to your computer and use it in GitHub Desktop.
Save beshur/e8a55a47b900096eea3b to your computer and use it in GitHub Desktop.
Force-Directed Graph

This simple force-directed graph shows character co-occurence in Les Misérables. A physical simulation of charged particles and springs places related characters in closer proximity, while unrelated characters are farther apart. Layout algorithm inspired by Tim Dwyer and Thomas Jakobsen. Data based on character coappearence in Victor Hugo's Les Misérables, compiled by Donald Knuth.

Compare this display to a force layout with curved links, a force layout with fisheye distortion and a matrix diagram.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
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("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; });
});
});
</script>
{
"nodes":[
{"name":"[7,8,9,10,11]", "node_id":1},
{"name":"[]", "node_id":3},
{"name":"[1,8,9,10,11]", "node_id":7},
{"name":"[1,7,9,10,11]", "node_id":8},
{"name":"[1,7,8,10,11]", "node_id":9},
{"name":"[1,7,8,9,11]", "node_id":10},
{"name":"[1,7,8,9,10]", "node_id":11}
],
"links":[
{"source":0, "target":0, "value":1},
{"source":0, "target":1, "value":1},
{"source":0, "target":2, "value":1},
{"source":0, "target":3, "value":1},
{"source":0, "target":4, "value":1},
{"source":0, "target":5, "value":1},
{"source":0, "target":6, "value":1},
{"source":1, "target":2, "value":1}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment