block by pjsier 7c15c9ba785ef1f97508cafbd31ba836

Cook County Migration Sankey

Full Screen

index.html

<!DOCTYPE html>
<style>
body {
  font-family: Verdana, sans-serif;
  font-size: 12px;
}
path.county {
  fill: #bdbdbd;
}
path.link {
  fill: none;
}
path.link:hover {
  stroke-opacity: 1;
}

.county-borders {
  fill: none;
  stroke: #fff;
  stroke-width: 0.5px;
  stroke-linejoin: round;
  stroke-linecap: round;
  pointer-events: none;
}
</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script src="https://d3js.org/d3-queue.v3.min.js"></script>
<script>

// Add queue with defer, join csv with migration numbers to topojson FIPS (id attr on topo)
var svg = d3.select("svg");

var path = d3.geoPath();

function ready(error, us, migration) {
  if (error) throw error;
  // Pulled from https://bl.ocks.org/mbostock/4122298
  migration.forEach(function(d) { d.movers = +d.movers; });
  var color = d3.scaleQuantize()
    .domain([0, d3.max(migration, function(d) { return d.movers; })])
    .range(d3.schemeBuPu[6]);

  // Joining to migration fips if available, otherwise 0
  us.objects.counties.geometries.forEach(function(d) {
    var match = migration.filter(function(m) { return m.FIPS === d.id; });
    d.properties = {movers: 0};
    if (match.length) d.properties = match[0];
  });

  var cookCentroid = path.centroid(
    topojson.feature(us, us.objects.counties.geometries.filter(
      function(d) { return d.id === "17031"; }
    )[0])
  );
  
  // https://github.com/d3/d3-shape/issues/27
  function link(d) {
    c = path.centroid(d);
    return "M" + c[0] + "," + c[1]
        + "C" + (c[0] + cookCentroid[0]) / 2 + "," + c[1]
        + " " + (c[0] + cookCentroid[0]) / 2 + "," + cookCentroid[1]
        + " " + cookCentroid[0] + "," + cookCentroid[1];
  }
  
  var line = d3.line()
    .curve(d3.curveBasis)
    .x(function(d) { return d[0]; })
    .y(function(d) { return d[1]; });
  
  var features = topojson.feature(us, us.objects.counties).features;
  var g = svg.append("g").attr("class", "counties");
  
  var strokeScale = d3.scaleLinear()
    .range([0, 50])
    .domain(d3.extent(features, function(d) { return d.properties.movers; }));
  
  g.selectAll("path.county")
    .data(features).enter()
    .append("path")
      .attr("d", path)
      .attr("class", "county");
    
  g.append("path")
    .attr("class", "county-borders")
    .attr("d", path(topojson.mesh(us, us.objects.counties, function(a, b) { return a !== b; })));
    
  var legend = g.append("g")
    .attr("class", "legend")
    .attr("transform", "translate(700,500)");
    
  legend.append("rect")
    .attr("width", 225)
    .attr("height", 100)
    .attr("fill", "#9ecae1")
    .style("opacity", 0.5);
    
  legend.append("text")
    .attr("x", 10)
    .attr("y", 20)
    .attr("font-weight", "bold")
    .text("Cook County Migration");
  
  legend.append("text")
    .attr("x", 10)
    .attr("y", 50)
    .attr("id", "legendCounty")
    .text("Hover over a link");
    
  legend.append("text")
    .attr("x", 10)
    .attr("y", 70)
    .attr("id", "legendCount")
    .text("");
  legend.append("text")
    .attr("x", 10)
    .attr("y", 85)
    .attr("id", "cook")
    .text("");
    
  var linkFeatures = features.filter(function(d) { return d.properties.movers > 1000; });
  
  g.selectAll("path.link")
    .data(linkFeatures)
    .enter().append("path")
    .attr("d", link)
    .attr("class", "link")
    .attr("stroke", function(d) { return color(d.properties.movers); })
    .attr("stroke-width", function(d) { return strokeScale(d.properties.movers); })
    .attr("stroke-opacity", 0.6)
    .on("mouseover", function(d) { 
      d3.select("#legendCounty").text(d.properties.county + ", " + d.properties.state);
      d3.select("#legendCount").text(d3.format(",")(d.properties.movers) + " moved from");
      d3.select("#cook").text("Cook County");
    })
    .on("mouseout", function(d) { 
      d3.select("#legendCounty").text("Hover over a link");
      d3.select("#legendCount").text("");
      d3.select("#cook").text("");
    });
}

(function() {
  d3.queue()
    .defer(d3.json, "https://d3js.org/us-10m.v1.json")
    .defer(d3.csv, "cook_county_out_migration.csv")
    .await(ready)
})()
</script>