block by kcsluis 493f973ea9c9dfe49ad0

Bar Graph

Full Screen

index.html

<!DOCTYPE html>

<head>
	<meta charset="utf-8">
	<title></title>
	<style type="text/css">
	body {
		font-family: sans-serif;
	}
	.barPositive {
		fill: #333;
	}
	.barNegative {
		fill: #ccc;
	}
	.axis text {
		font-size: 10px;
		fill: #777;
	}
	.axis path {
		display: none;
	}
	.axis line {
		stroke-width:1px;
		stroke: #ccc;
		stroke-dasharray: 2px 2px;
	}
</style>
</head>

<body>
</body>

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
<script>

var margin = {top: 20, right: 20, bottom: 20, left: 60};
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 + ")");

// ordinal scale and rangeRoundBands are uniquely important for bar graphs
var x = d3.scale.ordinal()
		.rangeRoundBands([0, width], 0.33);
var y = d3.scale.linear()
		.range([height, 0]);

var xAxis = d3.svg.axis()
		.scale(x)
		.tickSize(-height)
		.tickPadding(8)
		.orient("bottom");
var yAxis = d3.svg.axis()
		.scale(y)
		.tickSize(-width)
		.tickPadding(8)
		.orient("left");

d3.tsv("jobs.tsv", ready);

function ready(err, data) {
	if (err) throw "error loading data";

	data.forEach(function(d) {
		d.jobs_change = +d.jobs_change;
		d.private_job_change = +d.private_job_change;
		d.unemployment_rate = +d.unemployment_rate;
		var s = d.month_year.split("-");
		d.date = new Date(s[0], (+s[1]-1) );
	});

	y.domain(d3.extent(data, function (d) { return d.jobs_change; }));
	data.sort(function(a,b) { return a.date - b.date; });
	x.domain(data.map( function (d) { return d.month_year; }));

	svg.append("g")
			.attr("class", "x axis")
			.attr("transform", "translate(0," + (height) + ")")
			.call(xAxis)
			// selectAll text to update axis text
			.selectAll("text")
			.text(function (d) { 
				var dateSplit = d.split("-");
				if ( dateSplit[1] === "01" ) {
					return dateSplit[0];
				};
 			});
	svg.append("g")
			.attr("class", "y axis")
			.call(yAxis)
			.selectAll("text")
			.text( function	(d) { 
				var changeLabel = d;
				return d = (changeLabel > 0) ? "+" + d + "k" : d + "k";
			});

	var rect = svg.append("g").attr("class", "g-rect-group").selectAll("rect")
			.data(data)
			.enter()
			.append("rect")
			// ternary to add positive or negative class to bars
			.attr("class", function (d) { 
				return (d.jobs_change > 0) ? 'bar barPositive' : 'bar barNegative';
			})
			// .rangeBand() function with rangeRoundBand to properly space bars
			.attr("width", x.rangeBand())
			.attr("x", function(d) { return x(d.month_year); })
			// fancy absolute values to handle positive and negative values
			.attr("y", function(d) { return y(Math.max(d.jobs_change, 0)); })
			.attr("height", function(d) { return Math.abs(y(d.jobs_change) - y(0)); });

};

</script>

jobs.tsv

month_year	jobs_change	private_job_change	unemployment_rate
2008-11	-803	-797	6.8
2008-12	-661	-658	7.3
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