I'm new to JS, React and Leaflet but I think I've managed okay so far. I have a choropleth displaying coffee information correctly. Unfortunately when I change the data within onEachCountry the changes are not reflected as this is not a state. Maybe I can somehow make each layer within the onEachCountry loop, a state? Or is there some easy refresh option I can call in the JSX maybe?
I've tried to use the useEffect for onEachCountry, I've tried console logs too and the data IS being updated, just not displayed. Other leaflet hooks seem to update more easily when changed.
Any help greatly appreciated.
import React, { useState, useEffect } from "react";
import { MapContainer, GeoJSON, TileLayer } from "react-leaflet";
import "leaflet/dist/leaflet.css";
import "./ChoroMap.css";
import NavBarCountry from "../NavBarCountry";
// from Choro
const ChoroMap = ({ countries, coffees, onChangeLegend }) => {
const [selectedStat, setSelectedStat] = useState("Producers");
useEffect(() => {
onEachCountry();
}, [selectedStat]);
const onProducersClick = function () {
onChangeLegend("Producers");
setSelectedStat("Producers");
};
const onExportersClick = function () {
onChangeLegend("Exporters");
setSelectedStat("Exporters");
};
const onFarmsClick = function () {
onChangeLegend("Farms");
setSelectedStat("Farms");
};
function legend(stat, comparisonArray) {
if (stat >= comparisonArray[0]) {
return "#741f1f";
} else if (stat >= comparisonArray[1] && stat < comparisonArray[0]) {
return "#9c2929";
} else if (stat >= comparisonArray[2] && stat < comparisonArray[1]) {
return "#d75e5e";
} else if (stat >= comparisonArray[3] && stat < comparisonArray[2]) {
return "#c57979";
} else if (stat >= 0 && stat < comparisonArray[3]) {
return "#f1b1b1";
}
}
function stripNumber(numberString) {
const number = Number(numberString.replace(/[^\d.-]/g, ""));
return number;
}
const onEachCountry = (country, layer) => {
if (country) {
// defaults
layer.options.fillOpacity = 1;
layer.options.weight = 0.6;
layer.options.color = "white";
// country name from JSON
const name = country.properties.ADMIN;
const countryObj = coffees.find((coffee) => coffee.country ===
name);
if (countryObj != null) {
if ((selectedStat == "Producers")) {
layer.bindPopup(`${name}
${countryObj.production_volume}`);
const productionVol =
stripNumber(countryObj.production_volume);
const foundColor = legend(
productionVol,
[10_000_000, 5_000_000, 2_000_000, 500_000]
);
layer.options.fillColor = foundColor;
}
else if ((selectedStat == "Exporters")) {
layer.bindPopup(`${name} ${countryObj.export_volume}`);
const exportVol = stripNumber(countryObj.export_volume);
const foundColor = legend(
exportVol,
[10_000_000, 5_000_000, 2_000_000, 500_000]
);
layer.options.fillColor = foundColor;
}
else if ((selectedStat == "Farms")) {
layer.bindPopup(`${name} ${countryObj.number_of_farms}`);
const numberOfFarms =
stripNumber(countryObj.number_of_farms);
const foundColor = legend(
numberOfFarms,
[5, 10, 15, 20]
);
layer.options.fillColor = foundColor;
}
console.log('onEachCountry', layer.options.fillColor)
}
}
};
return (
<div>
<NavBarCountry
onProducersClick={onProducersClick}
onExportersClick={onExportersClick}
onFarmsClick={onFarmsClick}
/>
<MapContainer
className="map"
attributionControl={false}
zoom={2.5}
center={[10, 10]}
>
<GeoJSON data={countries} onEachFeature={onEachCountry}/>
</MapContainer>
</div>
);
};
export default ChoroMap;