Skip to content

Instantly share code, notes, and snippets.

@elktamer
Forked from mbostock/.block
Last active April 6, 2021 15:46
Show Gist options
  • Save elktamer/00b31e6e1172f7915cf4bcb3663986b6 to your computer and use it in GitHub Desktop.
Save elktamer/00b31e6e1172f7915cf4bcb3663986b6 to your computer and use it in GitHub Desktop.
Hierarchical Edge Bundling
license: gpl-3.0
height: 960
border: no

Mouseover any of the nodes in this network to see the incoming links (dependants) in green and the outgoing links (dependencies) in red.

Compare to the static version.

FIRST LAST FULL NAME Additional Recording Artwork Cello Clarinet Composition & Production Design Double Bass Extended Piano Field Recording Guitar Harp Heartbeats Horn Joik Marimba Mastered Mixed Organ Percussion Piano Thank You Vibraphone Viola Voice Australia Canada (East) Canada (West) France Iceland Israel Norway Portugal Sweden United Kingdom United States of America Right Into You Aware That So (+ Nadia Sirota) Overhang Ebb Fast Twitch Bodied Lagos Honeymoon (ALBUM WIDE)
John Baron John Baron 1 1 1 1
Dan Bora Dan Bora 1 1 1 1 1 1 1 1 1 1 1
Nils Børstrand Nils Børstrand 1 1 1 1 1
Eline Brun Eline Brun 1 1 1 1 1
Mack Carson Mack Carson 1 1 1 1 1 1 1 1 1 1 1 1
Anthony Cenerini Anthony Cenerini 1 1 1
Paul Evans Paul Evans 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Morten Evensen Morten Evensen 1 1 1 1
Noel Fanaeian Noel Fanaeian 1 1 1 1 1 1 1 1 1 1 1 1
Heather Gunn Heather Gunn 1 1 1 1 1 1 1 1 1 1 1 1
Liam Hockley Liam Hockley 1 1 1
Greg Kawchuk Greg Kawchuk 1 1 1 1 1 1 1 1 1 1 1 1
Janet Kawchuk Janet Kawchuk 1 1 1 1 1 1 1 1 1 1 1 1
Jonathan Kawchuk Jonathan Kawchuk 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Michael Kawchuk Michael Kawchuk 1 1 1 1 1 1 1 1 1 1 1 1
Daylan Law Daylan Law 1 1 1 1 1
Jeremiah Levine Jeremiah Levine 1 1 1 1 1 1 1 1 1 1 1 1
Steve Levy Steve Levy
Andrew Macdonald Andrew Macdonald 1 1 1
Gur Magen Gur Magen 1 1 1
Katlin Mathison Katlin Mathison 1 1 1 1 1 1
Tom Moth Tom Moth 1 1 1
Amie Neigum Amie Neigum 1 1 1 1 1 1 1 1 1 1 1 1
Anat Nevo Anat Nevo 1 1 1
Gøril Nilsen Gøril Nilsen 1 1 1 1 1 1
Tom O’Connor Tom O’Connor 1 1 1 1 1 1
TP Oliva TP Oliva 1 1 1 1 1 1 1 1 1 1 1 1
Benoit Paillé Benoit Paillé 1 1 1 1 1 1 1 1 1 1 1 1
Daniel Rejmer Daniel Rejmer 1 1 1
Tahlia Rose Tahlia Rose 1 1 1 1 1 1 1 1 1 1 1 1
Jackie Saik Jackie Saik 1 1 1 1 1 1 1 1 1 1 1 1
Sturle Sandvik Sturle Sandvik 1 1 1
Lill Scheie Lill Scheie 1 1 1 1 1
Anna Siminoski Anna Siminoski 1 1 1
Nadia Sirota Nadia Sirota 1 1 1
Phil Steventon Phil Steventon 1 1 1 1
Mathias Van Eacloo Mathias Van Eacloo 1 1 1 1 1 1 1 1 1 1 1 1
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node {
font: 300 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
fill: #bbb;
}
.node:hover {
fill: #000;
}
.link {
stroke: steelblue;
stroke-opacity: 0.4;
fill: none;
pointer-events: none;
}
.node:hover,
.node--source,
.node--target {
font-weight: 700;
}
.node--source {
fill: #2ca02c;
}
.node--target {
fill: #d62728;
}
.link--source,
.link--target {
stroke-opacity: 1;
stroke-width: 2px;
}
.link--source {
stroke: #d62728;
}
.link--target {
stroke: #2ca02c;
}
</style>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var diameter = 960,
radius = diameter / 2,
innerRadius = radius - 120;
var cluster = d3.cluster()
.size([360, innerRadius]);
var line = d3.radialLine()
.curve(d3.curveBundle.beta(0.5))
.radius(function(d) { return d.y; })
.angle(function(d) { return d.x / 180 * Math.PI; });
var svg = d3.select("body").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(" + radius + "," + radius + ")");
var link = svg.append("g").selectAll(".link"),
node = svg.append("g").selectAll(".node");
d3.csv("credits.csv", function(error, credits) {
if (error) throw error;
var classes = creditsToClasses( credits );
var root = packageHierarchy(classes)
.sum(function(d) { return d.size; });
cluster(root);
link = link
.data(packageImports(root.leaves()))
.enter().append("path")
.each(function(d) { d.source = d[0], d.target = d[d.length - 1]; })
.attr("class", "link")
.attr("d", line);
node = node
.data(root.leaves())
.enter().append("text")
.attr("class", "node")
.attr("dy", "0.31em")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })
.attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.text(function(d) {
if( d.data.key != "FULL NAME")
return d.data.key;
})
.on("mouseover", mouseovered)
.on("mouseout", mouseouted);
});
function mouseovered(d) {
node
.each(function(n) { n.target = n.source = false; });
link
.classed("link--target", function(l) { if (l.target === d) return l.source.source = true; })
.classed("link--source", function(l) { if (l.source === d) return l.target.target = true; })
.filter(function(l) { return l.target === d || l.source === d; })
.raise();
node
.classed("node--target", function(n) { return n.target; })
.classed("node--source", function(n) { return n.source; });
}
function mouseouted(d) {
link
.classed("link--target", false)
.classed("link--source", false);
node
.classed("node--target", false)
.classed("node--source", false);
}
// Lazily construct the package hierarchy from class names.
function packageHierarchy(classes) {
var map = {};
function find(name, data) {
var node = map[name], i;
if (!node) {
node = map[name] = data || {name: name, children: []};
if (name.length) {
node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
node.parent.children.push(node);
node.key = name.substring(i + 1);
}
}
return node;
}
classes.forEach(function(d) {
if( typeof d.name != 'undefined')
find(d.name, d);
});
return d3.hierarchy(map[""]);
}
// Return a list of imports for the given array of nodes.
function packageImports(nodes) {
var map = {},
imports = [];
// Compute a map from name to node.
nodes.forEach(function(d) {
map[d.data.name] = d;
});
// For each import, construct a link from the source to target node.
nodes.forEach(function(d) {
if (d.data.imports)
d.data.imports.forEach(function(i) {
var input = map[d.data.name];
var mapi = map[i];
if( typeof mapi != 'undefined'){
var path = input.path(mapi);
imports.push(path);
}
});
});
return imports;
}
function creditsToClasses( credits){
var classArray = [];
for( var column =0; column < credits.columns.length; column++){
var classObj = {};
classObj.name = credits.columns[column];
classObj.size = 1;
classObj.imports=[];
classArray.push(classObj);
}
for(var row =1; row < credits.length; row++){
var classObj = {};
var contributor = credits[row];
classObj.name = contributor["FULL NAME"];
classObj.imports=[];
var size =1;
for( var column = 0; column < credits.columns.length;column++){
if( contributor[credits.columns[column]]==1){
classObj.imports.push(credits.columns[column]) ;
size++;
}
}
classObj.size = size;
classArray.push(classObj);
}
return classArray;
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment