|
<!DOCTYPE html> |
|
<meta charset='utf-8'> |
|
<head> |
|
<title>Simple Radial Tree (d3 v4; CSV; 63 Lines)</title> |
|
<script src="https://d3js.org/d3.v4.js"></script> |
|
<link href="//fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css"> |
|
</head> |
|
|
|
<style> |
|
html { |
|
background-color: black; |
|
} |
|
.glow { /* This trick adds a heavy white shadow around the text. */ |
|
text-shadow: |
|
-1px -1px 3px black, |
|
-1px 1px 3px black, |
|
1px -1px 3px black, |
|
1px 1px 3px black; |
|
} |
|
|
|
text { |
|
font-family: "Open Sans", sans-serif; |
|
pointer-events: none; |
|
alignment-baseline: central; |
|
fill: white; |
|
} |
|
|
|
path { |
|
fill: none; |
|
stroke: white; /* #4fb9b5; */ |
|
} |
|
</style> |
|
|
|
<svg> |
|
<g></g> |
|
</svg> |
|
|
|
<script> |
|
var vWidth = 900; |
|
var vHeight = 800; |
|
var vFontSize = [6,10,18,22]; |
|
var vColor = d3.scaleOrdinal().domain(["Oceania", "Africa", "Europe", "Latin America", "Asia"]) |
|
.range(["#ff6698", "#ffb366", "#ffff66", "#98ff66", "#6698ff"]); |
|
|
|
// .range(["#fb5454", "#f1fb54", "#54befb"]); |
|
|
|
|
|
// Prepare our physical space |
|
var g = d3.select('svg').attr('width', vWidth).attr('height', vHeight) |
|
.select('g').attr('transform', 'translate(' + vWidth/2 + ',' + vHeight/2 + ')'); |
|
|
|
// Get the data from our CSV file |
|
d3.csv('country-hierarchy.csv', function(error, vCsvData) { |
|
if (error) throw error; |
|
|
|
vData = d3.stratify()(vCsvData); |
|
drawViz(vData); |
|
}); |
|
|
|
function drawViz(vData) { |
|
|
|
vData.each( function(d){ |
|
switch (d.depth) { |
|
case 1: d.data.leg = d.id; break; |
|
case 2: d.data.leg = d.parent.id; break; |
|
case 3: d.data.leg = d.parent.parent.id; break; |
|
}}); |
|
|
|
|
|
// Declare d3 layout |
|
var vLayout = d3.cluster().size([2 * Math.PI, Math.min(vWidth, vHeight)/2 - 130]); // margin! |
|
|
|
// Layout + Data |
|
var vRoot = d3.hierarchy(vData); |
|
var vNodes = vRoot.descendants(); |
|
var vLinks = vLayout(vRoot).links(); |
|
|
|
// Draw on screen |
|
g.selectAll('path').data(vLinks).enter().append('path') |
|
.attr('d', d3.linkRadial() |
|
.angle(function (d) { return d.x; }) |
|
.radius(function (d) { return d.y; })); |
|
|
|
var node = g.selectAll(".node").data(vNodes).enter().append('g') |
|
.attr('transform', function(d) { return "translate(" + d3.pointRadial(d.x, d.y) + ")"; }); |
|
|
|
node.append("text") |
|
.text(function (d){ return d.data.data.id; }) |
|
.attr("font-size", function (d){ return vFontSize[d.height] + "pt"; }) |
|
.attr("transform", function(d) { return "rotate(" + textRotation(d) + ")" }) |
|
.attr("text-anchor", function (d){ |
|
if(d.height === 0){ return (d.x > Math.PI) ? "end" : "start"; } |
|
else { return "middle"; } }) |
|
.attr("dx", function (d){ |
|
if(d.depth === 3){ return (d.x > Math.PI) ? "-2px" : "2px"; } |
|
else { return "0px"; } }) |
|
.style("fill", function(d){ |
|
//if(d.data.data.least_devd_country === "Yes") { return "blue";} |
|
//else if (d.data.data.devd_region === "Yes") { return "green";} |
|
|
|
return vColor(d.data.data.leg); |
|
}) |
|
.classed("glow", function (d){ return d.height !== 0; }); |
|
|
|
|
|
function textRotation(d) { |
|
var angle = d.x / Math.PI * 180 + 90; |
|
|
|
if (d.depth < 2) { return 0;} |
|
else if (angle <= 270) { return angle - 180;} |
|
else { return angle;} |
|
} |
|
} |
|
</script> |