Skip to content

Instantly share code, notes, and snippets.

@enactdev
Last active October 18, 2017 00:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enactdev/155f713a14086c2891fdf16c6613451e to your computer and use it in GitHub Desktop.
Save enactdev/155f713a14086c2891fdf16c6613451e to your computer and use it in GitHub Desktop.
Philly donations by zipcode

Philly donations by zipcode

A Shape file of the zipcodes was downloaded from the US Census

That was loaded into a MySQL database, and a GeoJSON file was created with the subset of zipcodes that lie within Philly.

Map was created with Leaflet and code was heavily borrowed from two of their tutorials:

Future example code
{"19102":{"num_donations":"34","amount_donated":"39684.54"},"19103":{"num_donations":"60","amount_donated":"43087.19"},"19104":{"num_donations":"17","amount_donated":"21795.00"},"19105":{"num_donations":"3","amount_donated":"330.00"},"19106":{"num_donations":"43","amount_donated":"9194.30"},"19107":{"num_donations":"57","amount_donated":"210790.92"},"19109":{"num_donations":"3","amount_donated":"1100.00"},"19111":{"num_donations":"1","amount_donated":"100.00"},"19112":{"num_donations":"1","amount_donated":"5000.00"},"19116":{"num_donations":"2","amount_donated":"250.00"},"19118":{"num_donations":"14","amount_donated":"4745.00"},"19119":{"num_donations":"79","amount_donated":"18916.52"},"19120":{"num_donations":"4","amount_donated":"2270.00"},"19121":{"num_donations":"1","amount_donated":"220.00"},"19122":{"num_donations":"2","amount_donated":"600.00"},"19123":{"num_donations":"6","amount_donated":"12520.00"},"19124":{"num_donations":"2","amount_donated":"750.00"},"19125":{"num_donations":"10","amount_donated":"4142.00"},"19126":{"num_donations":"1","amount_donated":"100.00"},"19127":{"num_donations":"7","amount_donated":"82390.00"},"19128":{"num_donations":"12","amount_donated":"6238.36"},"19129":{"num_donations":"5","amount_donated":"1304.00"},"19130":{"num_donations":"30","amount_donated":"27072.64"},"19131":{"num_donations":"4","amount_donated":"8250.00"},"19132":{"num_donations":"6","amount_donated":"1467.83"},"19133":{"num_donations":"3","amount_donated":"2200.00"},"19134":{"num_donations":"1","amount_donated":"1000.00"},"19135":{"num_donations":"2","amount_donated":"200.00"},"19138":{"num_donations":"2","amount_donated":"2054.00"},"19139":{"num_donations":"11","amount_donated":"4670.00"},"19140":{"num_donations":"3","amount_donated":"3075.00"},"19143":{"num_donations":"47","amount_donated":"18716.00"},"19144":{"num_donations":"18","amount_donated":"12130.68"},"19145":{"num_donations":"5","amount_donated":"15350.00"},"19146":{"num_donations":"44","amount_donated":"35661.41"},"19147":{"num_donations":"66","amount_donated":"30322.00"},"19148":{"num_donations":"24","amount_donated":"5882.17"},"19150":{"num_donations":"4","amount_donated":"7100.00"},"19151":{"num_donations":"1","amount_donated":"3000.00"},"19152":{"num_donations":"1","amount_donated":"100.00"},"19154":{"num_donations":"1","amount_donated":"11900.00"}}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Delaware 2016 election races.">
<title>Donations by Philadelphia Zipcode</title>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<!-- Load Leaflet from CDN -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css"
integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"
integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log=="
crossorigin=""></script>
<!-- Load Esri Leaflet from CDN -->
<script src="https://unpkg.com/esri-leaflet@2.1.1/dist/esri-leaflet.js"
integrity="sha512-ECQqaYZke9cSdqlFG08zSkudgrdF6I1d8ViSa7I3VIszJyVqw4ng1G8sehEXlumdMnFYfzY0tMgdQa4WCs9IUw=="
crossorigin=""></script>
<!-- load the latest release from the cdn automatically -->
<script src="https://unpkg.com/esri-leaflet-vector"></script>
<style>
#mapid_1 {
width: 600px;
height: 400px;
}
.info {
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
}
.info h4 {
margin: 0 0 5px;
color: #777;
}
.legend {
text-align: left;
line-height: 18px;
color: #555;
}
.legend i {
width: 18px;
height: 18px;
float: left;
margin-right: 8px;
opacity: 0.7;
}
</style>
</head>
<body>
<div id="layout">
<!-- Menu toggle -->
<a href="#menu" id="menuLink" class="menu-link">
<!-- Hamburger icon -->
<span></span>
</a>
<div id="main">
<div class="header">
<h1>Donations by Philadelphia Zipcode</h1>
</div>
<div class="content">
<div id="mapid_1"></div>
<script>
//alert(max_total_amount);
var max_num_contrib = 0;
var max_total_amount = 0;
var zipcode_map = L.map('mapid_1').setView([40.00, -75.11], 10);
var layer = L.esri.Vector.basemap('ModernAntique').addTo(zipcode_map);
// control that shows state info on hover
var info = L.control();
info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info');
this.update();
return this._div;
};
info.update = function (props) {
this._div.innerHTML = '<h4>Philly donations by zipcode</h4>' + (props ?
'<b>' + props.num_contrib + ' contributors donated ' + '$' + props.total_amount + ' from zipcode' + props.name + '</b><br />'
: 'Hover over a zipcode');
};
info.addTo(zipcode_map);
function mapRound(x){
return Math.ceil(x / 100.0) * 100
}
// get color depending on population density value
function getColor(d) {
return d > mapRound(0.90*max_total_amount) ? '#800026' :
//d > mapRound(0.75*max_total_amount) ? '#BD0026' :
d > mapRound(0.65*max_total_amount) ? '#E31A1C' :
//d > mapRound(0.45*max_total_amount) ? '#FC4E2A' :
d > mapRound(0.40*max_total_amount) ? '#FD8D3C' :
//d > mapRound(0.15*max_total_amount) ? '#FEB24C' :
d > mapRound(0.15*max_total_amount) ? '#FED976' :
d > 1 ? '#FFEDA0' :
'#FFFFFF';
}
function style(feature) {
return {
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7,
fillColor: getColor(feature.properties.total_amount)
};
}
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
color: '#666',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
info.update(layer.feature.properties);
}
var geojson;
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomToFeature(e) {
zipcode_map.fitBounds(e.target.getBounds());
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
//click: zoomToFeature
});
}
zipcode_map.attributionControl.addAttribution('Population data &copy; <a href="http://census.gov/">US Census Bureau</a>');
var legend = L.control({position: 'bottomright'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend'),
//grades = [0, mapRound(0.05*max_total_amount), mapRound(0.15*max_total_amount), mapRound(0.30*max_total_amount), mapRound(0.45*max_total_amount), mapRound(0.60*max_total_amount), mapRound(0.75*max_total_amount), mapRound(0.90*max_total_amount)],
grades = [0, 1, mapRound(0.15*max_total_amount), mapRound(0.40*max_total_amount), mapRound(0.65*max_total_amount), mapRound(0.90*max_total_amount)],
labels = [],
from, to;
for (var i = 0; i < grades.length; i++) {
from = grades[i];
to = grades[i + 1];
labels.push(
'<i style="background:' + getColor(from + 1) + '"></i> ' +
from + (to ? '&ndash;' + to : '+'));
}
div.innerHTML = labels.join('<br>');
return div;
};
</script>
<script>
$(document).ready(function() {
//alert( 'hi there dude.' );
//var combined_data = 'hi'
// Pull in zipcode data
$.getJSON( "pa_zipcode_geo.json", function() {
//console.log( "success" );
})
.done(function( district_data ) {
//console.log( "second success" );
//console.log(district_data)
// Pull in donation data by zipcode
$.getJSON( "donations.json", function() {
//console.log( "success 2" );
})
.done(function( donation_data ) {
//console.log( "second success 2" );
//console.log(donation_data)
//alert( combined_data );
for (i in district_data.features) {
//console.log(district_data.features[i])
// "name":"19962","zipcode":19962,"num_contrib":"8","total_amount":"3400.00"
district_data.features[i].properties.name = district_data.features[i].properties.ZCTA5CE10;
district_data.features[i].properties.zipcode = district_data.features[i].properties.ZCTA5CE10;
district_data.features[i].properties.num_contrib = 0;
district_data.features[i].properties.total_amount = 0;
if (district_data.features[i].properties.ZCTA5CE10 in donation_data) {
//console.log('found: '+district_data.features[i].properties.ZCTA5CE10)
key = district_data.features[i].properties.ZCTA5CE10
district_data.features[i].properties.num_contrib = donation_data[key].num_donations;
district_data.features[i].properties.total_amount = donation_data[key].amount_donated;
if ( max_num_contrib < donation_data[key].num_donations ) {
max_num_contrib = donation_data[key].num_donations;
}
//console.log('curr: '+max_total_amount+ ' & test: '+donation_data[key].amount_donated)
// Javascript doesn't like decimal notation ...
if ( parseInt(max_total_amount) < parseInt(donation_data[key].amount_donated) ) {
max_total_amount = donation_data[key].amount_donated;
}
}
else {
//console.log('missing: '+district_data.features[i].properties.DISTRICT)
}
}
//alert(max_total_amount);
geojson = L.geoJson(district_data, {
style: style,
onEachFeature: onEachFeature
}).addTo(zipcode_map);
legend.addTo(zipcode_map);
})
.fail(function() {
console.log( "error 2" );
})
.always(function() {
//console.log( "getJSON().always() 2" );
});
// End Pull in donation data by zipcode
})
.fail(function() {
console.log( "error" );
})
.always(function() {
//console.log( "getJSON().always()" );
});
// alert( 'by dude' );
} );
</script>
</div> <!-- /main -->
</div>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
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