Skip to content

Instantly share code, notes, and snippets.

@SKalt
Last active July 7, 2017 13:48
Show Gist options
  • Save SKalt/c1102f4370077bf1c6a21a6e82b1e3eb to your computer and use it in GitHub Desktop.
Save SKalt/c1102f4370077bf1c6a21a6e82b1e3eb to your computer and use it in GitHub Desktop.
Better adaptive mabox-gl.js legends
var features = map.queryRenderedFeatures({layers:['your-layer']});
var properties = features.map(f => f.properties);
var propertyLevels = properties.map(p => p.yourProperty);
var [maxLevel, minLevel] = [Math.max(...propertyLevels), Math.min(...propertyLevels)];
// produce some levels to display here. The regular-interval approach is on of many.
// for common binning methods, see https://github.com/d3/d3-array/blob/master/README.md#thresholdSturges
var interval = maxLevel - minLevel;
if (interval === 0) throw new Error('no interval selected');
displayLevels = [0,1,2,3,4,5].map( i => interval * ( i / interval) + minLevel )
displayColors = displayLevels.map(
level => {
map.getLayer('your-layer')._paintDeclarations['']['fill-color'].function(
map.getZoom(),
{'your-property': level}
)
}
)
/**
* @param {mapboxgl.Map} map a mapboxgl map, used a an argument to ensure it is in scope
* @param {String} paintProperty the paint property to set, such as circle-radius or paint
* @param {String} max the most intense paint property level in your interpolation
* @param {String} min the least intense paint property level in your interpolation
*/
function adaptStyleSimpleExponential(map, paintProperty, max, min){
// see http://colorbrewer2.org/ for color ramp ideas
var features = map.queryRenderedFeatures({layers:['your-layer']});
var properties = features.map(f => f.properties);
var propertyLevels = properties.map(p => p.yourProperty);
var [maxLevel, minLevel] = [Math.max(...propertyLevels), Math.min(...propertyLevels)];
map.setPaintProperty('your-layer', paintProperty, {
property: 'your-property',
stops: [
[minLevel, min],
[maxLevel, max]
],
type: 'exponential'
})

The mapbox updating choropleth example uses a precomputed legend: both the stops and the colors they correspond to are already written into the webpage. In maps that follow Tobler's law that "everything is related to everything else, but near things are more related than distant things", some regions will contain features that have small but significant differences from each other that are difficult to see on a pre-computed legend. Here are two solutions: change the style and change the legend to match the displayed data (adapt_style and adapt_legend.js, respectively).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment