// Set up the SVG
var svg_width = 1000;
var svg_height = 500;
var projection = d3.geoAlbersUsa();
var path = d3.geoPath().projection(projection);
// Generate an SVG element on the page
var svg = d3.select("#plot").append("svg")
.attr("width", svg_width)
.attr("height", svg_height);
// Keep track of county populations
var population = d3.map();
// Make a scale for colors
var colorScale = d3.scalePow().exponent(.75)
.range(['#0571c0', '#fff', '#e01c8b']);
// Defer our actual code until we have both the map and county data loaded
d3.queue()
.defer(d3.json, 'us.json')
.defer(d3.csv, 'county_facts.csv', function(d) {
// This code runs for each row of county_facts.csv
var county_id = parseInt(d.fips);
var value = parseInt(d.SEX255214);
// Exclude states and the whole county
if(county_id % 1000 != 0 && value != 0) {
population.set(county_id, (value - 50)/100);
}
})
.await(function(error, us) {
// This code runs when both data files are loaded
var min = d3.min(population.values());
var max = d3.max(population.values());
// Compute the range of values for the legend
var legend_max = Math.max(Math.abs(min), max);
var legend_min = -legend_max;
// Set the domain of the color scale
colorScale.domain([legend_min, 0, legend_max]);
// Create a scale to choose legend values
var legendScale = d3.scaleLinear().domain([0, 8]).range([legend_max, legend_min]);
// Generate a legend
for(var i=0; i<=8; i++) {
svg.append('rect')
.attr('x', svg_width - 100)
.attr('y', 100 + 30 * i)
.attr('width', 25)
.attr('height', 25)
.attr('stroke', '#000')
.attr('stroke-width', '0.5px')
.attr('fill', colorScale(legendScale(i)));
svg.append('text')
.attr('x', svg_width - 70)
.attr('y', 118 + 30 * i)
.attr('font-family', 'sans-serif')
.attr('font-size', '10pt')
.text(d3.format('+.1%')(legendScale(i)));
}
// Create land area
svg.append('path')
.datum(topojson.feature(us, us.objects.land))
.attr('class', 'land')
.attr('d', path);
// Generate counties and color them based on population
svg.append('g')
.attr('class', 'counties')
.selectAll('path')
.data(topojson.feature(us, us.objects.counties).features)
.enter()
.append('path')
.attr('fill', d => colorScale(population.get(d.id)))
.on('mouseover', d => console.log(d))
.attr('d', path);
// Create county boundaries
svg.append('path')
.datum(topojson.mesh(us, us.objects.counties))
.attr('class', 'county-boundary')
.attr('d', path);
// Create state boundaries
svg.append('path')
.datum(topojson.mesh(us, us.objects.states))
.attr('class', 'state-boundary')
.attr('d', path);
// Grinnell's location: 41.743409, -92.723246
var coordinates = projection([-92.723246, 41.743409]);
// Make a circle at Grinnell's location
svg.append('circle')
.attr('r', 4)
.attr('cx', coordinates[0])
.attr('cy', coordinates[1])
.attr('fill', 'none')
.attr('stroke', 'black')
.attr('stroke-width', '1.5');
});