Skip to content
This repository has been archived by the owner on Dec 23, 2017. It is now read-only.

Commit

Permalink
Merge pull request #707 from jmcarp/feature/update-maps
Browse files Browse the repository at this point in the history
Feature/update maps
  • Loading branch information
Noah Manger committed Sep 22, 2015
2 parents af79864 + 2a42d9a commit 725f549
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 97 deletions.
File renamed without changes.
7 changes: 7 additions & 0 deletions static/js/data/notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Data Sources

* US states
* Build from Census data using https://github.com/mbostock/us-atlas

* FIPS state codes
* http://www2.census.gov/geo/docs/reference/state.txt
1 change: 1 addition & 0 deletions static/js/data/state.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"STATE": "01", "STUSAB": "AL", "STATE_NAME": "Alabama", "STATENS": "01779775"}, {"STATE": "02", "STUSAB": "AK", "STATE_NAME": "Alaska", "STATENS": "01785533"}, {"STATE": "04", "STUSAB": "AZ", "STATE_NAME": "Arizona", "STATENS": "01779777"}, {"STATE": "05", "STUSAB": "AR", "STATE_NAME": "Arkansas", "STATENS": "00068085"}, {"STATE": "06", "STUSAB": "CA", "STATE_NAME": "California", "STATENS": "01779778"}, {"STATE": "08", "STUSAB": "CO", "STATE_NAME": "Colorado", "STATENS": "01779779"}, {"STATE": "09", "STUSAB": "CT", "STATE_NAME": "Connecticut", "STATENS": "01779780"}, {"STATE": "10", "STUSAB": "DE", "STATE_NAME": "Delaware", "STATENS": "01779781"}, {"STATE": "11", "STUSAB": "DC", "STATE_NAME": "District of Columbia", "STATENS": "01702382"}, {"STATE": "12", "STUSAB": "FL", "STATE_NAME": "Florida", "STATENS": "00294478"}, {"STATE": "13", "STUSAB": "GA", "STATE_NAME": "Georgia", "STATENS": "01705317"}, {"STATE": "15", "STUSAB": "HI", "STATE_NAME": "Hawaii", "STATENS": "01779782"}, {"STATE": "16", "STUSAB": "ID", "STATE_NAME": "Idaho", "STATENS": "01779783"}, {"STATE": "17", "STUSAB": "IL", "STATE_NAME": "Illinois", "STATENS": "01779784"}, {"STATE": "18", "STUSAB": "IN", "STATE_NAME": "Indiana", "STATENS": "00448508"}, {"STATE": "19", "STUSAB": "IA", "STATE_NAME": "Iowa", "STATENS": "01779785"}, {"STATE": "20", "STUSAB": "KS", "STATE_NAME": "Kansas", "STATENS": "00481813"}, {"STATE": "21", "STUSAB": "KY", "STATE_NAME": "Kentucky", "STATENS": "01779786"}, {"STATE": "22", "STUSAB": "LA", "STATE_NAME": "Louisiana", "STATENS": "01629543"}, {"STATE": "23", "STUSAB": "ME", "STATE_NAME": "Maine", "STATENS": "01779787"}, {"STATE": "24", "STUSAB": "MD", "STATE_NAME": "Maryland", "STATENS": "01714934"}, {"STATE": "25", "STUSAB": "MA", "STATE_NAME": "Massachusetts", "STATENS": "00606926"}, {"STATE": "26", "STUSAB": "MI", "STATE_NAME": "Michigan", "STATENS": "01779789"}, {"STATE": "27", "STUSAB": "MN", "STATE_NAME": "Minnesota", "STATENS": "00662849"}, {"STATE": "28", "STUSAB": "MS", "STATE_NAME": "Mississippi", "STATENS": "01779790"}, {"STATE": "29", "STUSAB": "MO", "STATE_NAME": "Missouri", "STATENS": "01779791"}, {"STATE": "30", "STUSAB": "MT", "STATE_NAME": "Montana", "STATENS": "00767982"}, {"STATE": "31", "STUSAB": "NE", "STATE_NAME": "Nebraska", "STATENS": "01779792"}, {"STATE": "32", "STUSAB": "NV", "STATE_NAME": "Nevada", "STATENS": "01779793"}, {"STATE": "33", "STUSAB": "NH", "STATE_NAME": "New Hampshire", "STATENS": "01779794"}, {"STATE": "34", "STUSAB": "NJ", "STATE_NAME": "New Jersey", "STATENS": "01779795"}, {"STATE": "35", "STUSAB": "NM", "STATE_NAME": "New Mexico", "STATENS": "00897535"}, {"STATE": "36", "STUSAB": "NY", "STATE_NAME": "New York", "STATENS": "01779796"}, {"STATE": "37", "STUSAB": "NC", "STATE_NAME": "North Carolina", "STATENS": "01027616"}, {"STATE": "38", "STUSAB": "ND", "STATE_NAME": "North Dakota", "STATENS": "01779797"}, {"STATE": "39", "STUSAB": "OH", "STATE_NAME": "Ohio", "STATENS": "01085497"}, {"STATE": "40", "STUSAB": "OK", "STATE_NAME": "Oklahoma", "STATENS": "01102857"}, {"STATE": "41", "STUSAB": "OR", "STATE_NAME": "Oregon", "STATENS": "01155107"}, {"STATE": "42", "STUSAB": "PA", "STATE_NAME": "Pennsylvania", "STATENS": "01779798"}, {"STATE": "44", "STUSAB": "RI", "STATE_NAME": "Rhode Island", "STATENS": "01219835"}, {"STATE": "45", "STUSAB": "SC", "STATE_NAME": "South Carolina", "STATENS": "01779799"}, {"STATE": "46", "STUSAB": "SD", "STATE_NAME": "South Dakota", "STATENS": "01785534"}, {"STATE": "47", "STUSAB": "TN", "STATE_NAME": "Tennessee", "STATENS": "01325873"}, {"STATE": "48", "STUSAB": "TX", "STATE_NAME": "Texas", "STATENS": "01779801"}, {"STATE": "49", "STUSAB": "UT", "STATE_NAME": "Utah", "STATENS": "01455989"}, {"STATE": "50", "STUSAB": "VT", "STATE_NAME": "Vermont", "STATENS": "01779802"}, {"STATE": "51", "STUSAB": "VA", "STATE_NAME": "Virginia", "STATENS": "01779803"}, {"STATE": "53", "STUSAB": "WA", "STATE_NAME": "Washington", "STATENS": "01779804"}, {"STATE": "54", "STUSAB": "WV", "STATE_NAME": "West Virginia", "STATENS": "01779805"}, {"STATE": "55", "STUSAB": "WI", "STATE_NAME": "Wisconsin", "STATENS": "01779806"}, {"STATE": "56", "STUSAB": "WY", "STATE_NAME": "Wyoming", "STATENS": "01779807"}, {"STATE": "60", "STUSAB": "AS", "STATE_NAME": "American Samoa", "STATENS": "01802701"}, {"STATE": "66", "STUSAB": "GU", "STATE_NAME": "Guam", "STATENS": "01802705"}, {"STATE": "69", "STUSAB": "MP", "STATE_NAME": "Northern Mariana Islands", "STATENS": "01779809"}, {"STATE": "72", "STUSAB": "PR", "STATE_NAME": "Puerto Rico", "STATENS": "01779808"}, {"STATE": "74", "STUSAB": "UM", "STATE_NAME": "U.S. Minor Outlying Islands", "STATENS": "01878752"}, {"STATE": "78", "STUSAB": "VI", "STATE_NAME": "U.S. Virgin Islands", "STATENS": "01802710"}]
File renamed without changes.
1 change: 1 addition & 0 deletions static/js/data/us-states-10m.json

Large diffs are not rendered by default.

57 changes: 0 additions & 57 deletions static/js/fips.json

This file was deleted.

38 changes: 22 additions & 16 deletions static/js/modules/election-lookup.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ require('leaflet-providers');
var helpers = require('./helpers');
var utils = require('./election-utils');

var states = require('../us.json');
var districts = require('../stateDistricts.json');
var states = require('../data/us-states-10m.json');
var districts = require('../data/stateDistricts.json');

var stateFeatures = topojson.feature(states, states.objects.units).features;
var stateFeatures = topojson.feature(states, states.objects.states).features;

var districtTemplate = require('../../templates/districts.hbs');
var resultTemplate = require('../../templates/electionResult.hbs');
Expand Down Expand Up @@ -173,11 +173,6 @@ ElectionLookup.prototype.init = function() {
this.$resultsItems = this.$elm.find('.results-items');
this.$resultsTitle = this.$elm.find('.results-title');

this.$map = $('.election-map');
this.map = new ElectionLookupMap(this.$map.get(0), {
handleSelect: this.handleSelectMap.bind(this)
});

this.$zip.on('change', this.handleZipChange.bind(this));
this.$state.on('change', this.handleStateChange.bind(this));
this.$form.on('change', 'input,select', this.search.bind(this));
Expand All @@ -186,6 +181,12 @@ ElectionLookup.prototype.init = function() {

this.handleStateChange();
this.handlePopState();

this.$map = $('.election-map');
this.map = new ElectionLookupMap(this.$map.get(0), {
drawStates: _.isEmpty(this.serialized),
handleSelect: this.handleSelectMap.bind(this)
});
};

ElectionLookup.prototype.handleSelectMap = function(state, district) {
Expand Down Expand Up @@ -367,10 +368,11 @@ ElectionLookupMap.prototype.init = function() {
this.overlay = null;
this.districts = null;
this.map = L.map(this.elm);
this.map.on('zoomend', this.handleZoom.bind(this));
this.map.on('viewreset', this.handleReset.bind(this));
L.tileLayer.provider('Stamen.TonerLite').addTo(this.map);
this.map.setView([37.8, -96], 3);
this.drawStates();
if (this.opts.drawStates) {
this.map.setView([37.8, -96], 3);
}
};

ElectionLookupMap.prototype.drawStates = function() {
Expand Down Expand Up @@ -403,9 +405,10 @@ ElectionLookupMap.prototype.drawDistricts = function(districts) {
};

ElectionLookupMap.prototype.updateBounds = function(districts) {
var rule = _.find(boundsOverrides, function(rule, district) {
var rule = districts && _.find(boundsOverrides, function(rule, district) {
return districts.indexOf(parseInt(district)) !== -1;
});
this._viewReset = !!(rule || districts);
if (rule) {
this.map.setView(rule.coords, rule.zoom);
}
Expand Down Expand Up @@ -440,14 +443,13 @@ ElectionLookupMap.prototype.filterDistricts = function(districts) {

ElectionLookupMap.prototype.handleStateClick = function(e) {
if (this.opts.handleSelect) {
var state = utils.decodeState(e.target.feature.id.substring(2, 4));
var state = utils.decodeState(e.target.feature.id);
this.opts.handleSelect(state);
}
};

ElectionLookupMap.prototype.onEachState = function(feature, layer) {
var state = parseInt(feature.id.substring(2, 4));
var color = this.statePalette[state % this.statePalette.length];
var color = this.statePalette[feature.id % this.statePalette.length];
layer.setStyle({color: color});
layer.on('click', this.handleStateClick.bind(this));
};
Expand All @@ -470,7 +472,11 @@ ElectionLookupMap.prototype.handleDistrictClick = function(e) {
}
};

ElectionLookupMap.prototype.handleZoom = function(e) {
ElectionLookupMap.prototype.handleReset = function(e) {
if (this._viewReset) {
this._viewReset = false;
return;
}
var zoom = e.target.getZoom();
if (zoom <= STATE_ZOOM_THRESHOLD) {
this.drawStates();
Expand Down
12 changes: 5 additions & 7 deletions static/js/modules/election-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,25 @@ var topojson = require('topojson');
var s = require('underscore.string');
_.mixin(s.exports());

var fips = require('../fips.json');
var fipsInverse = _.invert(fips);
var fips = require('./fips');

var districts = require('../districts.json');
var districts = require('../data/districts.json');
var districtFeatures = topojson.feature(districts, districts.objects.districts);

function encodeDistrict(state, district) {
return parseInt(fips[state.toUpperCase()]) * 100 + (parseInt(district) || 0);
return fips.fipsByState[state.toUpperCase()].STATE * 100 + (parseInt(district) || 0);
}

function decodeDistrict(district) {
district = _.sprintf('%04d', district);
return {
state: fipsInverse[district.substring(0, 2)],
state: fips.fipsByCode[parseInt(district.substring(0, 2))].STUSAB,
district: parseInt(district.substring(2, 4))
};
}

function decodeState(state) {
state = _.sprintf('%02d', parseInt(state));
return fipsInverse[state];
return fips.fipsByCode[parseInt(state)].STUSAB;
}

function truncate(value, digits) {
Expand Down
29 changes: 29 additions & 0 deletions static/js/modules/fips.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

/* global require, module */

var _ = require('underscore');

function byField(values, key) {
var getter = typeof key === 'function' ?
key :
function(val) {
return val[key];
};
return _.reduce(values, function(acc, val) {
acc[getter(val)] = val;
return acc;
}, {});
}

var fips = _.each(require('../data/state.json'), function(row) {
row.STATE = parseInt(row.STATE);
});
var fipsByCode = byField(fips, 'STATE');
var fipsByState = byField(fips, 'STUSAB');

module.exports = {
fips: fips,
fipsByCode: fipsByCode,
fipsByState: fipsByState
};
29 changes: 13 additions & 16 deletions static/js/modules/maps.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,16 @@ require('leaflet-providers');

var events = require('fec-style/js/events');

var fips = require('./fips');
var helpers = require('./helpers');
var utils = require('./election-utils');

var states = require('../us.json');
var states = require('../data/us-states-10m.json');

var districts = require('../districts.json');
var districts = require('../data/districts.json');
var districtFeatures = topojson.feature(districts, districts.objects.districts);

var stateFeatures = topojson.feature(states, states.objects.units).features;
var stateFeatureMap = _.chain(stateFeatures)
.map(function(feature) {
return [feature.properties.name, feature];
})
.object()
.value();
var stateFeatures = topojson.feature(states, states.objects.states).features;

var compactRules = [
['B', 9],
Expand Down Expand Up @@ -66,7 +61,9 @@ function stateMap($elm, data, width, height, min, max, addLegend, addTooltips) {
var results = _.reduce(
data.results,
function(acc, val) {
acc[val.state_full] = val.total;
var row = fips.fipsByState[val.state] || {};
var code = row.STATE ? parseInt(row.STATE) : null;
acc[code] = val.total;
return acc;
},
{}
Expand All @@ -87,15 +84,15 @@ function stateMap($elm, data, width, height, min, max, addLegend, addTooltips) {
.data(stateFeatures)
.enter().append('path')
.attr('fill', function(d) {
return scale(results[d.properties.name] || 0);
return scale(results[d.id] || 0);
})
.attr('data-state', function(d) {
return d.properties.name;
return fips.fipsByCode[d.id].STATE_NAME;
})
.attr('class', 'shape')
.attr('d', path)
.on('mouseover', function(d) {
if (results[d.properties.name]) {
if (results[d.id]) {
this.parentNode.appendChild(this);
this.classList.add('state--hover');
}
Expand Down Expand Up @@ -165,8 +162,8 @@ function stateTooltips(svg, path, results) {
this.parentNode.appendChild(this);
var offset = $(this).offset();
var html = tooltipTemplate({
name: d.properties.name,
total: helpers.currency(results[d.properties.name] || 0)
name: fips.fipsByCode[d.id].STATE_NAME,
total: helpers.currency(results[d.id] || 0)
});
tooltip
.style('display', 'block')
Expand Down Expand Up @@ -203,7 +200,7 @@ DistrictMap.prototype.load = function(election) {
var encoded = utils.encodeDistrict(election.state, election.district);
feature = utils.findDistrict(encoded);
} else {
feature = stateFeatureMap[election.stateFull];
feature = fipsByState[parseInt(election.state)];
}
feature && this.render(feature);
};
Expand Down
1 change: 0 additions & 1 deletion static/js/us.json

This file was deleted.

0 comments on commit 725f549

Please sign in to comment.