Skip to content

Instantly share code, notes, and snippets.

@ngopal
Created December 2, 2015 19:45
Show Gist options
  • Save ngopal/4e208d023ac4186a1e9e to your computer and use it in GitHub Desktop.
Save ngopal/4e208d023ac4186a1e9e to your computer and use it in GitHub Desktop.
A gist showing how to setup a small multiple implementation of a basic D3 force directed graph. The code also contains an example of how to read in a CSV file that contains graph edges. The JSBIN example lives here: http://jsbin.com/hinixi/2
source target
A1 A2
A2 A3
A2 A4
<!DOCTYPE html>
<html>
<head>
<style>
.link {
stroke: #000;
}
.node {
stroke: #fff;
}
</style>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
// D3 small multiples with force-directed graphs example
// with borrowed materical from this block: http://bl.ocks.org/mbostock/2949937
var width = 300;
var height = 300;
var svgOne = d3.select("#one")
.attr("width", width)
.attr("height", height);
var svgTwo = d3.select("#two")
.attr("width", width)
.attr("height", height);
// force code below
var force = d3.layout.force()
.size([width, height]);
d3.csv("graph_edges.csv", function(error, links) {
if (error !== null) {
console.log(error);
}
else {
console.log(links);
var nodesByName = {};
// Create nodes for each unique source and target.
links.forEach(function(link) {
link.source = nodeByName(link.source);
link.target = nodeByName(link.target);
});
// Extract the array of nodes from the map by name.
var nodes = d3.values(nodesByName);
// Create the link lines.
var link = svgOne.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link");
// Create the node circles.
var node = svgOne.selectAll(".node")
.data(nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 4.5)
.call(force.drag);
// Start the force layout.
force
.nodes(nodes)
.links(links)
.on("tick", tick)
.start();
// Create the link lines.
var linkTwo = svgTwo.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link");
// Create the node circles.
var nodeTwo = svgTwo.selectAll(".node")
.data(nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 4.5)
.call(force.drag);
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("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
linkTwo.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; });
nodeTwo.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
function nodeByName(name) {
return nodesByName[name] || (nodesByName[name] = {name: name});
}
}
});
</script>
</head>
<body>
<svg id="one"></svg>
<svg id="two"></svg>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment