Skip to content

Instantly share code, notes, and snippets.

@schluppeck
Forked from mbostock/.block
Last active June 9, 2017 13:38
Show Gist options
  • Save schluppeck/5b3b452a126c643ff07757e82020e5c9 to your computer and use it in GitHub Desktop.
Save schluppeck/5b3b452a126c643ff07757e82020e5c9 to your computer and use it in GitHub Desktop.
Force-Directed Graph
license: gpl-3.0
height: 600

Force-directed layout of graph info in D3.js v4

forked from Mike Bostock's original here: https://bl.ocks.org/mbostock/4062045

Data captures relationships between staff members at UoN Psychology.

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>
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 1.5px;
}
</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var filename = 'psychology.json';
var pSize = 10, apSize = 5; // profs and a-profs
var color = d3.scaleOrdinal(d3.schemeCategory10);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody().strength(-10))
.force("center", d3.forceCenter(width / 2, height / 2));
d3.json(filename, function(error, graph) {
if (error) throw error;
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", function(d) {
return Math.sqrt(d.value);
});
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", function (d) { return d.title == "Prof" ? pSize : apSize;} )
.attr("fill", function(d) {
return color(d.group);
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
node.append("title")
.text(function(d) {
return d.title;
});
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.links);
function ticked() {
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;
});
}
});
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
</script>
{
"nodes": [
{"id": "McGraw, Paul", "group": "Vision", "title" : "Prof"},
{"id": "Cassaday, Helen" , "group": "BNS", "title" : "Prof"},
{"id": "Ferguson, Eamonn" , "group": "PSPH", "title" : "Prof"},
{"id": "Jackson, Stephen" , "group": "Perception & Action", "sz" : 10},
{"id": "Johnston, Alan", "group": "Vision", "title" : "Prof"},
{"id": "Ledgeway, Timothy", "group": "Vision", "title" : "Prof"},
{"id": "Mitchell, Peter" , "group": "HDL", "title" : "Prof"},
{"id": "O'Malley, Claire" , "group": "??", "title" : "Prof"},
{"id": "Townsend, Ellen" , "group": "PSPH", "title" : "Prof"},
{"id": "Wilding, Ed", "group": "Cognition", "title" : "Prof"},
{"id": "Bibby, Peter", "group": "Cognition"},
{"id": "Bonardi, Charlotte", "group": "BNS"},
{"id": "Chapman, Peter", "group": "Cognition"},
{"id": "Filik, Ruth", "group": "Cognition"},
{"id": "Haselgrove, Mark", "group": "BNS"},
{"id": "Lawrence, Claire", "group": "PSPH"},
{"id": "Moran, Paula", "group": "BNS"},
{"id": "Newport, Roger", "group": "Perception & Action"},
{"id": "Peirce, Jon", "group": "Vision"},
{"id": "Pitchford, Nicola", "group": "HDL"},
{"id": "Robinson, Jasper", "group": "BNS"},
{"id": "Ropar, Danielle", "group": "HDL"},
{"id": "Schluppeck, Denis", "group": "Vision", "title": "DS"},
{"id": "Schuermann, Martin", "group": "Perception & Action"},
{"id": "Serrien, Deborah", "group": "Perception & Action"},
{"id": "Tunney, Richard", "group": "Cognition"},
{"id": "van Heuven, Walter", "group": "Cognition"},
{"id": "Webb, Ben", "group": "Vision", "title": "BSW"},
{"id": "Allen, Harriet" ,"group": "Vision"},
{"id": "Bast, Tobias", "group": "BNS"},
{"id": "Bauer, Markus" ,"group": "Vision"},
{"id": "Blackie, Laura", "group": "??"},
{"id": "Cragg, Lucy", "group": "HDL"},
{"id": "Danielmeier, Claudia","group": "Cognition"},
{"id": "de Joux, Neil", "group": "??"},
{"id": "Derrfuss, Jan" ,"group": "Vision"},
{"id": "Einav, Shiri", "group": "HDL"},
{"id": "Holmes, Nicholas", "group": "Perception & Action"},
{"id": "Ison, Matias" ,"group": "Vision"},
{"id": "Roach, Neil" ,"group": "Vision"},
{"id": "Sheppard, Lizzy","group": "Cognition"},
{"id": "Smith, Alastair","group": "Cognition"},
{"id": "Spence, Alexa", "group": "??"},
{"id": "Stirk, Jonathan","group": "Cognition"}
],
"links":[
{"source": "McGraw, Paul", "target": "Schluppeck, Denis", "value": 1},
{"source": "McGraw, Paul", "target": "Ledgeway, Timothy", "value": 1},
{"source": "McGraw, Paul", "target": "Webb, Ben", "value": 1},
{"source": "McGraw, Paul", "target": "Roach, Neil", "value": 1},
{"source": "McGraw, Paul", "target": "Peirce, Jon", "value": 1},
{"source": "Peirce, Jon", "target": "Schluppeck, Denis", "value": 2},
{"source": "Peirce, Jon", "target": "Webb, Ben", "value": 2},
{"source": "Schluppeck, Denis", "target": "Webb, Ben", "value": 3},
{"source": "Schluppeck, Denis", "target": "Ledgeway, Timothy", "value": 3},
{"source": "Ropar, Danielle", "target": "Mitchell, Peter", "value": 1}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment