toolkit/javascript/d3/examples/population/population.js
changeset 47 c0b4a8b5a012
equal deleted inserted replaced
46:efd9c589177a 47:c0b4a8b5a012
       
     1 var w = 960,
       
     2     h = 500,
       
     3     x = d3.scale.linear().range([0, w]),
       
     4     y = d3.scale.linear().range([0, h - 40]);
       
     5 
       
     6 // An SVG element with a bottom-right origin.
       
     7 var svg = d3.select("#chart").append("svg:svg")
       
     8     .attr("width", w)
       
     9     .attr("height", h)
       
    10     .style("padding-right", "30px")
       
    11   .append("svg:g")
       
    12     .attr("transform", "translate(" + x(1) + "," + (h - 20) + ")scale(-1,-1)");
       
    13 
       
    14 // A sliding container to hold the bars.
       
    15 var body = svg.append("svg:g")
       
    16     .attr("transform", "translate(0,0)");
       
    17 
       
    18 // A container to hold the y-axis rules.
       
    19 var rules = svg.append("svg:g");
       
    20 
       
    21 // A label for the current year.
       
    22 var title = svg.append("svg:text")
       
    23     .attr("class", "title")
       
    24     .attr("dy", ".71em")
       
    25     .attr("transform", "translate(" + x(1) + "," + y(1) + ")scale(-1,-1)")
       
    26     .text(2000);
       
    27 
       
    28 d3.csv("population.csv", function(data) {
       
    29 
       
    30   // Convert strings to numbers.
       
    31   data.forEach(function(d) {
       
    32     d.people = +d.people;
       
    33     d.year = +d.year;
       
    34     d.age = +d.age;
       
    35   });
       
    36 
       
    37   // Compute the extent of the data set in age and years.
       
    38   var age0 = 0,
       
    39       age1 = d3.max(data, function(d) { return d.age; }),
       
    40       year0 = d3.min(data, function(d) { return d.year; }),
       
    41       year1 = d3.max(data, function(d) { return d.year; }),
       
    42       year = year1;
       
    43 
       
    44   // Update the scale domains.
       
    45   x.domain([0, age1 + 5]);
       
    46   y.domain([0, d3.max(data, function(d) { return d.people; })]);
       
    47 
       
    48   // Add rules to show the population values.
       
    49   rules = rules.selectAll(".rule")
       
    50       .data(y.ticks(10))
       
    51     .enter().append("svg:g")
       
    52       .attr("class", "rule")
       
    53       .attr("transform", function(d) { return "translate(0," + y(d) + ")"; });
       
    54 
       
    55   rules.append("svg:line")
       
    56       .attr("x2", w);
       
    57 
       
    58   rules.append("svg:text")
       
    59       .attr("x", 6)
       
    60       .attr("dy", ".35em")
       
    61       .attr("transform", "rotate(180)")
       
    62       .text(function(d) { return Math.round(d / 1e6) + "M"; });
       
    63 
       
    64   // Add labeled rects for each birthyear.
       
    65   var years = body.selectAll("g")
       
    66       .data(d3.range(year0 - age1, year1 + 5, 5))
       
    67     .enter().append("svg:g")
       
    68       .attr("transform", function(d) { return "translate(" + x(year1 - d) + ",0)"; });
       
    69 
       
    70   years.selectAll("rect")
       
    71       .data(d3.range(2))
       
    72     .enter().append("svg:rect")
       
    73       .attr("x", 1)
       
    74       .attr("width", x(5) - 2)
       
    75       .attr("height", 1e-6);
       
    76 
       
    77   years.append("svg:text")
       
    78       .attr("y", -6)
       
    79       .attr("x", -x(5) / 2)
       
    80       .attr("transform", "rotate(180)")
       
    81       .attr("text-anchor", "middle")
       
    82       .style("fill", "#fff")
       
    83       .text(String);
       
    84 
       
    85   // Add labels to show the age.
       
    86   svg.append("svg:g").selectAll("text")
       
    87       .data(d3.range(0, age1 + 5, 5))
       
    88     .enter().append("svg:text")
       
    89       .attr("text-anchor", "middle")
       
    90       .attr("transform", function(d) { return "translate(" + (x(d) + x(5) / 2) + ",-4)scale(-1,-1)"; })
       
    91       .attr("dy", ".71em")
       
    92       .text(String);
       
    93 
       
    94   // Nest by year then birthyear.
       
    95   data = d3.nest()
       
    96       .key(function(d) { return d.year; })
       
    97       .key(function(d) { return d.year - d.age; })
       
    98       .rollup(function(v) { return v.map(function(d) { return d.people; }); })
       
    99       .map(data);
       
   100 
       
   101   // Allow the arrow keys to change the displayed year.
       
   102   d3.select(window).on("keydown", function() {
       
   103     switch (d3.event.keyCode) {
       
   104       case 37: year = Math.max(year0, year - 10); break;
       
   105       case 39: year = Math.min(year1, year + 10); break;
       
   106     }
       
   107     redraw();
       
   108   });
       
   109 
       
   110   redraw();
       
   111 
       
   112   function redraw() {
       
   113     if (!(year in data)) return;
       
   114     title.text(year);
       
   115 
       
   116     body.transition()
       
   117         .duration(750)
       
   118         .attr("transform", function(d) { return "translate(" + x(year - year1) + ",0)"; });
       
   119 
       
   120     years.selectAll("rect")
       
   121         .data(function(d) { return data[year][d] || [0, 0]; })
       
   122       .transition()
       
   123         .duration(750)
       
   124         .attr("height", y);
       
   125   }
       
   126 });