Built with blockbuilder.org
forked from anonymous's block: Dendrogram + Grouped Horizontal Bar Chart
forked from vpletzke's block: Dendrogram + Grouped Horizontal Bar Chart
forked from lorenzopub's block: Dendrogram + Grouped Horizontal Bar Chart
license: mit |
Built with blockbuilder.org
forked from anonymous's block: Dendrogram + Grouped Horizontal Bar Chart
forked from vpletzke's block: Dendrogram + Grouped Horizontal Bar Chart
forked from lorenzopub's block: Dendrogram + Grouped Horizontal Bar Chart
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
circle, | |
path { | |
cursor: pointer; | |
} | |
circle { | |
fill: none; | |
pointer-events: all; | |
} | |
</style> | |
<body> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script> | |
var margin = {top: 350, right: 480, bottom: 350, left: 480}, | |
radius = Math.min(margin.top, margin.right, margin.bottom, margin.left) - 10; | |
var hue = d3.scale.category10(); | |
var luminance = d3.scale.sqrt() | |
.domain([0, 1e6]) | |
.clamp(true) | |
.range([90, 20]); | |
var svg = d3.select("body").append("svg") | |
.attr("width", margin.left + margin.right) | |
.attr("height", margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var partition = d3.layout.partition() | |
.sort(function(a, b) { return d3.ascending(a.name, b.name); }) | |
.size([2 * Math.PI, radius]); | |
var arc = d3.svg.arc() | |
.startAngle(function(d) { return d.x; }) | |
.endAngle(function(d) { return d.x + d.dx ; }) | |
.padAngle(.01) | |
.padRadius(radius / 3) | |
.innerRadius(function(d) { return radius / 3 * d.depth; }) | |
.outerRadius(function(d) { return radius / 3 * (d.depth + 1) - 1; }); | |
d3.json("flare.json", function(error, root) { | |
if (error) throw error; | |
// Compute the initial layout on the entire tree to sum sizes. | |
// Also compute the full name and fill color for each node, | |
// and stash the children so they can be restored as we descend. | |
partition | |
.value(function(d) { return d.size; }) | |
.nodes(root) | |
.forEach(function(d) { | |
d._children = d.children; | |
d.sum = d.value; | |
d.key = key(d); | |
d.fill = fill(d); | |
}); | |
// Now redefine the value function to use the previously-computed sum. | |
partition | |
.children(function(d, depth) { return depth < 2 ? d._children : null; }) | |
.value(function(d) { return d.sum; }); | |
var center = svg.append("circle") | |
.attr("r", radius / 3) | |
.on("click", zoomOut); | |
center.append("title") | |
.text("zoom out"); | |
var path = svg.selectAll("path") | |
.data(partition.nodes(root).slice(1)) | |
.enter().append("path") | |
.attr("d", arc) | |
.style("fill", function(d) { return d.fill; }) | |
.each(function(d) { this._current = updateArc(d); }) | |
.on("click", zoomIn); | |
function zoomIn(p) { | |
if (p.depth > 1) p = p.parent; | |
if (!p.children) return; | |
zoom(p, p); | |
} | |
function zoomOut(p) { | |
if (!p.parent) return; | |
zoom(p.parent, p); | |
} | |
// Zoom to the specified new root. | |
function zoom(root, p) { | |
if (document.documentElement.__transition__) return; | |
// Rescale outside angles to match the new layout. | |
var enterArc, | |
exitArc, | |
outsideAngle = d3.scale.linear().domain([0, 2 * Math.PI]); | |
function insideArc(d) { | |
return p.key > d.key | |
? {depth: d.depth - 1, x: 0, dx: 0} : p.key < d.key | |
? {depth: d.depth - 1, x: 2 * Math.PI, dx: 0} | |
: {depth: 0, x: 0, dx: 2 * Math.PI}; | |
} | |
function outsideArc(d) { | |
return {depth: d.depth + 1, x: outsideAngle(d.x), dx: outsideAngle(d.x + d.dx) - outsideAngle(d.x)}; | |
} | |
center.datum(root); | |
// When zooming in, arcs enter from the outside and exit to the inside. | |
// Entering outside arcs start from the old layout. | |
if (root === p) enterArc = outsideArc, exitArc = insideArc, outsideAngle.range([p.x, p.x + p.dx]); | |
path = path.data(partition.nodes(root).slice(1), function(d) { return d.key; }); | |
// When zooming out, arcs enter from the inside and exit to the outside. | |
// Exiting outside arcs transition to the new layout. | |
if (root !== p) enterArc = insideArc, exitArc = outsideArc, outsideAngle.range([p.x, p.x + p.dx]); | |
d3.transition().duration(d3.event.altKey ? 7500 : 750).each(function() { | |
path.exit().transition() | |
.style("fill-opacity", function(d) { return d.depth === 1 + (root === p) ? 1 : 0; }) | |
.attrTween("d", function(d) { return arcTween.call(this, exitArc(d)); }) | |
.remove(); | |
path.enter().append("path") | |
.style("fill-opacity", function(d) { return d.depth === 2 - (root === p) ? 1 : 0; }) | |
.style("fill", function(d) { return d.fill; }) | |
.on("click", zoomIn) | |
.each(function(d) { this._current = enterArc(d); }); | |
path.transition() | |
.style("fill-opacity", 1) | |
.attrTween("d", function(d) { return arcTween.call(this, updateArc(d)); }); | |
}); | |
} | |
}); | |
function key(d) { | |
var k = [], p = d; | |
while (p.depth) k.push(p.name), p = p.parent; | |
return k.reverse().join("."); | |
} | |
function fill(d) { | |
var p = d; | |
while (p.depth > 1) p = p.parent; | |
var c = d3.lab(hue(p.name)); | |
c.l = luminance(d.sum); | |
return c; | |
} | |
function arcTween(b) { | |
var i = d3.interpolate(this._current, b); | |
this._current = i(0); | |
return function(t) { | |
return arc(i(t)); | |
}; | |
} | |
function updateArc(d) { | |
return {depth: d.depth, x: d.x, dx: d.dx}; | |
} | |
d3.select(self.frameElement).style("height", margin.top + margin.bottom + "px"); | |
</script> |
id | value | |
---|---|---|
UNC-CH | ||
UNC-CH.QuickFactsData | ||
UNC-CH.QuickFactsData.Gender | ||
UNC-CH.QuickFactsData.Gender.Female | 16827 | |
UNC-CH.QuickFactsData.Gender.Male | 12642 | |
UNC-CH.QuickFactsData.Age | ||
UNC-CH.QuickFactsData.Age.Under 25 | 20873 | |
UNC-CH.QuickFactsData.Age.25 and Over | 8595 | |
UNC-CH.QuickFactsData.Attendance | ||
UNC-CH.QuickFactsData.Attendance.Full-Time | 25084 | |
UNC-CH.QuickFactsData.Attendance.Part-Time | 4585 | |
UNC-CH.QuickFactsData.Residency | ||
UNC-CH.QuickFactsData.Residency.In-State | 21232 | |
UNC-CH.QuickFactsData.Residency.Out-of-State | 8237 | |
UNC-CH.QuickFactsData.Enrollment | ||
UNC-CH.QuickFactsData.Enrollment.Undergraduate | 18523 | |
UNC-CH.QuickFactsData.Enrollment.Graduate | 8427 | |
UNC-CH.QuickFactsData.Enrollment.Professional | 2519 | |
UNC-CH.QuickFactsData.Citizenship | ||
UNC-CH.QuickFactsData.Citizenship.US Citizen | 27114 | |
UNC-CH.QuickFactsData.Citizenship.Resident Alien | 763 | |
UNC-CH.QuickFactsData.Citizenship.Nonresident Alien | 1592 | |
UNC-CH.QuickFactsData.Proximity | ||
UNC-CH.QuickFactsData.Proximity.On-Campus | 27100 | |
UNC-CH.QuickFactsData.Proximity.Off-Campus | 2369 | |
UNC-CH.QuickFactsData.Race | ||
UNC-CH.QuickFactsData.Race.American Indian or Alaskan Native | 129 | |
UNC-CH.QuickFactsData.Race.Asian | 3759 | |
UNC-CH.QuickFactsData.Race.Black or African-American | 2342 | |
UNC-CH.QuickFactsData.Race.Hispanic | 2145 | |
UNC-CH.QuickFactsData.Race.Native Hawaiian or Pacific Islander | 43 | |
UNC-CH.QuickFactsData.Race.Race/Ethnicity Unknown | 1184 | |
UNC-CH.QuickFactsData.Race.Two or More Races | 1610 | |
UNC-CH.QuickFactsData.Race.White | 18257 |
{ | |
"name": "UNC-CH Quick Facts Data", | |
"children": [ | |
{ | |
"name": "Gender", | |
"children":[ | |
{ | |
"name": "Female", "size": 16827}, | |
{"name":"Male", "size":12642}]}, | |
{"name":"Age", | |
"children": | |
[{"name":"Under 25", "size":20873}, | |
{"name":"25 and Over", "size":8595}]}, | |
{"name":"Attendance", | |
"children": | |
[{"name":"Full-Time", "size":25084}, | |
{"name":"Part-Time", "size":4385}]}, | |
{"name":"Residency", | |
"children": | |
[{"name":"In-State", "size":21232}, | |
{"name":"Out-of-State", "size":8237}]}, | |
{"name":"Enrollment", | |
"children": | |
[{"name":"Undergraduate", "size":18523}, | |
{"name":"Graduate", "size":8427}, | |
{"name":"Professional", "size":2519}]}, | |
{"name":"Citizenship", | |
"children": | |
[{"name":"US Citizen", "size":27114}, | |
{"name":"Resident Alien", "size":763}, | |
{"name":"Nonresident Alien", "size":1592}]}, | |
{"name":"Proximity", | |
"children": | |
[{"name":"On-Campus", "size":27100}, | |
{"name":"Off-Campus", "size":2369}]}, | |
{"name":"Race", | |
"children": | |
[{"name":"American Indian or Alaskan Native", "size":129}]}, | |
{"name":"Asian", "size":27114}, | |
{"name":"Black or African-American", "size":3759}, | |
{"name":"Hispanic", "size":2342}, | |
{"name":"Native Hawaiian or Pacific Islander", "size":2145}, | |
{"name":"Race/Ethnicity Unknown", "size":43}, | |
{"name":"Two or More Races", "size":1184}, | |
{"name":"White", "size":18257}] | |
} |
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
.link { | |
fill: none; | |
stroke: #555; | |
stroke-opacity: 0.4; | |
stroke-width: 1px; | |
} | |
text { | |
font-family: "Arial Black", Gadget, sans-serif; | |
fill: black; | |
font-weight: bold; | |
font-size: 14px | |
} | |
.xAxis .tick text{ | |
fill: black; | |
} | |
.grid .tick line{ | |
stroke: grey; | |
stroke-dasharray: 5, 10; | |
opacity: 0.7; | |
} | |
.grid path{ | |
stroke-width: 0; | |
} | |
.node circle { | |
fill: #999; | |
} | |
.node--internal circle { | |
fill: #555; | |
} | |
.node--internal text { | |
font-size: 16px; | |
text-shadow: 0 2px 0 #fff, 0 -2px 0 #fff, 2px 0 0 #fff, -2px 0 0 #fff; | |
} | |
.node--leaf text { | |
fill: black; | |
} | |
.ballG text { | |
fill: black; | |
} | |
.shadow { | |
-webkit-filter: drop-shadow( -1.5px -1.5px 1.5px #000 ); | |
filter: drop-shadow( -1.5px -1.5px 1.5px #000 ); | |
} | |
</style> | |
</head> | |
<body> | |
<svg width="960" height="1100"></svg> | |
<script> | |
// main svg | |
var svg = d3.select("svg"), | |
width = +svg.attr("width"), | |
height = +svg.attr("height"), | |
g = svg.append("g").attr("transform", "translate(20,0)"); // move right 20px. | |
// x-scale and x-axis | |
var experienceName = ["", "","","","",""]; | |
var formatSkillPoints = function (d) { | |
return experienceName[d % 6]; | |
} | |
var xScale = d3.scaleLinear() | |
.domain([0, 28000]) | |
.range([0, 280]); | |
var xAxis = d3.axisTop() | |
.scale(xScale) | |
.ticks(5) | |
.tickFormat(formatSkillPoints); | |
// Setting up a way to handle the data | |
var tree = d3.cluster() // This D3 API method setup the Dendrogram datum position. | |
.size([height, width - 460]) // Total width - bar chart width = Dendrogram chart width | |
.separation(function separate(a, b) { | |
return a.parent == b.parent // 2 levels tree grouping for category | |
|| a.parent.parent == b.parent | |
|| a.parent == b.parent.parent ? 0.4 : 0.8; | |
}); | |
var stratify = d3.stratify() // This D3 API method gives cvs file flat data array dimensions. | |
.parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); }); | |
d3.csv("https://gist.githubusercontent.com/vpletzke/9607d012e725638343ee01a8e8fa6310/raw/568f6f255250192b955c3e16ff151c12cc50800d/skillsdata.csv", row, function(error, data) { | |
if (error) throw error; | |
var root = stratify(data); | |
tree(root); | |
// Draw every datum a line connecting to its parent. | |
var link = g.selectAll(".link") | |
.data(root.descendants().slice(1)) | |
.enter().append("path") | |
.attr("class", "link") | |
.attr("d", function(d) { | |
return "M" + d.y + "," + d.x | |
+ "C" + (d.parent.y + 100) + "," + d.x | |
+ " " + (d.parent.y + 100) + "," + d.parent.x | |
+ " " + d.parent.y + "," + d.parent.x; | |
}); | |
// Setup position for every datum; Applying different css classes to parents and leafs. | |
var node = g.selectAll(".node") | |
.data(root.descendants()) | |
.enter().append("g") | |
.attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); }) | |
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); | |
// Draw every datum a small circle. | |
node.append("circle") | |
.attr("r", 4); | |
// Setup G for every leaf datum. | |
var leafNodeG = g.selectAll(".node--leaf") | |
.append("g") | |
.attr("class", "node--leaf-g") | |
.attr("transform", "translate(" + 8 + "," + -13 + ")"); | |
leafNodeG.append("rect") | |
.attr("class","shadow") | |
.style("fill", function (d) {return d.data.color;}) | |
.attr("width", 2) | |
.attr("height", 30) | |
.attr("rx", 2) | |
.attr("ry", 2) | |
.transition() | |
.duration(800) | |
.attr("width", function (d) {return xScale(d.data.value);}); | |
leafNodeG.append("text") | |
.attr("dy", 19.5) | |
.attr("x", 8) | |
.style("text-anchor", "start") | |
.text(function (d) { | |
return d.data.id.substring(d.data.id.lastIndexOf(".") + 1) + " - " + d.data.value; | |
}); | |
// Write down text for every parent datum | |
var internalNode = g.selectAll(".node--internal"); | |
internalNode.append("text") | |
.attr("y", -10) | |
.style("text-anchor", "middle") | |
.text(function (d) { | |
return d.data.id.substring(d.data.id.lastIndexOf(".") + 1); | |
}); | |
// Attach axis on top of the first leaf datum. | |
var firstEndNode = g.select(".node--leaf"); | |
firstEndNode.insert("g") | |
.attr("class","xAxis") | |
.attr("transform", "translate(" + 7 + "," + -14 + ")") | |
.call(xAxis); | |
// tick mark for x-axis | |
firstEndNode.insert("g") | |
.attr("class", "grid") | |
.attr("transform", "translate(7," + (height - 15) + ")") | |
.call(d3.axisBottom() | |
.scale(xScale) | |
.ticks(5) | |
.tickSize(-height, 0, 0) | |
.tickFormat("") | |
); | |
// Emphasize the y-axis baseline. | |
svg.selectAll(".grid").select("line") | |
.style("stroke-dasharray","20,1") | |
.style("stroke","black"); | |
// The moving ball | |
/* var ballG = svg.insert("g") | |
.attr("class","ballG") | |
.attr("transform", "translate(" + 1100 + "," + height/2 + ")"); | |
ballG.insert("circle") | |
.attr("class","shadow") | |
.style("fill","steelblue") | |
.attr("r", 8); | |
ballG.insert("text") | |
.style("text-anchor", "middle") | |
.attr("dy",5) | |
.text("0.0"); | |
*/ | |
// Animation functions for mouse on and off events. | |
d3.selectAll(".node--leaf-g") | |
.on("mouseover", handleMouseOver) | |
.on("mouseout", handleMouseOut); | |
function handleMouseOver(d) { | |
var leafG = d3.select(this); | |
leafG.select("rect") | |
.attr("stroke","#4D4D4D") | |
.attr("stroke-width","2"); | |
var ballGMovement = ballG.transition() | |
.duration(400) | |
.attr("transform", "translate(" + (d.y | |
+ xScale(d.data.value) + 90) + "," | |
+ (d.x + 1.5) + ")"); | |
ballGMovement.select("circle") | |
.style("fill", d.data.color) | |
.attr("r", 18); | |
ballGMovement.select("text") | |
.delay(300) | |
.text(Number(d.data.value).toFixed(1)); | |
} | |
function handleMouseOut() { | |
var leafG = d3.select(this); | |
leafG.select("rect") | |
.attr("stroke-width","0"); | |
} | |
}); | |
function row(d) { | |
return { | |
id: d.id, | |
value: +d.value, | |
color: d.color | |
}; | |
} | |
</script> | |
</body> |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
font: 10px sans-serif; | |
position: relative; | |
} | |
.node { | |
box-sizing: border-box; | |
position: absolute; | |
overflow: hidden; | |
} | |
.node-label { | |
padding: 4px; | |
line-height: 1em; | |
white-space: pre; | |
} | |
.node-value { | |
color: rgba(0,0,0,0.8); | |
font-size: 9px; | |
margin-top: 1px; | |
} | |
</style> | |
<body> | |
<script src="//d3js.org/d3.v4.min.js"></script> | |
<script> | |
var width = 961, | |
height = 1061, | |
ratio = 4; | |
var format = d3.format(",d"); | |
var color = d3.scaleOrdinal() | |
.range(d3.schemeCategory10 | |
.map(function(c) { c = d3.rgb(c); c.opacity = 0.6; return c; })); | |
var stratify = d3.stratify() | |
.parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); }); | |
var treemap = d3.treemap() | |
.tile(d3.treemapSquarify.ratio(1)) | |
.size([width / ratio, height]); | |
d3.csv("flare.csv", type, function(error, data) { | |
if (error) throw error; | |
var root = stratify(data) | |
.sum(function(d) { return d.value; }) | |
.sort(function(a, b) { return b.height - a.height || b.value - a.value; }); | |
treemap(root); | |
d3.select("body") | |
.selectAll(".node") | |
.data(root.leaves()) | |
.enter().append("div") | |
.attr("class", "node") | |
.attr("title", function(d) { return d.id + "\n" + format(d.value); }) | |
.style("left", function(d) { return Math.round(d.x0 * ratio) + "px"; }) | |
.style("top", function(d) { return Math.round(d.y0) + "px"; }) | |
.style("width", function(d) { return Math.round(d.x1 * ratio) - Math.round(d.x0 * ratio) - 1 + "px"; }) | |
.style("height", function(d) { return Math.round(d.y1) - Math.round(d.y0) - 1 + "px"; }) | |
.style("background", function(d) { while (d.depth > 1) d = d.parent; return color(d.id); }) | |
.append("div") | |
.attr("class", "node-label") | |
.text(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1); }) | |
.append("div") | |
.attr("class", "node-value") | |
.text(function(d) { return format(d.value); }); | |
}); | |
function type(d) { | |
d.value = +d.value; | |
return d; | |
} | |
</script> |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
text { | |
font: 10px sans-serif; | |
text-anchor: middle; | |
} | |
.node--hover circle { | |
stroke: #000; | |
stroke-width: 1.2px; | |
} | |
</style> | |
<svg width="960" height="960"><g transform="translate(1,1)"></g></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 format = d3.format(",d"); | |
var color = d3.scaleSequential(d3.interpolateMagma) | |
.domain([-4, 4]); | |
var stratify = d3.stratify() | |
.parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); }); | |
var pack = d3.pack() | |
.size([width - 2, height - 2]) | |
.padding(3); | |
d3.csv("flare.csv", function(error, data) { | |
if (error) throw error; | |
var root = stratify(data) | |
.sum(function(d) { return d.value; }) | |
.sort(function(a, b) { return b.value - a.value; }); | |
pack(root); | |
var node = svg.select("g") | |
.selectAll("g") | |
.data(root.descendants()) | |
.enter().append("g") | |
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) | |
.attr("class", function(d) { return "node" + (!d.children ? " node--leaf" : d.depth ? "" : " node--root"); }) | |
.each(function(d) { d.node = this; }) | |
.on("mouseover", hovered(true)) | |
.on("mouseout", hovered(false)); | |
node.append("circle") | |
.attr("id", function(d) { return "node-" + d.id; }) | |
.attr("r", function(d) { return d.r; }) | |
.style("fill", function(d) { return color(d.depth); }); | |
var leaf = node.filter(function(d) { return !d.children; }); | |
leaf.append("clipPath") | |
.attr("id", function(d) { return "clip-" + d.id; }) | |
.append("use") | |
.attr("xlink:href", function(d) { return "#node-" + d.id + ""; }); | |
leaf.append("text") | |
.attr("clip-path", function(d) { return "url(#clip-" + d.id + ")"; }) | |
.selectAll("tspan") | |
.data(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1).split(/(?=[A-Z][^A-Z])/g); }) | |
.enter().append("tspan") | |
.attr("x", 0) | |
.attr("y", function(d, i, nodes) { return 13 + (i - nodes.length / 2 - 0.5) * 10; }) | |
.text(function(d) { return d; }); | |
node.append("title") | |
.text(function(d) { return d.id + "\n" + format(d.value); }); | |
}); | |
function hovered(hover) { | |
return function(d) { | |
d3.selectAll(d.ancestors().map(function(d) { return d.node; })).classed("node--hover", hover); | |
}; | |
} | |
</script> |
id,value,color | |
UNC-CH, | |
UNC-CH.Gender, | |
UNC-CH.Gender.Female,16827,#e9ded9 | |
UNC-CH.Gender.Male,12642,#d5c5be | |
UNC-CH.Age, | |
UNC-CH.Age.Under 25,20873,#808080 | |
UNC-CH.Age.25 and Over,8595,#80A0A0 | |
UNC-CH.Attendance, | |
UNC-CH.Attendance.Full-Time,25084,#808080 | |
UNC-CH.Attendance.Part-Time,4585,#80A0A0 | |
UNC-CH.Residency, | |
UNC-CH.Residency.In-State,21232,#808080 | |
UNC-CH.Residency.Out-of-State,8237,#80A0A0 | |
UNC-CH.Enrollment, | |
UNC-CH.Enrollment.Undergraduate,18523,#808080 | |
UNC-CH.Enrollment.Graduate,8427,#80A0A0 | |
UNC-CH.Enrollment.Professional,2519,#E54F24 | |
UNC-CH.Citizenship, | |
UNC-CH.Citizenship.US Citizen,27114,#808080 | |
UNC-CH.Citizenship.Resident Alien,763,#80A0A0 | |
UNC-CH.Citizenship.Nonresident Alien,1592,#E54F24 | |
UNC-CH.Proximity, | |
UNC-CH.Proximity.On-Campus,27100,#808080 | |
UNC-CH.Proximity.Off-Campus,2369,#80A0A0 | |
UNC-CH.Race, | |
UNC-CH.Race.American Indian or Alaskan Native,129,#808080 | |
UNC-CH.Race.Asian,3759,#80A0A0 | |
UNC-CH.Race.Black or African-American,2342,#E54F24 | |
UNC-CH.Race.Hispanic,2145,#FF9900 | |
UNC-CH.Race.Native Hawaiian or Pacific Islander,43,#563B7E | |
UNC-CH.Race.Race/Ethnicity Unknown,1184,#D6BA33 | |
UNC-CH.Race.Two or More Races,1610,#1169AE | |
UNC-CH.Race.White,18257,#F6854D |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
font: 10px sans-serif; | |
position: relative; | |
} | |
.node { | |
box-sizing: border-box; | |
position: absolute; | |
overflow: hidden; | |
} | |
.node-label { | |
padding: 4px; | |
line-height: 1em; | |
white-space: pre; | |
} | |
.node-value { | |
color: rgba(0,0,0,0.8); | |
font-size: 9px; | |
margin-top: 1px; | |
} | |
</style> | |
<body> | |
<script src="//d3js.org/d3.v4.min.js"></script> | |
<script> | |
var width = 960, | |
height = 1060; | |
var format = d3.format(",d"); | |
var color = d3.scaleOrdinal() | |
.range(d3.schemeCategory10 | |
.map(function(c) { c = d3.rgb(c); c.opacity = 0.6; return c; })); | |
var stratify = d3.stratify() | |
.parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); }); | |
var treemap = d3.treemap() | |
.size([width, height]) | |
.padding(1) | |
.round(true); | |
d3.csv("flare.csv", type, function(error, data) { | |
if (error) throw error; | |
var root = stratify(data) | |
.sum(function(d) { return d.value; }) | |
.sort(function(a, b) { return b.height - a.height || b.value - a.value; }); | |
treemap(root); | |
d3.select("body") | |
.selectAll(".node") | |
.data(root.leaves()) | |
.enter().append("div") | |
.attr("class", "node") | |
.attr("title", function(d) { return d.id + "\n" + format(d.value); }) | |
.style("left", function(d) { return d.x0 + "px"; }) | |
.style("top", function(d) { return d.y0 + "px"; }) | |
.style("width", function(d) { return d.x1 - d.x0 + "px"; }) | |
.style("height", function(d) { return d.y1 - d.y0 + "px"; }) | |
.style("background", function(d) { while (d.depth > 2) d = d.parent; return color(d.id); }) | |
.append("div") | |
.attr("class", "node-label") | |
.text(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1).split(/(?=[A-Z][^A-Z])/g).join("\n"); }) | |
.append("div") | |
.attr("class", "node-value") | |
.text(function(d) { return format(d.value); }); | |
}); | |
function type(d) { | |
d.value = +d.value; | |
return d; | |
} | |
</script> |