Readings of the amount of PM2.5 (particulate matter less than 2.5 micrometers in diameter) in the air in Beijing for every hour over the past 8 years. Readings reported in micrograms per cubic meter.
Data is not fully validated or verified, collected unofficially from the U.S. Embassy in Beijing, and provided by the U.S. Department of State
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body { font: 10px sans-serif; }
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path { display: none; }
.line {
fill: none;
stroke-width: 1.5px;
stroke-linecap: round;
}
.line.yr_2008 { stroke: #a6cee3; }
.line.yr_2009 { stroke: #1f78b4; }
.line.yr_2010 { stroke: #b2df8a; }
.line.yr_2011 { stroke: #33a02c; }
.line.yr_2012 { stroke: #fb9a99; }
.line.yr_2013 { stroke: #e31a1c; }
.line.yr_2014 { stroke: #fdbf6f; }
.line.yr_2015 { stroke: #ff7f00; }
#years_form {
width: 36%;
margin: auto;
}
</style>
<body>
<form name="example" id="years_form">
<input type="checkbox" class="years" name="year" value="yr_2008" checked onchange="toggle()">2008
<input type="checkbox" class="years" name="year" value="yr_2009" onchange="toggle()">2009
<input type="checkbox" class="years" name="year" value="yr_2010" onchange="toggle()">2010
<input type="checkbox" class="years" name="year" value="yr_2011" onchange="toggle()">2011
<input type="checkbox" class="years" name="year" value="yr_2012" onchange="toggle()">2012
<input type="checkbox" class="years" name="year" value="yr_2013" onchange="toggle()">2013
<input type="checkbox" class="years" name="year" value="yr_2014" onchange="toggle()">2014
<input type="checkbox" class="years" name="year" value="yr_2015" onchange="toggle()">2015
</form>
<script src="//d3js.org/d3.v3.js"></script>
<script>
var margin = {top: 10, right: 50, left: 50, bottom: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = {}; // x is time
var y = d3.scale.linear() // y is value
.domain([0, 1000])
.range([height, 0]);
var line = {}; // path generators
var svg = d3.select("body").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
var data = {}, remaining = 8; // parallel loading csv code from here: https://groups.google.com/forum/#!msg/d3-js/3Y9VHkOOdCM/YnmOPopWUxQJ
d3.csv("//dhoboy.github.io/china-air-files/beijing2008.csv", function(data_2008) {
data.yr_2008 = data_2008;
if (!--remaining) draw();
})
d3.csv("//dhoboy.github.io/china-air-files/beijing2009.csv", function(data_2009) {
data.yr_2009 = data_2009;
if (!--remaining) draw();
})
d3.csv("//dhoboy.github.io/china-air-files/beijing2010.csv", function(data_2010) {
data.yr_2010 = data_2010;
if (!--remaining) draw();
})
d3.csv("//dhoboy.github.io/china-air-files/beijing2011.csv", function(data_2011) {
data.yr_2011 = data_2011;
if (!--remaining) draw();
})
d3.csv("//dhoboy.github.io/china-air-files/beijing2012.csv", function(data_2012) {
data.yr_2012 = data_2012;
if (!--remaining) draw();
})
d3.csv("//dhoboy.github.io/china-air-files/beijing2013.csv", function(data_2013) {
data.yr_2013 = data_2013;
if (!--remaining) draw();
})
d3.csv("//dhoboy.github.io/china-air-files/beijing2014.csv", function(data_2014) {
data.yr_2014 = data_2014;
if (!--remaining) draw();
})
d3.csv("//dhoboy.github.io/china-air-files/beijing2015.csv", function(data_2015) {
data.yr_2015 = data_2015;
if (!--remaining) draw();
})
function draw() {
var data_keys = d3.keys(data);
data_keys.forEach(function(year) { // set x scale's domain
x[year] = d3.time.scale()
.range([0, width]);
})
var default_x_scale = d3.time.scale() // for the axis
.domain([new Date(2015, 0, 1, 0), new Date(2015, 11, 31, 23)])
.range([0, width]);
data = d3.entries(data);
data.forEach(function(dataset) {
dataset.value = dataset.value.filter(function(d) { // only want valid readings
return d["QC Name"] == "Valid" && d["Value"] != "-999";
}).map(function(d) { // form datasets to be date and value
return {date: new Date(d["Year"], d["Month"]-1, d["Day"], d["Hour"]), value: +d["Value"]};
});
x[dataset.key]
.domain(d3.extent(dataset.value, function(d) { return d.date; }))
line[dataset.key] = d3.svg.line()
.x(function(d) { return x[dataset.key](d.date); })
.y(function(d) { return y(d.value); })
.interpolate("linear");
});
var xAxis = d3.svg.axis()
.scale(default_x_scale)
.orient("bottom")
.tickFormat(d3.time.format("%B"));
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10)
/* axes */
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("PM2.5/micrograms per cubic meter")
/* lines */
data.forEach(function(dataset) {
svg.append("path")
.datum(dataset.value)
.attr("class", "line " + dataset.key)
.attr("d", line[dataset.key])
});
svg.selectAll(".line")
.style("display", "none");
toggle();
}
function toggle() {
for (var i = 0; i < document.example.year.length; i++) {
var year = document.example.year[i];
if (year.checked) {
svg.select("." + year.value)
.style("display", "block")
} else {
svg.select("." + year.value)
.style("display", "none")
}
}
}
</script>