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

Feature/update maps #707

Merged
merged 4 commits into from
Sep 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"}]
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.