Mapbox GL JS: Coloring individual features in large GeoJSON

Viewed 1187

I have a map of states with each precinct as an individual feature in Mapbox. I want to change the color of each of these precincts based on the difference between party votes. Here's an example of what I'm trying to achieve versus what I have right now.

I tried using map.setPaintProperty, however setting one feature forces you to change every other feature that doesn't match the ID.

map.setPaintProperty("wisconsin", "fill-color", 
    ["match",["get", "id"],
       features[i].properties["OBJECTID"],
       color, "#ffffff"
    ]
);

How could I go about this or is there another method of doing so?

1 Answers

So, you want to do data-driven styling. There are basically three methods.

Expression mapping property to color

If the attribute you want to visualise is in the data (ie, you have a .population property on each feature), you use an expression like:

'fill-color': ['interpolate-hcl', ['linear'], ['get', 'population'], 0, 'red', 1e6, 'blue']

See https://docs.mapbox.com/help/glossary/data-driven-styling/

Expression mapping each ID to a specific color

If your attributes are not contained within your data source, you can programmatically generate a huge expression that will look like:

'fill-color': ['match', ['get', 'id'],
  1020, 'red',
  1033, 'green',
  1038, 'red',
  1049, 'white',
  // ...

Use feature-state to add the attribute at run-time

Finally, you can get better rendering performance than the previous case, albeit with some extra complexity, by calling setFeatureState to actually add the attribute you want at runtime.

Your style looks like this:

'fill-color': ['interpolate-hcl', ['linear'], ['feature-state', 'population'], 0, 'red', 1e6, 'blue']

Then you iterate over every feature within the viewport to actually add that attribute:

for (const district of districts) {
  map.setFeatureState({ source: 'mysource', sourceLayer: 'mysourcelayer', id: district.id }, { population: district.population});
}

See https://docs.mapbox.com/mapbox-gl-js/api/map/#map#setfeaturestate .

Related