Skip to content

Instantly share code, notes, and snippets.

@PatrickCLipscomb
Created March 3, 2017 16:18
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 PatrickCLipscomb/1febeba87a35723ec1851aa2dd2d90b2 to your computer and use it in GitHub Desktop.
Save PatrickCLipscomb/1febeba87a35723ec1851aa2dd2d90b2 to your computer and use it in GitHub Desktop.
// This code creates an interactive map with filtering and data visualization functionality. It is part of my personal Weird Map project. It uses the Google Maps JavaScript API and a geoJSON file that I have stored as a gist for the interactive data layer
// github: https://github.com/PatrickCLipscomb/Weird-Map
// heroku: https://weird-map.herokuapp.com/
// this will render the map with the seleceted location filter active or with the data layer present depending on user selection
$(document).on('turbolinks:load', function() {
$('.filter').each(function() {
var iD = $(this).attr('id').toString()
$('#' + iD).on('click', function() {
$('#the-switch').html(iD);
$('.filter').each(function() {
$(this).removeClass('active');
})
$(this).addClass('active');
initMap();
})
})
})
// creates the maps with the locations overlayed with listeners that will provide informative popups
var map;
function initMap() {
// sets the map style and initial location and zoom
map = new google.maps.Map(document.getElementById('map-box'), {
center: {lat: 45.5231, lng: -122.5965},
zoom: 11,
styles: [{"featureType":"all","stylers":[{"saturation":0},{"hue":"#e7ecf0"}]},{"featureType":"road","stylers":[{"saturation":-70}]},{"featureType":"transit","stylers":[{"visibility":"off"}]},{"featureType":"poi","stylers":[{"visibility":"off"}]},{"featureType":"water","stylers":[{"visibility":"simplified"},{"saturation":-60}]}]
});
// this places each location on the map according to the filter that has been selected
<% @locations.each do |location| %>
var filterVariable = $('#the-switch').html();
if ("<%=location.category%>" == filterVariable || filterVariable == "All") {
var infoWindow<%=location.id%>;
var marker<%=location.id%> = new google.maps.Marker({
position: {lat: <%=location.latitude.to_f %>, lng: <%=location.longitude.to_f %>},
map: map,
icon: "images/<%=location.category.downcase%>.png"
});
var contentString<%=location.id%> = '<a href="<%= location.website.to_s %>" target="_blank"><h3><%= location.name.to_s %></h3></a><br><%= location.description.to_s %><br> <em>Category: <%= location.category.to_s %></em> <br> <a href="<%= location.streetview.to_s %>" target="_blank">Street View</a> <br>';
//add info window to marker when clicked, close other info window when opening a new one
google.maps.event.addListener(marker<%=location.id%>, 'click', function() {
<% @locations.each do |loc_id| %>
if (infoWindow<%=loc_id.id%> !== void 0) {
infoWindow<%=loc_id.id%>.close();
}
<% end %>
infoWindow<%=location.id%> = new google.maps.InfoWindow({
content: contentString<%=location.id%>
});
infoWindow<%=location.id%>.open(map, marker<%=location.id%>);
});
marker<%=location.id%>.setMap(map);
}
<% end %>
// this triggers the data layer to be overlayed on the map
$('#Data').on('click', function() {
dataMap(map);
createLegend(map)
})
}
// creates the bars per neighborhood datalayer and the associated event listeners for an interactive experience that includes informative popups
function dataMap(map) {
var infoWindow = new google.maps.InfoWindow({
content: ""
});
var featureNumber = <%= Location.first.number_of_bars() %>
console.log(featureNumber)
console.log(getColor(featureNumber))
var neighborhood = new google.maps.Data();
neighborhood.loadGeoJson('https://gist.githubusercontent.com/PatrickCLipscomb/7ac440d386ddd14ac93004531c6bb8fe/raw/6bb2a4fc4229b3e6cb08471a24bdc9f2023647fa/portlandBars.json');
neighborhood.setStyle(function(feature) {
return {
fillColor: getColor(feature.getProperty('bars')),
fillOpacity: 0.8,
strokeColor: '#b3b3b3',
strokeWeight: 1,
zIndex: 1
};
});
neighborhood.addListener('mouseover', function(e) {
neighborhood.overrideStyle(e.feature, {
strokeColor: '#2a2a2a',
strokeWeight: 2,
zIndex: 2
});
});
neighborhood.addListener('mouseout', function(e) {
neighborhood.revertStyle();
});
neighborhood.addListener('click', function(e) {
console.log(e);
infoWindow.setContent('<div style="line-height:1.00;overflow:hidden;white-space:nowrap;">' +
e.feature.getProperty('name') + '<br> bars: ' +
e.feature.getProperty('bars') + '</div>');
var anchor = new google.maps.MVCObject();
anchor.set("position", e.latLng);
infoWindow.open(map, anchor);
});
neighborhood.setMap(map);
}
// sets the color for each neighborhood based on number of bars
function getColor(featureNumber) {
var colors = [
'#fee5d9',
'#fcae91',
'#fb6a4a',
'#de2d26',
'#a50f15'
];
return featureNumber >= 25 ? colors[4] :
featureNumber > 15 ? colors[3] :
featureNumber > 3 ? colors[2] :
featureNumber > 0 ? colors[1] :
colors[0];
}
// creates a floating legend in the bottom right corner of the map that correlates bars with colors
function createLegend(map) {
var div = document.createElement('div');
div.innerHTML = '<h4>Total Bars in Each Neighborhood</h4>' +
'<ul>' +
'<li><h5><div class="legend-color" id="zero"></div> = 0</h5></li>' +
'<li><h5><div class="legend-color" id="one"></div> = 1-3</h5></li>' +
'<li><h5><div class="legend-color" id="three"></div> = 3-15</h5></li>' +
'<li><h5><div class="legend-color" id="fifteen"></div> = 15-25</h5></li>' +
'<li><h5><div class="legend-color" id="twenty-five"></div> = more than 25</h5></li>';
$('#legend').empty();
$('#legend').append(div);
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].clear();
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(legend);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment