Built with blockbuilder.org
forked from anonymous's block: Dendrogram + Grouped Horizontal Bar Chart
forked from vpletzke'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
| <!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> |