The basic functionality of my web map is to allow users to switch between choropleth views using a dropdown menu. This basically works, but the issue I'm now having is with the info box that allows a user to get information about the polygon when they hover over it.
I can only get that functionality to work correctly for one choropleth map at a time. For the choropleth that doesn't work, the hover information will not change on the map and after moving the mouse away from the polygon, the color automatically changes back to the first choropleth map, rather than staying with the intended color selection. I'm not sure exactly where my code is wrong, probably within my "Hover Functionality" lines:
//----------------------------------
// EV COUNT CHOROPLETH LEGEND - lower right corner
//----------------------------------
var legend = L.control({
position: "bottomright"
});
legend.onAdd = function(map) {
var div = L.DomUtil.create("div", "info legend"),
grades = [1, 100, 500, 1000, 5000, 10000, 25000, 50000, 154000],
labels = [],
from,
to;
// loop through "grades" and create respective entries - colored box + range
for (var i = 0; i < grades.length; i++) {
from = grades[i];
to = grades[i + 1];
labels.push( //cf. .legend i style in css - 17x17 box
'<i style="background:' +
getColor(from + 1) +
'"></i> ' +
from +
(to ? "–" + to : "+") // catching the last case, i.e., i+1 is not defined anymore
// condition ? exprIfTrue : exprIfFalse
);
}
//debugger;
div.innerHTML = labels.join("<br>");
return div;
};
legend.addTo(map);
//-----------------------------------------------
// INFO CONTROL FOR EV COUNT POPUP ON MOUSE HOVER - lower left corner
//-----------------------------------------------
var info = L.control({
position: "bottomleft"
});
info.onAdd = function(map) {
this._div = L.DomUtil.create("div", "info");
this.update();
return this._div;
};
info.update = function(vehicles) {
this._div.innerHTML =
"<h4>EV Registration</h4>" +
(vehicles
? "<b>" + vehicles.name + "</b><br>" + vehicles.evcount + " registered electric vehicles"
: "Hover over a county");
// condition ? exprIfTrue : exprIfFalse
};
info.addTo(map);
//-----------------------------------------------
// FUNCTIONS FOR HANDLING THE POPUPS AND
// THE STYLING OF THE COUNTY POLYGONS - EV COUNT
//-----------------------------------------------
// Create chorolpleth map and get associated color depending on EV count value
function getColor(d) {
return d > 154000 ? "#004529" :
d > 50000 ? "#006837" :
d > 25000 ? "#238443" :
d > 10000 ? "#41ab5d" :
d > 5000 ? "#78c679" :
d > 1000 ? "#addd8e" :
d > 500 ? "#d9f0a3" :
d > 100 ? "#f1fcb9" :
"#e5e5ce" ;
}
function style(feature) {
return {
weight: 2,
opacity: 1,
color: "white",
dashArray: "3",
fillOpacity: 0.7,
fillColor: getColor(feature.properties.evcount)
};
}
//-----------------------------------------------
// GRAY OUTLINE MOUSE HOVER FUNCTIONALITY
//-----------------------------------------------
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 4,
color: "#666",
dashArray: "",
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera) {
layer.bringToFront();
}
info.update(layer.feature.properties);
}
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
function onEachFeature(feature, layer) {
layer.on({
//addEventListeners
mouseover: highlightFeature, // mouse moves over shape
mouseout: resetHighlight, // mouse leaves shape
click: zoomToFeature // click on shape and map will zoom
});
}
var geojson;
var counties=
"https://rjankows88.carto.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM public.california";
console.log("County Query: " + counties);
$.getJSON(counties, function(cartodbdata2) {
geojson = L.geoJson(cartodbdata2, {
// add popup with info to each geosjon feature
style: style, //style polygons
onEachFeature: onEachFeature //attached popup behavior
}).addTo(map);
map.fitBounds(geojson.getBounds()); // zooms to fit data
});
//----------------------------------
// POPULATION CHOROPLETH LEGEND - lower right corner
//----------------------------------
var poplegend = L.control({
position: "bottomright"
});
poplegend.onAdd = function(map) {
var div = L.DomUtil.create("div", "info legend"),
grades = [1000, 65000, 155000, 280000, 550000, 1150000, 2470000, 3330000, 11000000],
poplabels = [],
from,
to;
// loop through "grades" and create respective entries - colored box + range
for (var i = 0; i < grades.length; i++) {
from = grades[i];
to = grades[i + 1];
poplabels.push( //cf. .legend i style in css - 17x17 box
'<i style="background:' +
getColorpop(from + 1) +
'"></i> ' +
from +
(to ? "–" + to : "+") // catching the last case, i.e., i+1 is not defined anymore
// condition ? exprIfTrue : exprIfFalse
);
}
//debugger;
div.innerHTML = poplabels.join("<br>");
return div;
};
poplegend.addTo(map);
//-----------------------------------------------
// INFO CONTROL FOR POPULATION POPUP ON MOUSE HOVER - lower left corner
//-----------------------------------------------
var popinfo = L.control({
position: "bottomleft"
});
popinfo.onAdd = function(map) {
this._div = L.DomUtil.create("div", "info");
this.update();
return this._div;
};
popinfo.update = function(population) {
this._div.innerHTML =
"<h4>Population Estimate (2019) </h4>" +
(population
? "<b>" + population.name + "</b><br>" + population.pop2019 + " people per county"
: "Hover over a county");
// condition ? exprIfTrue : exprIfFalse
};
popinfo.addTo(map);
//-----------------------------------------------
// FUNCTIONS FOR HANDLING THE POPUPS AND
// THE STYLING OF THE COUNTY POLYGONS - POPULATION
//-----------------------------------------------
// Create chorolpleth map and get associated color depending on population
function getColorpop(p) {
return p > 11000000 ? "#034e7b" :
p > 3330000 ? "#0570b0" :
p > 2470000 ? "#3690c0" :
p > 1150000 ? "#74a9cf" :
p > 550000 ? "#a6bddb" :
p > 280000 ? "#d0d1e6" :
p > 155000 ? "#ece7f2" :
p > 65000 ? "#fff7fb" :
"#f0f0f0" ;
}
function style2(feature) {
return {
weight: 2,
opacity: 1,
color: "white",
dashArray: "3",
fillOpacity: 0.7,
fillColor: getColorpop(feature.properties.pop2019)
};
}
//-----------------------------------------------
// GRAY OUTLINE MOUSE HOVER FUNCTIONALITY
//-----------------------------------------------
function highlightFeature(e) {
var layer2 = e.target;
layer2.setStyle({
weight: 4,
color: "#666",
dashArray: "",
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera) {
layer2.bringToFront();
}
popinfo.update(layer2.feature.properties);
}
function resetHighlight(e) {
geojson2.resetStyle(e.target);
popinfo.update();
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
function onEachFeature(feature, layer2) {
layer2.on({
//addEventListeners
mouseover: highlightFeature, // mouse moves over shape
mouseout: resetHighlight, // mouse leaves shape
click: zoomToFeature // click on shape and map will zoom
});
}
var geojson2;
var population =
"https://rjankows88.carto.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM public.california";
console.log("Population Query: " + population);
$.getJSON(population, function(cartodbdata3) {
geojson2 = L.geoJson(cartodbdata3, {
// add popup with info to each geosjon feature
style: style2, //style polygons
onEachFeature: onEachFeature //attached popup behavior
}).addTo(map);
map.fitBounds(geojson2.getBounds()); // zooms to fit data
});
var evlayer = {legend, info, geojson};
var poplayer = {poplegend, popinfo, geojson2};
//-----------------------------------------------
// CONTROL FOR DROPDOWN
//-----------------------------------------------
var myDropdown = L.Control.extend({
options: {
position: "topleft"
},
onAdd: function(map) {
this._div = L.DomUtil.create("div", "myDropdown");
this._div.innerHTML =
'<h2 id="title">Select a layer </h2>' +
'<select id="selector">' +
'<option value="init">Any</option>' +
'<option value="evlayer">Electric Vehicles per County</option>' +
'<option value="poplayer">Population Estimate per County</option>' +
"</select>";
L.DomEvent.disableClickPropagation(this._div);
return this._div;
}
});
map.addControl(new myDropdown());
var layer_select = L.DomUtil.get("selector");
//prevent clicks on the selector from propagating through to the map
//(otherwise popups will close immediately after opening)
L.DomEvent.addListener(layer_select, "click", function(e) {
L.DomEvent.stopPropagation(e);
});
L.DomEvent.addListener(layer_select, "change", change);
//-----------------------------------------------
// DROPDOWN MENU FUNCTIONALITY
//-----------------------------------------------
function change(e) {
var showEvlayer = false;
var showPoplayer = false;
var evlayerShown = map.hasLayer(geojson);
var poplayerShown = map.hasLayer(geojson2);
switch ($('select').val()) {
case 'init':
showEvlayer = false;
showPoplayer = false;
break;
case 'evlayer':
showEvlayer = true;
break;
case 'poplayer':
showPoplayer = true;
}
if (evlayerShown) {
if (!showEvlayer) {
map.removeLayer(geojson);
map.removeControl(legend);
map.removeControl(info);
}
}
else if (showEvlayer) {
map.addLayer(geojson);
map.addControl(legend);
map.addControl(info);
}
if (poplayerShown) {
if (!showPoplayer) {
map.removeLayer(geojson2);
map.removeControl(poplegend);
map.removeControl(popinfo);
}
}
else if (showPoplayer) {
map.addLayer(geojson2);
map.addControl(poplegend);
map.addControl(popinfo);
}
};