Stacked Bar chart of job distribution in the 9 county SF Bay Area from 2002 – 2015.
This variation of a stacked bar chart shows percentages rather than absolute numbers.
forked from mbostock's block: Normalized Stacked Bar Chart
license: gpl-3.0 |
Stacked Bar chart of job distribution in the 9 county SF Bay Area from 2002 – 2015.
This variation of a stacked bar chart shows percentages rather than absolute numbers.
forked from mbostock's block: Normalized Stacked Bar Chart
year | makers | services | professions | support | all | |
---|---|---|---|---|---|---|
2002 | 845976 | 836274 | 719462 | 796246 | 3197958 | |
2003 | 782889 | 823079 | 679760 | 794857 | 3080585 | |
2004 | 774831 | 817061 | 673196 | 786663 | 3051751 | |
2005 | 790634 | 834913 | 680094 | 781862 | 3087503 | |
2006 | 790769 | 843916 | 698395 | 801632 | 3134712 | |
2007 | 808558 | 854848 | 704257 | 840688 | 3208351 | |
2008 | 786034 | 854061 | 706370 | 894112 | 3240577 | |
2009 | 728030 | 790862 | 688202 | 912137 | 3119231 | |
2010 | 705744 | 804637 | 684297 | 964995 | 3159673 | |
2011 | 712845 | 828965 | 718965 | 976399 | 3237174 | |
2012 | 716963 | 867654 | 749794 | 963670 | 3298081 | |
2013 | 733019 | 913297 | 804682 | 994328 | 3445326 | |
2014 | 766057 | 954828 | 831186 | 1013606 | 3565677 | |
2015 | 799916 | 985787 | 887679 | 1056618 | 3730000 |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
.bar { | |
fill: steelblue; | |
} | |
.axis path { | |
display: none; | |
} | |
</style> | |
<svg width="960" height="500"></svg> | |
<script src="//d3js.org/d3.v4.min.js"></script> | |
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> | |
<script> | |
var svg = d3.select("svg"), | |
margin = {top: 20, right: 60, bottom: 30, left: 40}, | |
width = +svg.attr("width") - margin.left - margin.right, | |
height = +svg.attr("height") - margin.top - margin.bottom, | |
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var x = d3.scaleBand() | |
.rangeRound([0, width]) | |
.padding(0.1) | |
.align(0.1); | |
var y = d3.scaleLinear() | |
.rangeRound([height, 0]); | |
var z = d3.scaleOrdinal(d3.schemePastel1) | |
var stack = d3.stack() | |
.offset(d3.stackOffsetExpand); | |
var format = d3.format(".2f") | |
d3.csv("data.csv", type, function(error, data) { | |
if (error) throw error; | |
data.columns.pop(); // don't need "all" | |
data.sort(function(a, b) { | |
return b[data.columns[1]] / b.total - a[data.columns[1]] / a.total; | |
}); | |
console.log(data) | |
x.domain(data.map(function(d) { return +d.year; }).sort()); | |
z.domain(data.columns.slice(1)); | |
var serie = g.selectAll(".serie") | |
.data(stack.keys(data.columns.slice(1))(data)) | |
.enter().append("g") | |
.attr("class", "serie") | |
.attr("fill", function(d) { return z(d.key); }); | |
serie.selectAll("rect") | |
.data(function(d) { return d; }) | |
.enter().append("rect") | |
.attr("x", function(d) { return x(d.data.year); }) | |
.attr("y", function(d) { return y(d[1]); }) | |
.attr("height", function(d) { return y(d[0]) - y(d[1]); }) | |
.attr("width", x.bandwidth()) | |
.each(function(d) { | |
console.log(d, this) | |
var el = d3.select(this) | |
el.append("title").text(format(d[1] - d[0]) + "%") | |
}) | |
g.append("g") | |
.attr("class", "axis axis--x") | |
.attr("transform", "translate(0," + height + ")") | |
.call(d3.axisBottom(x)); | |
g.append("g") | |
.attr("class", "axis axis--y") | |
.call(d3.axisLeft(y).ticks(10, "%")); | |
var legend = serie.append("g") | |
.attr("class", "legend") | |
.attr("transform", function(d) { | |
var d = d.find(d2 => d2.data.year === 2015) | |
return "translate(" + | |
(x(d.data.year) + x.bandwidth()) + "," + | |
((y(d[0]) + y(d[1])) / 2) + ")"; | |
}); | |
legend.append("line") | |
.attr("x1", -6) | |
.attr("x2", 6) | |
.attr("stroke", "#000"); | |
legend.append("text") | |
.attr("x", 9) | |
.attr("dy", "0.35em") | |
.attr("fill", "#000") | |
.style("font", "10px sans-serif") | |
.text(function(d) { return d.key; }); | |
}); | |
function type(d, i, columns) { | |
for (i = 0, t = 0; i < columns.length; ++i) { | |
d[columns[i]] = +d[columns[i]]; | |
} | |
d.total = +d.all; | |
delete d.all; | |
return d; | |
} | |
</script> |