Last active
May 2, 2019 08:16
-
-
Save kcsluis/875d1b1a48b737567388 to your computer and use it in GitHub Desktop.
Jobs Growth Under Obama
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> | |
<meta charset="utf-8"> | |
<style type="text/css"> | |
/*svg {*/ | |
/* border: 1px solid #f0f;*/ | |
/*}*/ | |
body { | |
font-family: 'arial', sans-serif; | |
font-size: 9px; | |
} | |
h1 { | |
font-size: 36px; | |
} | |
.barPositive { | |
fill: #069; | |
} | |
.barNegative { | |
fill: lightGray; | |
} | |
.axis path { | |
display: none; | |
} | |
.axis line { | |
stroke-width: 1px; | |
stroke: #ccc; | |
stroke-dasharray: 2px 2px; | |
} | |
.xAxis { | |
font-weight: bold; | |
} | |
.label { | |
fill: #AAA; | |
} | |
.streakLine { | |
stroke: #069; | |
stroke-width: 3px; | |
} | |
.streakLabel { | |
text-anchor: middle; | |
fill: #069; | |
font-weight: bold; | |
font-size: 15px; | |
} | |
</style> | |
<body> | |
</body> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script> | |
<script> | |
// additional data sourced from | |
// http://data.bls.gov/timeseries/CES0000000001?output_view=net_1mth | |
// okay to keep these global | |
var marginCore = 20; | |
var margin = {top: 60, right: marginCore, bottom: 20, left: marginCore}; | |
var width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
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.tsv("jobs.tsv", function(error, data) { | |
if (error) throw error; | |
// data is an object, but now we need arrays | |
data.forEach( function (d) { | |
d.jobs_change = +d.jobs_change; | |
d.private_job_change = +d.private_job_change; | |
d.private_job_change = +d.private_job_change; | |
var s = d.month_year.split("-"); | |
d.date = new Date(s[0], (+s[1]-1) ); | |
}); | |
// use map to strip out jobs_change | |
var jobs = data.map( function (d) { return d.jobs_change; }); | |
var months = data.map( function (d) { return d.month_year; }); | |
// reduce, anyone? | |
var totalJobsChange = jobs.reduce( function (a, b) { | |
return a+b; | |
}); | |
var totalJobsIncrease = jobs.reduce ( function (a, b) { | |
return (b > 0) ? a+b : a; | |
}); | |
data.sort( function (a,b) { return a.date - b.date; }); | |
// console.log(data); | |
// console.log(jobs); | |
// console.log(months); | |
var jobsMin = d3.min(jobs); | |
var jobsMax = d3.max(jobs); | |
// console.log(jobsMin, jobsMax); | |
var xScale = d3.scale.ordinal() | |
.rangeRoundBands([0, width], 0.333) | |
.domain(months); | |
var yScale = d3.scale.linear() | |
.range([height, 0]) | |
.domain([jobsMin, jobsMax]); | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.tickSize(-width+35) | |
.tickPadding(6) | |
.orient("left"); | |
// could use some pointers about abstracting out this function / variable access | |
// kFormat = function (number) { | |
// return (number > 0) ? "+" + d + "k" : d + "k"; | |
// }; | |
// var changeLabel; | |
// function kFormat(number) { | |
// return (number > 0) ? "+" + d + "k" : d + "k"; | |
// }; | |
// adding yAxis up so it draws below bars | |
svg.append("g") | |
.attr("class", "axis") | |
.call(yAxis) | |
.attr("transform", "translate(18,0)") | |
.selectAll("text") | |
.text( function (d) { | |
var changeLabel = d; | |
return d = (changeLabel > 0) ? "+" + d + "k" : d + "k"; | |
}); | |
// .text( function (d) { | |
// console.log(d); | |
// var changeLabel = d; | |
// return kFormat(changeLabel); | |
// }); | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.tickSize(0) | |
.tickPadding(6) | |
.orient("bottom"); | |
var bars = svg.selectAll("bars") | |
.data(data) | |
.enter() | |
.append("rect") | |
.attr('class', function (d) { | |
if (d.jobs_change > 0) { return 'bar barPositive'} | |
else { return 'bar barNegative'}; | |
}) | |
.attr('x', function(d) { return xScale(d.month_year); }) | |
.attr("width", xScale.rangeBand()) | |
// this returns the higher of either d.jobs_change (so, positive numbers) or 0 | |
.attr('y', function(d) { return yScale(Math.max(d.jobs_change, 0)); }) | |
// this returns height as absolute value of change minus scaled value of 0 | |
.attr("height", function(d) { return Math.abs(yScale(d.jobs_change) - yScale(0)); }); | |
svg.append("line") | |
.attr('x1', 17) | |
.attr("x2", width-17) | |
.attr("y1", yScale(0)) | |
.attr("y2", yScale(0)) | |
.style("stroke", "#333") | |
.style("stroke-width", 1); | |
svg.append("g") | |
.attr("class", "xAxis") | |
.call(xAxis) | |
.attr("transform", "translate(0," + yScale(0) + ")") | |
.selectAll("g") | |
// yadda yadda yadda, use if then to add custom classes | |
.attr("class", function (d) { return d }) | |
.selectAll("text") | |
.text(function (d) { | |
var dateSplit = d.split("-"); | |
if ( dateSplit[1] === "01" ) { | |
return dateSplit[0]; | |
}; | |
}); | |
function formatNumber (num) { | |
return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,") | |
}; | |
// labels | |
svg.append("text") | |
.attr("class", "label") | |
.attr("transform", "translate(-10,-25)") | |
.style("font-size", "13px") | |
.text(function() { | |
var tJS = "+" + formatNumber(totalJobsChange) + "k"; | |
var tJI = "+" + formatNumber(totalJobsIncrease) + "k"; | |
return "Overall Increase in Jobs: " + tJS + " | Total Jobs Added: " + tJI; | |
}); | |
svg.append("text") | |
.attr("class", "label") | |
.attr("transform", "translate(-10,-40)") | |
.text("Monthly Change in U.S. Nonfarm Jobs for Extent of Obama Administration"); | |
// streak label | |
// draw a line from october 2010 to last positive month | |
// then below and centered | |
// add a label that counts number of positive months | |
var mnth, stopStreakMonth; | |
var startStreakMonth = 21; | |
// there's probably a more elegant way to do this | |
for (mnth = startStreakMonth; mnth < data.length; mnth++) { | |
if (data[mnth].jobs_change < 0) { | |
stopStreakMonth = mnth; | |
mnth = data.length; | |
} else { | |
stopStreakMonth = data.length-1; | |
}; | |
}; | |
var firstStreakMonth = xScale(months[startStreakMonth]); | |
var lastStreakMonth = xScale(months[stopStreakMonth]); | |
var lengthOfStreak = stopStreakMonth - startStreakMonth; | |
var labelBelowZero = yScale(0)+25; | |
svg.append("g") | |
.attr("class", "streakLabel") | |
.attr("transform", "translate(" + xScale.rangeBand()/2 + ",0)") | |
.append("line") | |
.attr("class", "streakLine") | |
.attr('x1', firstStreakMonth) | |
.attr("x2", lastStreakMonth) | |
.attr("y1", labelBelowZero) | |
.attr("y2", labelBelowZero); | |
svg.select(".streakLabel") | |
.append("text") | |
.attr("x", (lastStreakMonth - firstStreakMonth)/2 + firstStreakMonth) | |
.attr("y", labelBelowZero+20) | |
.text(lengthOfStreak + " Months of Continued Jobs Growth"); | |
}); | |
</script> |
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
month_year | jobs_change | private_job_change | unemployment_rate | |
---|---|---|---|---|
2009-01 | -818 | -839 | 7.8 | |
2009-02 | -724 | -725 | 8.3 | |
2009-03 | -799 | -787 | 8.7 | |
2009-04 | -692 | -802 | 8.9 | |
2009-05 | -361 | -312 | 9.4 | |
2009-06 | -482 | -426 | 9.5 | |
2009-07 | -339 | -296 | 9.5 | |
2009-08 | -231 | -219 | 9.6 | |
2009-09 | -199 | -184 | 9.8 | |
2009-10 | -202 | -232 | 10 | |
2009-11 | -42 | -42 | 9.9 | |
2009-12 | -171 | -120 | 9.9 | |
2010-01 | -40 | -40 | 9.7 | |
2010-02 | -35 | -27 | 9.8 | |
2010-03 | 189 | 141 | 9.8 | |
2010-04 | 239 | 193 | 9.9 | |
2010-05 | 516 | 84 | 9.6 | |
2010-06 | -167 | 92 | 9.4 | |
2010-07 | -58 | 92 | 9.5 | |
2010-08 | -51 | 128 | 9.6 | |
2010-09 | -27 | 115 | 9.5 | |
2010-10 | 220 | 196 | 9.5 | |
2010-11 | 121 | 134 | 9.8 | |
2010-12 | 120 | 140 | 9.4 | |
2011-01 | 110 | 119 | 9.1 | |
2011-02 | 220 | 257 | 9 | |
2011-03 | 246 | 261 | 8.9 | |
2011-04 | 251 | 264 | 9 | |
2011-05 | 54 | 108 | 9 | |
2011-06 | 84 | 102 | 9.1 | |
2011-07 | 96 | 175 | 9.1 | |
2011-08 | 85 | 52 | 9.1 | |
2011-09 | 202 | 216 | 9 | |
2011-10 | 112 | 139 | 8.9 | |
2011-11 | 157 | 178 | 8.7 | |
2011-12 | 223 | 234 | 8.5 | |
2012-01 | 275 | 277 | 8.3 | |
2012-02 | 259 | 254 | 8.3 | |
2012-03 | 143 | 147 | 8.2 | |
2012-04 | 68 | 85 | 8.1 | |
2012-05 | 87 | 116 | 8.2 | |
2012-06 | 45 | 63 | 8.2 | |
2012-07 | 181 | 163 | 8.3 | |
2012-08 | 142 | 97 | 8.1 | |
2012-09 | 114 | 104 | 7.8 | |
2012-10 | 213 | 0 | 0 | |
2012-11 | 164 | 0 | 0 | |
2012-12 | 293 | 0 | 0 | |
2013-01 | 205 | 0 | 0 | |
2013-02 | 314 | 0 | 0 | |
2013-03 | 115 | 0 | 0 | |
2013-04 | 187 | 0 | 0 | |
2013-05 | 219 | 0 | 0 | |
2013-06 | 127 | 0 | 0 | |
2013-07 | 164 | 0 | 0 | |
2013-08 | 256 | 0 | 0 | |
2013-09 | 150 | 0 | 0 | |
2013-10 | 225 | 0 | 0 | |
2013-11 | 317 | 0 | 0 | |
2013-12 | 109 | 0 | 0 | |
2014-01 | 166 | 0 | 0 | |
2014-02 | 188 | 0 | 0 | |
2014-03 | 225 | 0 | 0 | |
2014-04 | 330 | 0 | 0 | |
2014-05 | 236 | 0 | 0 | |
2014-06 | 286 | 0 | 0 | |
2014-07 | 249 | 0 | 0 | |
2014-08 | 213 | 0 | 0 | |
2014-09 | 250 | 0 | 0 | |
2014-10 | 221 | 0 | 0 | |
2014-11 | 423 | 0 | 0 | |
2014-12 | 329 | 0 | 0 | |
2015-01 | 201 | 0 | 0 | |
2015-02 | 266 | 0 | 0 | |
2015-03 | 119 | 0 | 0 | |
2015-04 | 187 | 0 | 0 | |
2015-05 | 254 | 0 | 0 | |
2015-06 | 223 | 0 | 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment