Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapbox - changing cluster colors dynamically

I am using mapbox clusters. i'd like to change the cluster colors according some logic from another function. I am trying to change the colors on moveend. I would ideally like something like this....

map.on('load', function(){ 

    //data
    map.addSource("surveydata", {
        type: "geojson",
        data: "/surveydata/"+lastweek+"/"+today+"",
        cluster: true,
        clusterRadius: 20 
    });

    map.addLayer({
        "id": "cluster",
        "type": "circle",
        "source": "surveydata",
        "paint": {
            'circle-color': 'rgba(0,0,200,0.2)',
            'circle-radius': 20
        },
        "filter": [">=", "point_count", 2]
    });

});


//recolor clusters
map.on('moveend', function (e) { 

    var colors = ['#ff0000', '#00ff00', '#0000ff'];
    var cluster = map.queryRenderedFeatures({ layers: ["cluster"] });

    //HERE
    for(i = 0; i < cluster.length; i++){

        console.log(cluster[i]); //THIS RETURNS ALL THE CLUSTERS SUCCESSFULLY
        cluster[i].setcolor(randomcolor) //this I am not sure how to do
    }
 });

I understand that having a unique id for the layer names would be ideal but I do not think I have that luxury. Any thoughts would be appreciated.

like image 835
barrylachapelle Avatar asked Oct 29 '22 09:10

barrylachapelle


2 Answers

This question ended a one day research odyssey for me, so thanks so much! I wanted to dynamically set the input steps for the circle-color "interpolate" expression based on the max point_count of all clusters. So, whenever the user zooms in or out, the clusters are still colored relative to the other clusters.

I ended up with this code, hopefully it will help somebody in the future:

map.on('moveend', function (e) {
  var clusters = map.queryRenderedFeatures({ layers: ["clusters"] });

  const max_count = clusters
    .map(c => c.properties.point_count)
    .reduce((a, b) => Math.max(a, b));

  map.setPaintProperty('clusters', 'circle-color', [
    'interpolate',
    ["linear"],
    ['get', 'point_count'],
    0, "#b2ebf2",
    max_count, "#dd2c00"
  ]);
});
like image 169
Peter Avatar answered Jan 02 '23 21:01

Peter


You require the SetPaintProperty to the layer
https://www.mapbox.com/mapbox-gl-js/api/#map#setpaintproperty

Documentation

map.setPaintProperty('my-layer', 'fill-color', '#faafee');

Example of randomising cluster

// recolor clusters
map.on('moveend', function (e) { 
  var colors = ['#ff0000', '#00ff00', '#0000ff'];
  var cluster = map.queryRenderedFeatures({ layers: ["cluster"] });

  //HERE
  for(i = 0; i < cluster.length; i++){
    map.setPaintProperty('cluster', 'circle-color', colors[i]);
  }
});

additional

If you want to randomize the color based on mouse-position/mouse-move, you could add the above to that event and calculate there based on color

like image 31
Denis Tsoi Avatar answered Jan 02 '23 19:01

Denis Tsoi