Last active
August 29, 2015 14:10
-
-
Save hotzeplotz/0199a17276be22465ad5 to your computer and use it in GitHub Desktop.
European MetroMonitor - Workshop
This file contains hidden or 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
| /** | |
| * Turn a CSV file with longitude and latitude columsn into a GeoJSON data structure | |
| */ | |
| function csv_to_geojson(csv_data) { | |
| var full_data = { | |
| type: "FeatureCollection", | |
| features: [] | |
| }; | |
| full_data.features = _.map(csv_data, | |
| function(city_row, key, list) { | |
| return { | |
| id: city_row.MetroRegion, | |
| properties: city_row, | |
| type: "Feature", | |
| geometry: { | |
| type: "Point", | |
| coordinates: [ | |
| city_row.Longitude, city_row.Latitude | |
| ] | |
| } | |
| }; | |
| }); | |
| return full_data; | |
| } | |
| /** | |
| * Prepare and build the map! | |
| */ | |
| function make_map(map_data) { | |
| L.mapbox.accessToken = 'pk.eyJ1IjoibHNlY2l0aWVzIiwiYSI6IjJ6ZjA5UGMifQ.8y1yiWucAic55wg5YoiTGQ'; | |
| var map = L.mapbox.map(map_data.map_id, 'lsecities.k37p4f29', { | |
| attributionControl: false, | |
| infoControl: true | |
| }) | |
| .setView(map_data.initial_position, map_data.initial_zoom), | |
| $metro_tooltip = $('.metro-tooltip'); | |
| /***** | |
| * Uncomment the following line to enable Leaflet-Hash */ | |
| // var hash = new L.Hash(map); | |
| /** | |
| * Show tooltip | |
| */ | |
| function enterLayer(){ | |
| var metroName = this.feature.properties.MetroRegion, | |
| val_at_timepoint = map_data.time_var_value_function(this.feature.properties[map_data.time_var]), | |
| val_growth = Math.round(this.feature.properties[map_data.growth_var] * 100) / 100; | |
| $metro_tooltip.html( | |
| '<h3>' + metroName + '</h3>' + | |
| '<dl>' + | |
| '<dt>' + map_data.time_var_label + '</dt>' + | |
| '<dd>' + val_at_timepoint + ' ' + map_data.time_var_unit + '</dd>' + | |
| '<dt>' + map_data.growth_var_label + '</dt>' + | |
| '<dd>' + val_growth + ' ' + map_data.growth_var_unit + '</dd>' + | |
| '</dl>' | |
| ).show(); | |
| this.bringToFront(); | |
| this.setStyle({ | |
| weight: 2, | |
| opacity: 1 | |
| }); | |
| } | |
| /** | |
| * Hide tooltip | |
| */ | |
| function leaveLayer(){ | |
| $metro_tooltip.hide(); | |
| this.bringToBack(); | |
| this.setStyle({ | |
| weight: 1, | |
| opacity: 0.7 | |
| }); | |
| } | |
| /** | |
| * Create a new layer with a special pointToLayer function | |
| * which is used to generate scaled points | |
| */ | |
| var citiesLayer = L.geoJson(null, { | |
| pointToLayer: scaledPoint, | |
| onEachFeature: function(feature, layer) { | |
| layer.on({ | |
| mouseover: enterLayer, | |
| mouseout: leaveLayer | |
| }); | |
| } | |
| }) | |
| .addTo(map); | |
| var fill; // attach function later within d3.json(); | |
| function citiesSize(feature) { | |
| return { radius: pointRadius(feature)}; | |
| } | |
| function pointColor(feature) { | |
| return fill(feature.properties[map_data.growth_var]); | |
| } | |
| function pointRadius(feature) { | |
| var val_value = +feature.properties[map_data.time_var]; | |
| return d3.scale.sqrt() | |
| .domain([0, 2e4]) | |
| .range([0, 20])(val_value) * 1.5; | |
| } | |
| function scaledPoint(feature, latlng) { | |
| return L.circleMarker(latlng, { | |
| radius: pointRadius(feature), | |
| fillColor: pointColor(feature), | |
| fillOpacity: 0.75, | |
| weight: 0.5, | |
| color: '#fff' | |
| }); | |
| } | |
| // Request our data and add it to the citiesLayer. | |
| d3.csv(map_data.data_file, function(err, csv_data) { | |
| var data = csv_to_geojson(csv_data); | |
| var min = d3.min(data.features.map(function(d) { return d.properties[map_data.growth_var]; })); | |
| var max = d3.max(data.features.map(function(d) { return d.properties[map_data.growth_var]; })); | |
| fill = map_data.circles_fill(min, max); | |
| citiesLayer.addData(data); | |
| }); | |
| } |
This file contains hidden or 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>European MetroMonitor</title> | |
| <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | |
| <!-- include MapBox stylesheet --> | |
| <link href='https://api.tiles.mapbox.com/mapbox.js/v2.1.4/mapbox.css' rel='stylesheet' /> | |
| <!-- include our own stylesheet --> | |
| <link href='style.css' rel='stylesheet' /> | |
| </head> | |
| <body> | |
| <div id='map' class='dark'></div> | |
| <div class="metro-tooltip"></div> | |
| <!-- include external libraries: MapBox, D3 and jQuery --> | |
| <script src='//api.tiles.mapbox.com/mapbox.js/v2.1.4/mapbox.js'></script> | |
| <script src='//cdnjs.cloudflare.com/ajax/libs/d3/3.4.6/d3.min.js' charset="utf-8"></script> | |
| <script src='//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js'></script> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> | |
| <!-- include our own JavaScript code --> | |
| <script src='data-visualization.js'></script> | |
| <script> | |
| make_map({ | |
| data_file: 'http://bl.ocks.org/hotzeplotz/raw/1bef0638b3ba0d2e01b5/43259ee8f3bae048cc42a4d94df33a9b77f3d532/dataset.csv', | |
| map_id: 'map', | |
| /***** | |
| * to change the initial centering of the map to a specific european city, | |
| * search for its latitude and longitude and update the initial_position | |
| * setting below; try your dream summer holiday destination! :) | |
| * e.g. google 'palermo lat lon' and use the values given by google, | |
| * rounding them to two decimal digits [ 38.11, 13.36 ]*/ | |
| initial_position: [51.51, 12.00], | |
| /***** | |
| * to start with a closer zoom, increase the initial_zoom setting below | |
| * to a value above 4 (e.g. try 6 or 7) */ | |
| initial_zoom: 4, | |
| /***** | |
| * to plot a variable other than POPTOTT_2012 (metro region's population in 2012) | |
| * for the radius of circles, choose one of the dataset's variables here: | |
| * https://gist.githubusercontent.com/hotzeplotz/1bef0638b3ba0d2e01b5/raw/variables.txt | |
| * and set it as time_var below; don't forget to update | |
| * time_var_label, time_var_unit and time_var_value_function time accordingly! */ | |
| time_var: 'POPTOTT_2012', | |
| time_var_label: 'Population (2012)', | |
| time_var_unit: 'million', | |
| time_var_value_function: function(val) { | |
| return (val / 1000).toFixed(2); | |
| }, | |
| time_var_extent: function(data, variable) { /* return [min, max] for variable across data */ }, | |
| /***** | |
| * to plot a variable other than EMP_2012_GR (metro region's employment growth rate in 2012) | |
| * for the colour of circles, choose one of the dataset's variables here: | |
| * https://gist.githubusercontent.com/hotzeplotz/1bef0638b3ba0d2e01b5/raw/variables.txt | |
| * and set it as growth_var below; don't forget to update | |
| * growth_var_label and growth_var_unit accordingly! */ | |
| growth_var: 'GVA_2012_GR', | |
| growth_var_label: 'GVA growth rate (2012)', | |
| growth_var_unit: '%', | |
| /***** | |
| * default circles_fill, as used in European MetroMonitor app | |
| */ | |
| // circles_fill: function(min, max) { | |
| // return d3.scale.linear() | |
| // .domain([-10, -5, 0, 5, 10]) | |
| // .range(["#2B83BA", "#ABDDA4", "#FFFFBF", "#FDAE61", "#D7191C"]); | |
| //} | |
| /***** | |
| * use the circle_fill setting below to only highlight which cities have | |
| * negative growth and which have positive growth for the given year | |
| */ | |
| circles_fill: function(min, max) { | |
| return d3.scale.threshold() | |
| .domain([ 0 ]) | |
| .range([ 'red', 'green']); | |
| } | |
| /***** | |
| * or - just for fun - colour circles according to latitude with the | |
| * circle_fill setting below; hint: you also need to set the | |
| * growth_var above to "Latitude" (mind the capital L) | |
| */ | |
| //circles_fill: function(min, max) { | |
| // return d3.scale.linear() | |
| // .domain([ 0, 90 ]) | |
| // .range([ 'red', 'blue']); | |
| //} | |
| /***** | |
| * use the circle_fill setting below to only highlight which cities have | |
| * negative growth and which have positive growth for the given year | |
| */ | |
| // circles_fill: function(min, max) { | |
| // return d3.scale.threshold() | |
| // .domain([ 0 ]) | |
| // .range([ 'red', 'green']); | |
| // } | |
| /***** | |
| * or use the circles_fill setting below for a different fill style; | |
| * try using http://colorbrewer2.org/ to generate a colour palette | |
| */ | |
| // circles_fill: function(min, max) { | |
| // return d3.scale.threshold() | |
| // .domain([ -10 , -5, 0, 5, 10 ]) | |
| // .range(['rgb(242,240,247)','rgb(203,201,226)','rgb(158,154,200)','rgb(117,107,177)','rgb(84,39,143)']); | |
| // } | |
| }); | |
| </script> | |
| </body> | |
| </html> |
This file contains hidden or 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; | |
| font-family: sans-serif; | |
| } | |
| #map { | |
| position:absolute; | |
| top:0; | |
| bottom:0; | |
| width:100%; | |
| } | |
| .metro-tooltip{ | |
| position: absolute; | |
| top: 2em; | |
| right: 1em; | |
| z-index: 6; | |
| background: rgba(0,0,0,.75); | |
| color: white; | |
| padding: .5em .75em; | |
| font-size: .85em; | |
| display: none; | |
| } | |
| .leaflet-tile-pane { | |
| opacity: 0.6; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment