block by enjalot fe88df78ff6982c11cb92002b7410d84

town population changes

Full Screen

Adapting Kai‘s parallel coordinates from this example. Built with blockbuilder.org

index.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="d3parcoords.css">
  <link rel="stylesheet" type="text/css" href="style.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
  <script src="d3parcoords.js"></script>
  <script src="divgrid.js"></script>
  <style>
    body { margin:0;padding:10px;position:fixed;top:0;right:0;bottom:0;left:0; }


/* data table styles */
#grid { height: 198px; }
.row, .header { clear: left; font-size: 12px; line-height: 18px; height: 18px; }
.row:nth-child(odd) { background: rgba(0,0,0,0.05); }
.header { font-weight: bold; }
.cell { float: left; overflow: hidden; white-space: nowrap; width: 70px; height: 18px; }
    .col-11 { width: 100px }
</style>
</head>

<body>
  
  <div id="towns" class="parcoords" style="height:200px;"></div>
  <div id="grid"></div>
  <script>
    var blue_to_brown = d3.scale.linear()
      .domain([9, 50])
      .range(["steelblue", "brown"])
      .interpolate(d3.interpolateLab);

    var color = function(d) { return blue_to_brown(10); };

    var parcoords = d3.parcoords()("#towns")
      .color(color)
      .alpha(0.4);

    // load csv file and create the chart
    var maxPop = 5000;
    d3.csv('census-2000-2010-cities-and-towns.csv', function(data) {
      console.log(data[0], data[1])
      var rows = [];
      data.slice(0, 100).forEach(function(d){
        if(d.SUMLEV !== "162") return; //only want cities & towns
        var row = {
          name: d.NAME
        }
        d3.range(2000, 2011).forEach(function(year) {
          row[year] = +d['POPESTIMATE' + year]
        })
        if(row[2000] > maxPop || row[2010] > maxPop) return;
        rows.push(row)
      })
      console.log("rows", rows)
      
      parcoords
        .data(rows)
        .hideAxis(["name"])
        .render()
        .brushMode("1D-axes");  // enable brushing

      // create data table, row hover highlighting
      var grid = d3.divgrid();
      d3.select("#grid")
        .datum(rows.slice(0,10))
        .call(grid)
        .selectAll(".row")
        .on({
          "mouseover": function(d) { parcoords.highlight([d]) },
          "mouseout": parcoords.unhighlight
        });

      // update data table on brush event
      parcoords.on("brush", function(d) {
        d3.select("#grid")
          .datum(d.slice(0,10))
          .call(grid)
          .selectAll(".row")
          .on({
            "mouseover": function(d) { parcoords.highlight([d]) },
            "mouseout": parcoords.unhighlight
          });
      });
    });
  </script>
</body>

d3parcoords.css

.parcoords > svg, .parcoords > canvas { 
  font: 14px sans-serif;
  position: absolute;
}
.parcoords > canvas {
  pointer-events: none;
}

.parcoords text.label {
  cursor: default;
}

.parcoords rect.background {
  fill: transparent;
}
.parcoords rect.background:hover {
  fill: rgba(120,120,120,0.2);
}
.parcoords .resize rect {
  fill: rgba(0,0,0,0.1);
}
.parcoords rect.extent {
  fill: rgba(255,255,255,0.25);
  stroke: rgba(0,0,0,0.6);
}
.parcoords .axis line, .parcoords .axis path {
  fill: none;
  stroke: #222;
  shape-rendering: crispEdges;
}
.parcoords canvas {
  opacity: 1;
  -moz-transition: opacity 0.3s;
  -webkit-transition: opacity 0.3s;
  -o-transition: opacity 0.3s;
}
.parcoords canvas.faded {
  opacity: 0.25;
}
.parcoords {
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	-khtml-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
    background-color: white;
}

divgrid.js

// http://bl.ocks.org/3687826
d3.divgrid = function(config) {
  var columns = [];

  var dg = function(selection) {
    if (columns.length == 0) columns = d3.keys(selection.data()[0][0]);

    // header
    selection.selectAll(".header")
        .data([true])
      .enter().append("div")
        .attr("class", "header")

    var header = selection.select(".header")
      .selectAll(".cell")
      .data(columns);

    header.enter().append("div")
      .attr("class", function(d,i) { return "col-" + i; })
      .classed("cell", true)

    selection.selectAll(".header .cell")
      .text(function(d) { return d; });

    header.exit().remove();

    // rows
    var rows = selection.selectAll(".row")
        .data(function(d) { return d; })

    rows.enter().append("div")
        .attr("class", "row")

    rows.exit().remove();

    var cells = selection.selectAll(".row").selectAll(".cell")
        .data(function(d) { return columns.map(function(col){return d[col];}) })

    // cells
    cells.enter().append("div")
      .attr("class", function(d,i) { return "col-" + i; })
      .classed("cell", true)

    cells.exit().remove();

    selection.selectAll(".cell")
      .text(function(d) { return d; });

    return dg;
  };

  dg.columns = function(_) {
    if (!arguments.length) return columns;
    columns = _;
    return this;
  };

  return dg;
};

style.css

body {
  font-size: 14px;
  font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
  margin: 24px;
  background: #fcfcfc;
  line-height: 1.45em;
}
a {
  color: #555;
}
a:hover {
  color: #000;
}
ul {
  margin: 0 20px;
  padding: 0;
}
.dark {
  background: #222;
}
p {
  width: 560px;
}
pre {
  color: #444;
  font-family: Ubuntu Mono, Monaco, monospace;
  padding: 4px 8px;
  background: #f2f2f2;
  border: 1px solid #ccc;
}
h1 small {
  font-weight: normal;
  font-size: 0.5em;
}
h3 {
  margin-top: 40px;
}
.float {
  float: left;
}
.centered {
  text-align: center;
}
.hide {
  display: none;
}
input {
  font-size: 16px;
}