Skip to content

Instantly share code, notes, and snippets.

@dmcglone
Forked from veltman/README.md
Created Oct 14, 2019
Embed
What would you like to do?
Redistricting

Old vs. new proposed North Carolina congressional districts, data via WRAL.

Polygons were pre-processed for gentler animation as follows:

  1. For each district, find the difference n in the number of vertices between the old and new district.
  2. Add n vertices to whichever one has fewer, evenly spaced along the existing polyline, so the old and new shape each have the same number of vertices (not great for performance).
  3. For each pair of old/new district, wind the old district around to minimize the sum of the squared distances between point index i in the old district and point index i in the new district.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
stroke-width: 1px;
stroke: #444;
}
text {
font: bold 64px sans-serif;
text-anchor: middle;
text-transform: uppercase;
}
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js"></script>
<script>
var width = 960,
height = 500;
var colors = d3.scale.category20().range();
d3.shuffle(colors);
var svg = d3.select("body").append("svg")
.attr("width",width)
.attr("height",height);
var projection = d3.geo.conicConformal()
.parallels([34 + 20 / 60, 36 + 10 / 60])
.rotate([79, -33 - 45 / 60])
.scale(6102.002295938357)
.translate([570.5880508434078,431.7927213940179]);
var path = d3.geo.path().projection(projection);
queue()
.defer(d3.json,"old.geojson")
.defer(d3.json,"new.geojson")
.await(function(err,oldDistricts,newDistricts){
var combined = oldDistricts.features.map(function(d,i){
return [d,newDistricts.features[i]].map(path);
});
var districts = svg.selectAll("path")
.data(combined)
.enter()
.append("path")
.attr("d",next)
.style("fill",function(d,i){
return colors[i];
});
var label = svg.append("text")
.datum(["Old","New"])
.text(next)
.attr("x",300)
.attr("y",400);
morph();
function morph() {
districts.transition()
.duration(3200)
.attr("d",next)
.each("end",function(d,i){
if (i === combined.length - 1) {
morph();
}
});
label.transition()
.duration(0)
.delay(3200 / 2)
.each("end",function(){
label.text(next);
});
}
});
function next(d) {
return d.reverse()[1];
}
</script>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment