Published
Edited
Jul 27, 2022
Insert cell
# Leaflet Map 🍃🗺
Insert cell
map = {

// Variables that set the scope of the map view
const { lat, lng, z } = mapConfig;

//Creating Container DOM
let container = DOM.element('div', { style: `width:${1000}px;height:${width/1.6}px` });
d3.select(container).classed('info')
yield container;
// Now we create a map object and add a layer to it.
let map = L.map(container, { scrollWheelZoom: false }).setView([lat, lng], z);
let osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

//adding the GeoJson Overlay for the choropleth map
const statesLayer = L.geoJson(merged_data, {
style: style,
onEachFeature
}).addTo(map);

function style(feature) {
return {
fillColor: getColor(feature.properties.Q_Val),
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7
};
}

function getColor(d) {
return d > Levels[6] ? '#800026' :
d > Levels[5] ? '#BD0026' :
d > Levels[4] ? '#E31A1C' :
d > Levels[3] ? '#FC4E2A' :
d > Levels[2] ? '#FD8D3C' :
d > Levels[1] ? '#FEB24C' :
d > Levels[0] ? '#FED976' :
'#FFEDA0';
}

//Listeners
var geojson;

//Highlights the states on the map (Used on mouseover)
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();
}

};

// Resets states after highlight (Used on Mouse out)
function resetHighlight(e) {
geojson.resetStyle(e.target);
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
//wrapper function to apply events to states
function onEachFeature(feature, layer) {
// layer.bindTooltip(feature.properties.NAME + ": \n" + feature.properties.Q_Val + "KJ/m^2").openTooltip();
layer.bindTooltip("<div style='background:white; padding:1px 3px 1px 3px'><b>" + feature.properties.NAME + "</b><br>" +
toolTip_title[0] + ": " + feature.properties.Q_Val + toolTip_title[1] + "</div>",
{
direction: 'right',
permanent: false,
sticky: true,
offset: [10, 0],
opacity: 0.95,
className: 'leaflet-tooltip-own'
});
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
}

//Adding elements to states on event calls
geojson = L.geoJson(merged_data, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);



}
Insert cell
Insert cell
merged_data = mergeData(map_data, quantitative_data)
Insert cell
// Ideally this will be passed in through python
map_data = FileAttachment("gz_2010_us_040_00_20m.json").json()
Insert cell
// Also passed in through python
quantitative_data = FileAttachment("Sunshine_Data.csv").csv({typed : true})
Insert cell
// name of the column containing state names in the Quant_data
ID_Column = "State"
Insert cell
Quant_Column = "averageAnnualSunlight"
Insert cell
mapConfig =({
lat: 40,
lng: -97,
z: 4
})
Insert cell
Levels = [3000, 4000, 4500, 5250, 5500, 5750, 6000]
Insert cell
toolTip_title = ["Annual Solar Energy", "KJ/m^2"]
Insert cell
Insert cell
function mergeData(m_data, q_data) {
const m_clone = JSON.parse(JSON.stringify(m_data));
for(let j = 0; j < q_data.length; j++){
for(let i = 0; i < m_data.features.length; i++){
if(q_data[j][ID_Column] === m_data.features[i].properties.NAME){
m_clone.features[i].properties["Q_Val"] = q_data[j][Quant_Column]
}
}
}
return m_clone
}
Insert cell
Insert cell
L = require('leaflet@1.8.0')
Insert cell
leaflet = html`<link href='${resolve('leaflet@1.8.0/dist/leaflet.css')}' rel='stylesheet' />`
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more