Hihi, I’ve been struggling to get a choropleth map of us counties working in Observable Framework. I could benefit from seeing someone do it successfully. Every tile/county is grey even though I believe I am correctly getting/setting different hex codes based on data. To debug, I am emitting the hex code that I think should be coloring the county. It varies by county in the popup so I think I am doing that part right. Just can’t figure out why that same approach doesn’t work for the county tiles…
I’ve been following along examples of people using Observable (Adaptation de Tutorial 7 / leclercprof | Observable) but fear I am not making the right tweaks for Framework. I’ve changed by code too many times to remember what I’ve tried but currently I have something like what’s reproduced below. Any help with be greatly appreciated!
import {us} from "./components/d3-us-map-with-puerto-rico.js";
const data = FileAttachment("data/data.geojson").json();
const countyShapes = topojson.feature(us, us.objects.counties);
// read in county data
const coerceCounty = (d) => ({
FIPS5: d.FIPS5,
METRIC1: +d.METRIC1,
METRIC2: +d.METRIC2,
....
});
const county_data = FileAttachment("data/county_data.csv").csv().then((D) => D.map(coerceCounty));
// was doing this to create a Map object for getting the data I cared about by FIPS
// by abandoned for now
// const countyMap = d3.group(county_data, d => d.FIPS5);
const basemaps = [
{name: "METRIC1", data: "METRIC1"},
{name: "METRIC2", data: "METRIC2"}
];
const basemap = view(
Inputs.select(basemaps, {
label: "Select basemap",
format: (b) => b.name,
value: basemaps.find((b) => b.name === "METRIC1")}));
// TODO see if using a generator here helps?
// const genBasemap = Generators.input(basemap)
function getCountyData(fips) {
return county_data.find((b) => b.FIPS5 === fips);
};
// setCountyColor(countyMap.get("36001")[0][basemap.data])
function setCountyColor(d) {
return d > .60 ? '#fc4e08' :
d > .50 ? '#fd8d1a' :
d > .20 ? '#feb22a' :
d > .10 ? '#fed954' :
'#ffed80';
}
// start making the Leaflet map
// previously tried wrapping all this in a function to call when I wanted it
// but it just renders no matter what.
const geojsonMarkerOptions = {
radius: 5,
weight: 1,
opacity: 1,
fillOpacity: 0.6
};
const div = display(document.createElement("div"));
div.style = `width:${width}px;height:${width/1.6}px`;
const branchMap = L.map(div)
// add tile layer
const tileLayer = L.tileLayer(cartoLight, {
attribution: cartoAttr,
subdomains: 'abcd',
maxZoom: 20,
minZoom: 0
}).addTo(branchMap);
// county layer
const countyLayer = L.geoJson(countyShapes, {
style: (feature) => {
return {
fillColor: d => setCountyColor(getCountyData(d.feature.id)[basemap.data]),
fillOpacity: 0.2,
// fillColor: '#999999',
weight: 2,
opacity: .5,
color: 'white',
dashArray: '3'
}}
})
.bindPopup(d => d.feature.id + '<br> hex?: ' + setCountyColor(getCountyData(d.feature.id)[basemap.data]))
.addTo(branchMap)
//geoMarker obj
//passing a pointToLyaer function in a GeoJson options object when creating the GeoJSON layer
const branchesLayer = L.geoJSON(mapData, {
pointToLayer: (feature, latlng) => {
return L.circleMarker(latlng, {
geojsonMarkerOptions,
fillColor: feature.properties.isMainOffice == false ? "#ff7800" : "#4287f5",
color: feature.properties.isMainOffice == false ? "#ff7800" : "#4287f5"});
}
})
.bindPopup(function (Layer) {
return Layer.feature.properties.Name +
'<br> Number: ' + Layer.feature.properties.Number +
'<br> siteName: ' + Layer.feature.properties.siteName +
'<br> SiteId: ' + Layer.feature.properties.siteId
;
})
.addTo(branchMap);
branchMap.fitBounds(branchesLayer.getBounds());
// return branchMap