Last active
August 29, 2015 13:56
-
-
Save wboykinm/9035841 to your computer and use it in GitHub Desktop.
Leaflet Vectors and Nested Functions, Oh My!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset=utf-8 /> | |
<title>Sacramento Tree Foundation Map</title> | |
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' /> | |
<link href='https://api.tiles.mapbox.com/mapbox.js/v1.6.1/mapbox.css' rel='stylesheet' /> | |
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Rokkitt:400,700" /> | |
<link href='style.css' rel='stylesheet' /> | |
</head> | |
<body> | |
<ul id='map-ui'> | |
<li><a id="Percent_TC" class="lyr tree">% Tree Canopy</a></li> | |
<li><a id="mean_bmi" class="lyr health">Mean BMI</a></li> | |
<li><a id="per_ovw_ob" class="lyr health">% Overweight or Obese</a></li> | |
<li><a id="per_ob" class="lyr health">% Obese</a></li> | |
<li><a id="per_mvpa" class="lyr health active">% w/ >150min MVPA/wk</a></li> | |
<li><a id="per_hi_bp" class="lyr health">% w/ High Blood Pressure</a></li> | |
<li><a id="per_type2" class="lyr health">% w/ Type 2 Diabetes</a></li> | |
<li><a id="per_frpr" class="lyr health">% in Fair/Poor health</a></li> | |
<li><a id="per_asthma" class="lyr health">% w/ Asthma</a></li> | |
</ul> | |
<div id='map'></div> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> | |
<script src='http://api.tiles.mapbox.com/mapbox.js/v1.6.1/mapbox.js'></script> | |
<script src='//api.tiles.mapbox.com/mapbox.js/plugins/leaflet-hash/v0.2.1/leaflet-hash.js'></script> | |
<script src="http://d3js.org/topojson.v1.min.js"></script> | |
<script> | |
var mapdataviz, | |
popup, | |
zips_geojson, | |
zipsLayer; | |
// Creat wrapper function | |
$(function() { | |
// Create Data loading function, repeatable on page load and on button click | |
var loadData = function() { | |
// Create map | |
mapdataviz = L.mapbox.map('map', 'landplanner.map-khn9uycz').setView([38.574, -121.384], 10); | |
// Create Popup | |
popup = new L.Popup({ | |
autoPan: false | |
}); | |
var hash = L.hash(mapdataviz); | |
// ADD THE REFERENCE OVERLAY | |
var topPane = mapdataviz._createPane('leaflet-top-pane', mapdataviz.getPanes().mapPane); | |
var topLayer = new L.mapbox.tileLayer('sactree.h7id69df', { | |
maxZoom: 17, | |
opacity: 0.4 | |
}).addTo(mapdataviz); | |
topPane.appendChild(topLayer.getContainer()); | |
topLayer.setZIndex(7); | |
// Add and define the variables that carry theme info to the layer constructor | |
var actVar = $('a.active').attr('id'); | |
var actLayer = 'layer.feature.properties.' + actVar; | |
var actFeature = 'feature.properties.' + actVar; | |
//Get the topojson | |
$.getJSON('sactree_zips.json', function(data) { | |
console.log('json loaded!') | |
// Convert the topojson to geojson | |
zips_geojson = topojson.feature(data, data.objects.zips).features; | |
// Create leaflet vector layer and add it to the map | |
zipsLayer = L.geoJson(zips_geojson, { | |
style: getStyle, | |
onEachFeature: onEachFeature | |
}).addTo(mapdataviz); | |
// Define the vector styles | |
function getStyle(feature) { | |
return { | |
weight: 1, | |
opacity: 0.2, | |
color: 'black', | |
fillOpacity: 0.95, | |
fillColor: getColor(eval(actFeature)) | |
}; | |
} | |
// Define the polygon fill, conditional on theme and value | |
function getColor(d) { | |
if (actVar == 'Percent_TC') { | |
return d > 33 ? '#588125' | |
: d > 23 ? '#729B3F' | |
: d > 15 ? '#8BB458' | |
: d > 9 ? '#A5CE72' | |
: d > 4 ? '#BEE78B' | |
: d > 0.5 ? '#D7FFA4' | |
: '#fff'; | |
} | |
if (actVar == 'mean_bmi') { | |
return d > 31 ? '#4b75b3' | |
: d > 29 ? '#523494' | |
: d > 27 ? '#99a9c6' | |
: d > 25 ? '#bcc5cf' | |
: d > 22 ? '#dde1d8' | |
: d > 20 ? '#ffffe0' | |
: '#fff'; | |
} | |
else { | |
return d > 0.7 ? '#4b75b3' | |
: d > 0.5 ? '#523494' | |
: d > 0.4 ? '#99a9c6' | |
: d > 0.25 ? '#bcc5cf' | |
: d > 0.1 ? '#dde1d8' | |
: d > 0.02 ? '#ffffe0' | |
: '#fff'; | |
} | |
} | |
// Define the interactivity | |
function onEachFeature(feature, layer) { | |
layer.on({ | |
mousemove: mousemove, | |
mouseout: mouseout, | |
click: zoomToFeature | |
}); | |
} | |
var closeTooltip; | |
// Define the popup content, also conditional on theme and value | |
function mousemove(e) { | |
var layer = e.target; | |
popup.setLatLng(e.latlng); | |
if (actVar == 'Percent_TC' || actVar == 'mean_bmi') { | |
popup.setContent('<div class="marker-title">' + layer.feature.properties.NAME + ' - ' + layer.feature.properties.ID + '</div>' + $('.active').text() + ": <b>" + Math.round(eval(actLayer)).toFixed(0) + "</b>"); | |
} | |
else { | |
popup.setContent('<div class="marker-title">' + layer.feature.properties.NAME + ' - ' + layer.feature.properties.ID + '</div>' + Math.round(eval(actLayer) * 100).toFixed(0) + $('.active').text()); | |
} | |
if (!popup._map) popup.openOn(mapdataviz); | |
window.clearTimeout(closeTooltip); | |
// highlight feature on mouseover | |
layer.setStyle({ | |
weight: 3, | |
opacity: 0.3, | |
fillOpacity: 0.3 | |
}); | |
if (!L.Browser.ie && !L.Browser.opera) { | |
layer.bringToFront(); | |
} | |
} | |
function mouseout(e) { | |
zipsLayer.resetStyle(e.target); | |
closeTooltip = window.setTimeout(function() { | |
mapdataviz.closePopup(); | |
}, 100); | |
} | |
function zoomToFeature(e) { | |
mapdataviz.fitBounds(e.target.getBounds()); | |
} | |
}); | |
}; | |
// Define the reload-on-click function | |
$('.lyr').click(function () { | |
$('.lyr').removeClass('active'); | |
// todo - remove old polygons before reload: | |
mapdataviz.removeLayer(zipsLayer); | |
$(this).addClass('active'); | |
// Redefine the theme variables based on the clicked button | |
actVar = $(this).attr('id'); | |
actLayer = 'layer.feature.properties.' + actVar; | |
actFeature = 'feature.properties.' + actVar; | |
// Fire the big data loading function | |
loadData(); | |
}); | |
// init | |
loadData(); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
margin: 0; | |
padding: 0; | |
border: 0; | |
font-size: 100%; | |
font: normal 18px/25px 'Rokkitt', Georgia, serif; | |
vertical-align: baseline; | |
} | |
#map { position:absolute; top:0; bottom:0; width:100%; } | |
.map-legend .swatch { | |
width:20px; | |
height:20px; | |
float:left; | |
margin-right:10px; | |
} | |
.leaflet-popup-close-button { | |
display: none; | |
} | |
.leaflet-popup-content-wrapper { | |
pointer-events: none; | |
} | |
.leaflet-top-pane { | |
pointer-events: none; | |
} | |
#map-ui { | |
position: absolute; | |
top: 15px; | |
right: 10px; | |
list-style: none; | |
margin: 0; | |
padding: 10px; | |
z-index: 100; | |
background-color: rgba(255,255,255,0.8); | |
border: 2px solid #BBB; | |
} | |
#map-ui a { | |
color: #E5EFD4; | |
display: block; | |
margin: 0; | |
padding: 0; | |
border-radius: 6px; | |
min-width: 105px; | |
padding: 10px; | |
text-decoration: none; | |
text-transform: uppercase; | |
text-align: center; | |
border: 1px solid #fff; | |
} | |
#map-ui a.tree { | |
background-color: #729B3F; | |
} | |
#map-ui a.health { | |
background-color: #4B75B3; | |
} | |
#map-ui a:hover { | |
opacity: 0.8; | |
filter: alpha(opacity=80); | |
border-color: #FFF; | |
} | |
#map-ui a.active { | |
opacity: 0.6; | |
filter: alpha(opacity=60); | |
border: 2px solid #333; | |
color: #fff; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment