toolkit/javascript/d3/examples/population/population.js
changeset 47 c0b4a8b5a012
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolkit/javascript/d3/examples/population/population.js	Thu Apr 10 14:20:23 2014 +0200
@@ -0,0 +1,126 @@
+var w = 960,
+    h = 500,
+    x = d3.scale.linear().range([0, w]),
+    y = d3.scale.linear().range([0, h - 40]);
+
+// An SVG element with a bottom-right origin.
+var svg = d3.select("#chart").append("svg:svg")
+    .attr("width", w)
+    .attr("height", h)
+    .style("padding-right", "30px")
+  .append("svg:g")
+    .attr("transform", "translate(" + x(1) + "," + (h - 20) + ")scale(-1,-1)");
+
+// A sliding container to hold the bars.
+var body = svg.append("svg:g")
+    .attr("transform", "translate(0,0)");
+
+// A container to hold the y-axis rules.
+var rules = svg.append("svg:g");
+
+// A label for the current year.
+var title = svg.append("svg:text")
+    .attr("class", "title")
+    .attr("dy", ".71em")
+    .attr("transform", "translate(" + x(1) + "," + y(1) + ")scale(-1,-1)")
+    .text(2000);
+
+d3.csv("population.csv", function(data) {
+
+  // Convert strings to numbers.
+  data.forEach(function(d) {
+    d.people = +d.people;
+    d.year = +d.year;
+    d.age = +d.age;
+  });
+
+  // Compute the extent of the data set in age and years.
+  var age0 = 0,
+      age1 = d3.max(data, function(d) { return d.age; }),
+      year0 = d3.min(data, function(d) { return d.year; }),
+      year1 = d3.max(data, function(d) { return d.year; }),
+      year = year1;
+
+  // Update the scale domains.
+  x.domain([0, age1 + 5]);
+  y.domain([0, d3.max(data, function(d) { return d.people; })]);
+
+  // Add rules to show the population values.
+  rules = rules.selectAll(".rule")
+      .data(y.ticks(10))
+    .enter().append("svg:g")
+      .attr("class", "rule")
+      .attr("transform", function(d) { return "translate(0," + y(d) + ")"; });
+
+  rules.append("svg:line")
+      .attr("x2", w);
+
+  rules.append("svg:text")
+      .attr("x", 6)
+      .attr("dy", ".35em")
+      .attr("transform", "rotate(180)")
+      .text(function(d) { return Math.round(d / 1e6) + "M"; });
+
+  // Add labeled rects for each birthyear.
+  var years = body.selectAll("g")
+      .data(d3.range(year0 - age1, year1 + 5, 5))
+    .enter().append("svg:g")
+      .attr("transform", function(d) { return "translate(" + x(year1 - d) + ",0)"; });
+
+  years.selectAll("rect")
+      .data(d3.range(2))
+    .enter().append("svg:rect")
+      .attr("x", 1)
+      .attr("width", x(5) - 2)
+      .attr("height", 1e-6);
+
+  years.append("svg:text")
+      .attr("y", -6)
+      .attr("x", -x(5) / 2)
+      .attr("transform", "rotate(180)")
+      .attr("text-anchor", "middle")
+      .style("fill", "#fff")
+      .text(String);
+
+  // Add labels to show the age.
+  svg.append("svg:g").selectAll("text")
+      .data(d3.range(0, age1 + 5, 5))
+    .enter().append("svg:text")
+      .attr("text-anchor", "middle")
+      .attr("transform", function(d) { return "translate(" + (x(d) + x(5) / 2) + ",-4)scale(-1,-1)"; })
+      .attr("dy", ".71em")
+      .text(String);
+
+  // Nest by year then birthyear.
+  data = d3.nest()
+      .key(function(d) { return d.year; })
+      .key(function(d) { return d.year - d.age; })
+      .rollup(function(v) { return v.map(function(d) { return d.people; }); })
+      .map(data);
+
+  // Allow the arrow keys to change the displayed year.
+  d3.select(window).on("keydown", function() {
+    switch (d3.event.keyCode) {
+      case 37: year = Math.max(year0, year - 10); break;
+      case 39: year = Math.min(year1, year + 10); break;
+    }
+    redraw();
+  });
+
+  redraw();
+
+  function redraw() {
+    if (!(year in data)) return;
+    title.text(year);
+
+    body.transition()
+        .duration(750)
+        .attr("transform", function(d) { return "translate(" + x(year - year1) + ",0)"; });
+
+    years.selectAll("rect")
+        .data(function(d) { return data[year][d] || [0, 0]; })
+      .transition()
+        .duration(750)
+        .attr("height", y);
+  }
+});