Last active
July 16, 2018 11:50
-
-
Save cako/f551c5c9f86d30d2efde0a16edcc2c43 to your computer and use it in GitHub Desktop.
Hierarchical Edge Bundling for Courses (Subset)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[{"name":"EASC08001","size":10,"title":"Earth Dynamics","color":"#00004c","imports":["EASC08022","EASC08021","EASC08020","EASC08017","EASC09019","EASC09003","EASC09021","EASC10107","EASC10091"]},{"name":"GESC08002","size":2,"title":"Earth Modelling and Prediction","color":"#800000","imports":["EASC08018"]},{"name":"EASC08018","size":5,"title":"Earth Modelling and Prediction 2","color":"#00004c","imports":["EASC10118","EASC10098","EASC10102","EASC10103"]},{"name":"EASC08022","size":2,"title":"Earth Science Fundamentals for Geophysicists","color":"#00004c","imports":["EASC09021"]},{"name":"EASC08024","size":3,"title":"Environmental Geochemistry of the Earth's Surface","color":"#00004c","imports":["EASC10048","EASC10103"]},{"name":"EASC08021","size":8,"title":"Geomaterials","color":"#00004c","imports":["EASC09031","EASC09050","EASC09008","EASC10118","EASC10107","EASC10112","EASC10103"]},{"name":"EASC08020","size":12,"title":"Global Tectonics and the Rock Cycle","color":"#00004c","imports":["EASC09031","EASC09029","EASC09037","EASC09042","EASC09052","EASC09002","EASC10090","EASC10107","EASC10106","EASC10108","EASC10103"]},{"name":"EASC08008","size":5,"title":"Introduction to Geophysics","color":"#00004c","imports":["EASC08022","EASC09019","EASC09021","EASC09024"]},{"name":"EASC08017","size":2,"title":"Introduction to the Geological Record","color":"#00004c","imports":["EASC10108"]},{"name":"EASC08016","size":6,"title":"Physics of the Earth","color":"#00004c","imports":["EASC09019","EASC09021","EASC09054","EASC10110","EASC10035"]},{"name":"EASC09035","size":2,"title":"Computational Modelling for Geosciences","color":"#00004c","imports":["EASC11005"]},{"name":"EASC09019","size":1,"title":"Earth and Planetary Structure","color":"#00004c","imports":[]},{"name":"EASC09040","size":2,"title":"Exploration Geophysics","color":"#00004c","imports":["EASC10038"]},{"name":"EASC09036","size":3,"title":"Field Course in Tropical Marine and Terrestrial Geoscience","color":"#00004c","imports":["EASC10086","EASC10083"]},{"name":"EASC09031","size":1,"title":"Field Skills for Geologists","color":"#00004c","imports":[]},{"name":"EASC09033","size":3,"title":"Fields and Waves","color":"#00004c","imports":["EASC10035","EASC11003"]},{"name":"EASC09050","size":1,"title":"Geochemistry","color":"#00004c","imports":[]},{"name":"EASC09029","size":1,"title":"Geology 3rd Year Field Courses","color":"#00004c","imports":[]},{"name":"EASC09056","size":2,"title":"Global Environmental Change- Foundations","color":"#00004c","imports":["EASC10048"]},{"name":"EASC09027","size":2,"title":"Global Tectonics","color":"#00004c","imports":["EASC10118"]},{"name":"EASC09003","size":1,"title":"Hydrocarbons","color":"#00004c","imports":[]},{"name":"EASC09008","size":2,"title":"Igneous and Metamorphic Petrology","color":"#00004c","imports":["EASC10080"]},{"name":"EASC09021","size":3,"title":"Mathematical Methods for Geophysicists","color":"#00004c","imports":["EASC10036","EASC10037"]},{"name":"EASC09054","size":2,"title":"Mathematical and computational methods in Geophysics","color":"#00004c","imports":["EASC10109"]},{"name":"EASC09024","size":2,"title":"Measurement Techniques in Geophysics","color":"#00004c","imports":["EASC10040"]},{"name":"EASC09055","size":5,"title":"Research Training for Geophysics","color":"#00004c","imports":["EASC10111","EASC10065","EASC10052","EASC10053"]},{"name":"EASC09037","size":1,"title":"Sedimentology","color":"#00004c","imports":[]},{"name":"EASC09042","size":1,"title":"Spain Fieldcourse: Mountain Building and Destruction","color":"#00004c","imports":[]},{"name":"EASC09052","size":2,"title":"Structural Analysis of Rocks and Regions (SARR)","color":"#00004c","imports":["EASC10080"]},{"name":"EASC09002","size":2,"title":"Structural Geology","color":"#00004c","imports":["EASC09029"]},{"name":"EASC10118","size":1,"title":"Advanced Volcanology","color":"#00004c","imports":[]},{"name":"EASC10048","size":1,"title":"Applied Environmental Geochemistry","color":"#00004c","imports":[]},{"name":"EASC10101","size":2,"title":"Applied Hydrogeology and Near Surface Geophysics","color":"#00004c","imports":["EASC10077"]},{"name":"EASC10098","size":1,"title":"Earth's Atmospheric Composition","color":"#00004c","imports":[]},{"name":"EASC10102","size":1,"title":"Earth's Atmospheric Composition","color":"#00004c","imports":[]},{"name":"EASC10086","size":1,"title":"Environmental Geoscience 4th Year Field Course","color":"#00004c","imports":[]},{"name":"EASC10090","size":1,"title":"Evolution of the Modern Earth","color":"#00004c","imports":[]},{"name":"EASC10038","size":1,"title":"Exploration Seismology","color":"#00004c","imports":[]},{"name":"EASC10080","size":1,"title":"Formation and Evolution of Continents","color":"#00004c","imports":[]},{"name":"EASC10036","size":1,"title":"Geomagnetism","color":"#00004c","imports":[]},{"name":"EASC10109","size":1,"title":"Geophysical Imaging and Inversion","color":"#00004c","imports":[]},{"name":"EASC10116","size":1,"title":"Geophysical Investigation of Earth Resources","color":"#00004c","imports":[]},{"name":"EASC10110","size":2,"title":"Geophysical Measurement and Modelling","color":"#00004c","imports":["EASC10116"]},{"name":"EASC10111","size":1,"title":"Geophysics International Field Course","color":"#00004c","imports":[]},{"name":"EASC10065","size":1,"title":"Geophysics Project","color":"#00004c","imports":[]},{"name":"EASC10052","size":1,"title":"Geophysics Project 1","color":"#00004c","imports":[]},{"name":"EASC10053","size":1,"title":"Geophysics Project 2","color":"#00004c","imports":[]},{"name":"EASC10037","size":1,"title":"Global Geophysics","color":"#00004c","imports":[]},{"name":"EASC10082","size":2,"title":"Hydrogeology 1: Applied Hydrogeology","color":"#00004c","imports":["EASC10077"]},{"name":"EASC10077","size":1,"title":"Hydrogeology 2: Simulation of Groundwater Flow and Transport","color":"#00004c","imports":[]},{"name":"EASC10095","size":1,"title":"Igneous Petrogenesis","color":"#00004c","imports":[]},{"name":"EASC10107","size":3,"title":"Igneous, Metamorphic and Ore Processes","color":"#00004c","imports":["EASC10095","EASC10112"]},{"name":"EASC10083","size":1,"title":"Marine Systems and Policies (UG)","color":"#00004c","imports":[]},{"name":"EASC10106","size":1,"title":"Palaeontology and Sedimentology","color":"#00004c","imports":[]},{"name":"EASC10108","size":1,"title":"Petroleum Systems","color":"#00004c","imports":[]},{"name":"EASC10112","size":1,"title":"Planetary Geochemistry","color":"#00004c","imports":[]},{"name":"EASC10103","size":3,"title":"Practical Geochemistry and Data Analysis","color":"#00004c","imports":["EASC10086","EASC10112"]},{"name":"EASC10035","size":1,"title":"Seismology","color":"#00004c","imports":[]},{"name":"EASC10040","size":1,"title":"Transferable Skills for Geophysicists","color":"#00004c","imports":[]},{"name":"EASC10091","size":1,"title":"Volcanology","color":"#00004c","imports":[]},{"name":"EASC11003","size":1,"title":"Controlled Source Electro-Magnetic (CSEM) Methods","color":"#00004c","imports":[]},{"name":"EASC11005","size":1,"title":"Scientific Computing Skills","color":"#00004c","imports":[]}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
.node { | |
font: 300 18px "Helvetica Neue", Helvetica, Arial, sans-serif; | |
fill: #bbb; | |
} | |
.node:hover { | |
fill: #000; | |
} | |
.link { | |
stroke: steelblue; | |
stroke-opacity: 0.4; | |
stroke-width: 2px; | |
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: 3px; | |
} | |
.link--source { | |
stroke: #d62728; | |
} | |
.link--target { | |
stroke: #2ca02c; | |
} | |
ul { | |
display: flex; | |
justify-content: center; | |
} | |
li { | |
font: 300 22px "Helvetica Neue", Helvetica, Arial, sans-serif; | |
display: block; | |
text-align: center; | |
padding-right: 16px; | |
} | |
</style> | |
<body> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script> | |
if (screen.width > screen.height){ | |
var width = screen.width*0.988, | |
height = 1.5*screen.height; | |
} else { | |
var width = screen.height*0.988, | |
height = 1.5*screen.width; | |
} | |
var radius = Math.min(width, height) / Math.PI, | |
innerRadius = radius*Math.PI/10; | |
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", width) | |
.attr("height", height) | |
.append("g") | |
.attr("transform", "translate(" + width/2 + "," + height/3.4 + ")"); | |
var link = svg.append("g").selectAll(".link"), | |
node = svg.append("g").selectAll(".node"); | |
d3.json("hierarchy.json", function(error, classes) { | |
if (error) throw error; | |
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") | |
.style("fill", function(d) { return d.data.color; }) | |
.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.length > 35) { | |
return d.data.key.slice(0, 35) + "..."; | |
} | |
return d.data.key; | |
}) | |
.on("dblclick", function(d) { window.open('http://www.drps.ed.ac.uk/17-18/dpt/cx' + d.data.name.toLowerCase() + '.htm'); }) | |
.on("click", 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; }) | |
.append("svg:title").text(function(n) { | |
var txt = n.data.key + ' (' + n.data.name + ')'; | |
var i; | |
if (n.data.imports.length > 0) { | |
txt += "\nRequires: " | |
for (i=0; i < n.data.imports.length-1; i++){ | |
txt += n.data.imports[i] + ", "; | |
} | |
txt += n.data.imports[n.data.imports.length-1]; | |
} | |
return txt | |
}); | |
} | |
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 names = []; | |
var colors = []; | |
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 = data.title;//name.substring(i + 1); | |
node.color = data.color; | |
names.push(data.name.slice(0, 4)); | |
colors.push(data.color); | |
} | |
} | |
return node; | |
} | |
classes.forEach(function(d) { | |
find(d.name, d); | |
}); | |
names_unique = names.reverse().filter(function (e, i, names) { | |
return names.indexOf(e, i+1) === -1; | |
}).reverse(); | |
colors_unique = colors.reverse().filter(function (e, i, colors) { | |
return colors.indexOf(e, i+1) === -1; | |
}).reverse(); | |
var ul = d3.select('body').insert('ul', ":first-child"); | |
ul.selectAll('li') | |
.data(names_unique) | |
.enter() | |
.append('li') | |
.html(String) | |
.style("color", function(d, i) { | |
return colors_unique[i]; | |
}); | |
ul = d3.select('body').insert('ul', ":first-child"); | |
ul.selectAll('li') | |
.data(["Subject Code"]) | |
.enter() | |
.append('li') | |
.html(String) | |
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) { | |
imports.push(map[d.data.name].path(map[i])); | |
}); | |
}); | |
return imports; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment