Built with blockbuilder.org
Last active
October 28, 2016 23:42
-
-
Save jcnesci/6e3029c08d9f339910274422b72f9ca5 to your computer and use it in GitHub Desktop.
Stacked Barchart with Transitions
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
license: mit |
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
State | Under 5 Years | 5 to 13 Years | 14 to 17 Years | 18 to 24 Years | 25 to 44 Years | 45 to 64 Years | 65 Years and Over | |
---|---|---|---|---|---|---|---|---|
AL | 310504 | 552339 | 259034 | 450818 | 1231572 | 1215966 | 641667 | |
AK | 52083 | 85640 | 42153 | 74257 | 198724 | 183159 | 50277 | |
AZ | 515910 | 828669 | 362642 | 601943 | 1804762 | 1523681 | 862573 | |
AR | 202070 | 343207 | 157204 | 264160 | 754420 | 727124 | 407205 | |
CA | 2704659 | 4499890 | 2159981 | 3853788 | 10604510 | 8819342 | 4114496 | |
CO | 358280 | 587154 | 261701 | 466194 | 1464939 | 1290094 | 511094 | |
CT | 211637 | 403658 | 196918 | 325110 | 916955 | 968967 | 478007 | |
DE | 59319 | 99496 | 47414 | 84464 | 230183 | 230528 | 121688 | |
DC | 36352 | 50439 | 25225 | 75569 | 193557 | 140043 | 70648 | |
FL | 1140516 | 1938695 | 925060 | 1607297 | 4782119 | 4746856 | 3187797 | |
GA | 740521 | 1250460 | 557860 | 919876 | 2846985 | 2389018 | 981024 | |
HI | 87207 | 134025 | 64011 | 124834 | 356237 | 331817 | 190067 | |
ID | 121746 | 201192 | 89702 | 147606 | 406247 | 375173 | 182150 | |
IL | 894368 | 1558919 | 725973 | 1311479 | 3596343 | 3239173 | 1575308 | |
IN | 443089 | 780199 | 361393 | 605863 | 1724528 | 1647881 | 813839 | |
IA | 201321 | 345409 | 165883 | 306398 | 750505 | 788485 | 444554 | |
KS | 202529 | 342134 | 155822 | 293114 | 728166 | 713663 | 366706 | |
KY | 284601 | 493536 | 229927 | 381394 | 1179637 | 1134283 | 565867 | |
LA | 310716 | 542341 | 254916 | 471275 | 1162463 | 1128771 | 540314 | |
ME | 71459 | 133656 | 69752 | 112682 | 331809 | 397911 | 199187 | |
MD | 371787 | 651923 | 316873 | 543470 | 1556225 | 1513754 | 679565 | |
MA | 383568 | 701752 | 341713 | 665879 | 1782449 | 1751508 | 871098 | |
MI | 625526 | 1179503 | 585169 | 974480 | 2628322 | 2706100 | 1304322 | |
MN | 358471 | 606802 | 289371 | 507289 | 1416063 | 1391878 | 650519 | |
MS | 220813 | 371502 | 174405 | 305964 | 764203 | 730133 | 371598 | |
MO | 399450 | 690476 | 331543 | 560463 | 1569626 | 1554812 | 805235 | |
MT | 61114 | 106088 | 53156 | 95232 | 236297 | 278241 | 137312 | |
NE | 132092 | 215265 | 99638 | 186657 | 457177 | 451756 | 240847 | |
NV | 199175 | 325650 | 142976 | 212379 | 769913 | 653357 | 296717 | |
NH | 75297 | 144235 | 73826 | 119114 | 345109 | 388250 | 169978 | |
NJ | 557421 | 1011656 | 478505 | 769321 | 2379649 | 2335168 | 1150941 | |
NM | 148323 | 241326 | 112801 | 203097 | 517154 | 501604 | 260051 | |
NY | 1208495 | 2141490 | 1058031 | 1999120 | 5355235 | 5120254 | 2607672 | |
NC | 652823 | 1097890 | 492964 | 883397 | 2575603 | 2380685 | 1139052 | |
ND | 41896 | 67358 | 33794 | 82629 | 154913 | 166615 | 94276 | |
OH | 743750 | 1340492 | 646135 | 1081734 | 3019147 | 3083815 | 1570837 | |
OK | 266547 | 438926 | 200562 | 369916 | 957085 | 918688 | 490637 | |
OR | 243483 | 424167 | 199925 | 338162 | 1044056 | 1036269 | 503998 | |
PA | 737462 | 1345341 | 679201 | 1203944 | 3157759 | 3414001 | 1910571 | |
RI | 60934 | 111408 | 56198 | 114502 | 277779 | 282321 | 147646 | |
SC | 303024 | 517803 | 245400 | 438147 | 1193112 | 1186019 | 596295 | |
SD | 58566 | 94438 | 45305 | 82869 | 196738 | 210178 | 116100 | |
TN | 416334 | 725948 | 336312 | 550612 | 1719433 | 1646623 | 819626 | |
TX | 2027307 | 3277946 | 1420518 | 2454721 | 7017731 | 5656528 | 2472223 | |
UT | 268916 | 413034 | 167685 | 329585 | 772024 | 538978 | 246202 | |
VT | 32635 | 62538 | 33757 | 61679 | 155419 | 188593 | 86649 | |
VA | 522672 | 887525 | 413004 | 768475 | 2203286 | 2033550 | 940577 | |
WA | 433119 | 750274 | 357782 | 610378 | 1850983 | 1762811 | 783877 | |
WV | 105435 | 189649 | 91074 | 157989 | 470749 | 514505 | 285067 | |
WI | 362277 | 640286 | 311849 | 553914 | 1487457 | 1522038 | 750146 | |
WY | 38253 | 60890 | 29314 | 53980 | 137338 | 147279 | 65614 |
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> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script> | |
<style>s | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
</style> | |
</head> | |
<body> | |
<script> | |
var margin = {top: 20, right: 20, bottom: 30, left: 40}, | |
outerWidth = 960, | |
outerHeight = 500, | |
width = outerWidth - margin.left - margin.right, | |
height = outerHeight - margin.top - margin.bottom, | |
svg = d3.select("body").append("svg") | |
.attr("width", outerWidth) | |
.attr("height", outerHeight), | |
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"), | |
data = undefined, | |
serie, | |
serieEnter, | |
rect, | |
rectEnter; | |
var x = d3.scaleBand() | |
.rangeRound([0, width]) | |
.padding(0.1) | |
.align(0.1); | |
var y = d3.scaleLinear() | |
.rangeRound([height, 0]); | |
var z = d3.scaleOrdinal() | |
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); | |
var stack = d3.stack(); | |
d3.csv("data.csv", type, function(error, iData) { | |
if (error) throw error; | |
data = iData; | |
data.sort(function(a, b) { return b.total - a.total; }); | |
x.domain(data.map(function(d) { return d.State; })); | |
y.domain([0, d3.max(data, function(d) { return d.total; })]).nice(); | |
z.domain(data.columns.slice(1)); | |
// Button to generate new data. | |
g.append("rect") | |
.attr("class", "btn-update-data") | |
.attr("width", 60) | |
.attr("height", 20) | |
.attr("transform", "translate("+ (width-200) +", 0)") | |
.attr("fill", "red") | |
.on("click", function() { | |
updateChart(jumbleData(data), false); | |
}); | |
var legend = g.selectAll(".legend") | |
.data(data.columns.slice(1).reverse()) | |
.enter().append("g") | |
.attr("class", "legend") | |
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }) | |
.style("font", "10px sans-serif"); | |
legend.append("rect") | |
.attr("x", width - 18) | |
.attr("width", 18) | |
.attr("height", 18) | |
.attr("fill", z); | |
legend.append("text") | |
.attr("x", width - 24) | |
.attr("y", 9) | |
.attr("dy", ".35em") | |
.attr("text-anchor", "end") | |
.text(function(d) { return d; }); | |
updateChart(data, true); | |
}); | |
// Update the chart with the specified data. | |
function updateChart(iData, initializing) { | |
console.log("************* ENTER-updateChart") | |
console.log("iData", iData) | |
// ---------------------------------------------------------------- | |
// SERIE | |
// ---------------------------------------------------------------- | |
// SERIE ENTER ----------------------- | |
var stacks = stack.keys(iData.columns.slice(1))(iData); | |
// flatten stacks array | |
var stackData = []; | |
for (var i = 0; i < stacks.length; i++) { | |
for (var j = 0; j < stacks[i].length; j++) { | |
stacks[i][j].key = stacks[i].key; | |
stackData.push(stacks[i][j]); | |
} | |
} | |
if (initializing) { | |
// Parent bar | |
serieEnter = g.append("g").attr("class", "rects"); | |
rect = serieEnter.selectAll("rect.chart-rect") | |
// .data(stackData) | |
.data(stackData) | |
.enter() | |
.append("rect") | |
.attr("class", "chart-rect") | |
.attr("state", function(d) {return d.data.State; }) | |
.attr("x", function(d) { return x(d.data.State); }) | |
.attr("y", function(d) { return y(d[1]); }) | |
.attr("height", function(d) { return y(d[0]) - y(d[1]); }) | |
.attr("width", x.bandwidth()) | |
.attr("fill", function(d) { return z(d.key)}); | |
} else { | |
serieEnter = g.select("g.rects"); | |
rect = serieEnter.selectAll("rect.chart-rect") | |
.data(stackData) | |
.attr("height", 0); | |
// rect.transition() | |
// .attr("x", function(d) { return x(d.data.State); }) | |
// .duration(1000); | |
console.log("stackData", stackData) | |
rect.transition() | |
.attr("x", function(d) { return x(d.data.State); }) | |
.attr("height", function(d) { return y(d[0]) - y(d[1]); }) | |
.duration(1000); | |
} | |
// ---------------------------------------------------------------- | |
// AXES | |
// ---------------------------------------------------------------- | |
if (initializing) { | |
// X axis | |
g.append("g") | |
.attr("class", "axis axis-x") | |
.attr("transform", "translate(0," + height + ")") | |
.call(d3.axisBottom(x)); | |
// Y axis | |
g.append("g") | |
.attr("class", "axis axis-y") | |
.call(d3.axisLeft(y).ticks(10, "s")) | |
.append("text") | |
.attr("x", 2) | |
.attr("y", y(y.ticks(10).pop())) | |
.attr("dy", "0.35em") | |
.attr("text-anchor", "start") | |
.attr("fill", "#000") | |
.text("Population"); | |
} else { | |
// remove xAxis | |
g.select("g.axis-x").remove(); | |
// X axis | |
g.append("g") | |
.attr("class", "axis axis-x") | |
.attr("transform", "translate(0," + height + ")") | |
.call(d3.axisBottom(x)); | |
} | |
} | |
// Jumble the data so we can test transitioning to new data. | |
function jumbleData(iData) { | |
// console.log("*************** ENTER-jumbleData") | |
// console.log("iData", iData) | |
var result = undefined; | |
var oldColumns = iData.columns; | |
var data = _.cloneDeep(iData); // for some reason, clone() removes the 'columns' obj in iData, so we don't need to remove it after cloning... nice | |
// console.log("data", data) | |
for (var i = 0; i < data.length; i++) { | |
// console.log("------------- i", i) | |
var cur = data[i]; | |
var itemToSwapDataWith = _.sample(data) | |
// console.log("cur", cur) | |
// console.log("itemToSwapDataWith", itemToSwapDataWith) | |
// Swap state names for the 2 objects, so their data is swaped, essentially. | |
var curState = cur.State; | |
cur.State = itemToSwapDataWith.State; | |
itemToSwapDataWith.State = curState; | |
// console.log("----- SWAP -----") | |
// console.log("cur", cur) | |
// console.log("itemToSwapDataWith", itemToSwapDataWith) | |
} | |
data.columns = oldColumns; | |
result = data; | |
// console.log("result", result) | |
return result; | |
} | |
function type(d, i, columns) { | |
for (i = 1, t = 0; i < columns.length; ++i) t += d[columns[i]] = +d[columns[i]]; | |
d.total = t; | |
return d; | |
} | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment