Skip to content

Instantly share code, notes, and snippets.

@d3noob

d3noob/.block

Last active Nov 30, 2019
Embed
What would you like to do?
Basic Directional Force Layout Diagram
license: mit

This is an adaption of two of Mike Bostock's force layout examples (Mobile Patent Suits and Force-Directed Graph with Mouseover).

This particular graph is intended as a 'basic' example of a directional force layout graph (hence the arrows) and I intend to add additional examples with variations.

source target value
Harry Sally 1.2
Harry Mario 1.3
Sarah Alice 0.2
Eveie Alice 0.5
Peter Alice 1.6
Mario Alice 0.4
James Alice 0.6
Harry Carol 0.7
Harry Nicky 0.8
Bobby Frank 0.8
Alice Mario 0.7
Harry Lynne 0.5
Sarah James 1.9
Roger James 1.1
Maddy James 0.3
Sonny Roger 0.5
James Roger 1.5
Alice Peter 1.1
Johan Peter 1.6
Alice Eveie 0.5
Harry Eveie 0.1
Eveie Harry 2.0
Henry Mikey 0.4
Elric Mikey 0.6
James Sarah 1.5
Alice Sarah 0.6
James Maddy 0.5
Peter Johan 0.7
<!DOCTYPE html>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<style>
path.link {
fill: none;
stroke: #666;
stroke-width: 1.5px;
}
circle {
fill: #ccc;
stroke: #fff;
stroke-width: 1.5px;
}
text {
fill: #000;
font: 10px sans-serif;
pointer-events: none;
}
</style>
<body>
<script>
// get the data
d3.csv("force.csv", function(error, links) {
var nodes = {};
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] ||
(nodes[link.source] = {name: link.source});
link.target = nodes[link.target] ||
(nodes[link.target] = {name: link.target});
link.value = +link.value;
});
var width = 960,
height = 500;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(60)
.charge(-300)
.on("tick", tick)
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// build the arrow.
svg.append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
// add the links and the arrows
var path = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("svg:path")
// .attr("class", function(d) { return "link " + d.type; })
.attr("class", "link")
.attr("marker-end", "url(#end)");
// define the nodes
var node = svg.selectAll(".node")
.data(force.nodes())
.enter().append("g")
.attr("class", "node")
.call(force.drag);
// add the nodes
node.append("circle")
.attr("r", 5);
// add the text
node.append("text")
.attr("x", 12)
.attr("dy", ".35em")
.text(function(d) { return d.name; });
// add the curvy lines
function tick() {
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" +
d.source.x + "," +
d.source.y + "A" +
dr + "," + dr + " 0 0,1 " +
d.target.x + "," +
d.target.y;
});
node
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; });
}
});
</script>
</body>
</html>
@dirkschumacher

This comment has been minimized.

Copy link

@dirkschumacher dirkschumacher commented Feb 29, 2016

Hi, great work. What license is this under? Would you mind adding this to here: http://bl.ocks.org/d3noob/5141278 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment