Skip to content

Instantly share code, notes, and snippets.

@mbostock
Forked from mbostock/.block
Last active October 12, 2024 05:42
Show Gist options
  • Save mbostock/3886208 to your computer and use it in GitHub Desktop.
Save mbostock/3886208 to your computer and use it in GitHub Desktop.
Stacked Bar Chart

This stacked bar chart is constructed from a CSV file storing the populations of different states by age group. The chart employs conventional margins and a number of D3 features:

This example doesn’t use d3.layout.stack because it’s easy to just stack each state independently via array.forEach.

State Under 5 Years 5 to 13 Years 14 to 17 Years 18 to 24 Years 25 to 44 Years 45 to 64 Years 85 Years and Over
AL 310504 552339 259034 450818 1788160 1215966 85079
AK 52083 85640 42153 74257 244157 183159 4844
AZ 515910 828669 362642 601943 2544350 1523681 122985
AR 202070 343207 157204 264160 1102950 727124 58675
CA 2704659 4499890 2159981 3853788 14106543 8819342 612463
CO 358280 587154 261701 466194 1908747 1290094 67286
CT 211637 403658 196918 325110 1315851 968967 79111
DE 59319 99496 47414 84464 335753 230528 16118
DC 36352 50439 25225 75569 253061 140043 11144
FL 1140516 1938695 925060 1607297 7448550 4746856 521366
GA 740521 1250460 557860 919876 3705590 2389018 122419
HI 87207 134025 64011 124834 514623 331817 31681
ID 121746 201192 89702 147606 562896 375173 25501
IL 894368 1558919 725973 1311479 4932730 3239173 238921
IN 443089 780199 361393 605863 2419717 1647881 118650
IA 201321 345409 165883 306398 1116360 788485 78699
KS 202529 342134 155822 293114 1032553 713663 62319
KY 284601 493536 229927 381394 1670745 1134283 74759
LA 310716 542341 254916 471275 1630527 1128771 72250
ME 71459 133656 69752 112682 502277 397911 28719
MD 371787 651923 316873 543470 2143906 1513754 91884
MA 383568 701752 341713 665879 2510450 1751508 143097
MI 625526 1179503 585169 974480 3745900 2706100 186744
MN 358471 606802 289371 507289 1959728 1391878 106854
MS 220813 371502 174405 305964 1083566 730133 52235
MO 399450 690476 331543 560463 2253183 1554812 121678
MT 61114 106088 53156 95232 353363 278241 20246
NE 132092 215265 99638 186657 657016 451756 41008
NV 199175 325650 142976 212379 1034700 653357 31930
NH 75297 144235 73826 119114 490607 388250 24480
NJ 557421 1011656 478505 769321 3355280 2335168 175310
NM 148323 241326 112801 203097 741356 501604 35849
NY 1208495 2141490 1058031 1999120 7564953 5120254 397954
NC 652823 1097890 492964 883397 3566601 2380685 148054
ND 41896 67358 33794 82629 231417 166615 17772
OH 743750 1340492 646135 1081734 4361335 3083815 228649
OK 266547 438926 200562 369916 1377898 918688 69824
OR 243483 424167 199925 338162 1471825 1036269 76229
PA 737462 1345341 679201 1203944 4758088 3414001 310242
RI 60934 111408 56198 114502 399424 282321 26001
SC 303024 517803 245400 438147 1712803 1186019 76604
SD 58566 94438 45305 82869 292193 210178 20645
TN 416334 725948 336312 550612 2432897 1646623 106162
TX 2027307 3277946 1420518 2454721 9157082 5656528 332872
UT 268916 413034 167685 329585 985328 538978 32898
VT 32635 62538 33757 61679 229704 188593 12364
VA 522672 887525 413004 768475 3022170 2033550 121693
WA 433119 750274 357782 610378 2520000 1762811 114860
WV 105435 189649 91074 157989 717314 514505 38502
WI 362277 640286 311849 553914 2120449 1522038 117154
WY 38253 60890 29314 53980 193967 147279 8985
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["#4682b4", "#536793", "#574d73", "#553355", "#733247", "#8c2f39", "#a52a2a"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("data.csv", function(error, data) {
var ageNames = d3.keys(data[0]).filter(function(key) { return key !== "State"; });
data.forEach(function(d) {
var y0 = 0;
d.ages = ageNames.map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
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; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
var legend = svg.selectAll(".legend")
.data(ageNames.reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.State) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
});
</script>
@jason69
Copy link

jason69 commented Jul 30, 2013

Hi,
how would you add a ZoomBehaviour on that graph? https://github.com/mbostock/d3/wiki/Zoom-Behavior
I can't achieve it yet...

@goodchild999
Copy link

Hello,

Chart looks amazing, could you possibly give a hint as to how to add data labels to each sub bar ?

Thank you so much !!

@rmat3
Copy link

rmat3 commented Feb 18, 2016

great work Mike!
I have a question. Consider there is one more dimension say region(north, south,east,west) in the data. How can I add a dropdown on the page and update chart on change in value of region?

@NeckbreakerPascal
Copy link

Hey Mike,
looks amazing and I really like the code.

Just one question because I like to use it for a project. Is there a chance for drawing a "vertical stroke" to the bars. For example if there would be some average value or something for that state.

Thank you in advance for your answer

@NatasaPeic
Copy link

Thank you for this chart! I have been using it, and I have been struggling with colors.

I can't seem to find a way to change colors based on data values. I know how to do that for bar chart, but not for stacked bar chart. Any advice would be appreciated!

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment