Search code examples
cssrshinyr-leaflet

How to change default CSS cluster classes?


How do I change the default CSS classes which define cluster objects from within the Leaflet for R interface? For example, if I wanted to remove the opacity from the .marker-cluster-small class, how could I do this from within R?

Here is the CSS which creates the cluster classes: https://github.com/Leaflet/Leaflet.markercluster/blob/64a2d5711521e56cac8ab863fb658beda5690600/dist/leaflet.markercluster-src.js

For example, I want to remove the opacity from the clusters, e.g.

.marker-cluster-small {
    background-color: rgba(181, 226, 140, 1.0);
    }
.marker-cluster-small div {
    background-color: rgba(110, 204, 57, 1.0);
    }

Is there a way to do this from within iconCreateFunction ?

library(leaflet)
leaflet(quakes) %>% addTiles() %>% addMarkers(
  clusterOptions = markerClusterOptions(iconCreateFunction=JS("function (cluster) {    
    var childCount = cluster.getChildCount(); 
    var c = ' marker-cluster-';  
    if (childCount < 100) {  
      c += 'large';  
    } else if (childCount < 1000) {  
      c += 'medium';  
    } else { 
      c += 'small';  
    }    
    return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });

  }"))
)

Solution

  • You can maybe try to add inline CSS to the different markers in the function that creates the icons, for ex:

    clusterOptions = markerClusterOptions(iconCreateFunction=JS("function (cluster) {    
        var childCount = cluster.getChildCount();  
        if (childCount < 100) {  
          c = 'rgba(181, 226, 140, 1.0);'
        } else if (childCount < 1000) {  
          c = 'rgba(240, 194, 12, 1);'  
        } else { 
          c = 'rgba(241, 128, 23, 1);'  
        }    
        return new L.DivIcon({ html: '<div style=\"background-color:'+c+'\"><span>' + childCount + '</span></div>', className: 'marker-cluster', iconSize: new L.Point(40, 40) });
    
      }")
    

    If you are using shiny, you can also change the iconCreateFunction to assign a different class to each marker, and add tags$style in the header to set the CSS for these classes. Here's an example:

    ui <- fluidPage(
      tags$head(tags$style(HTML("
      .marker-custom-small {
      background-color: rgba(181, 226, 140, 1);
        }
    .marker-customr-small div {
        background-color: rgba(110, 204, 57, 1);
        }
    
    .marker-custom-medium {
        background-color: rgba(241, 211, 87, 1);
        }
    .marker-custom-medium div {
        background-color: rgba(240, 194, 12, 1);
        }
    
    .marker-custom-large {
        background-color: rgba(253, 156, 115, 1);
        }
    .marker-custom-large div {
        background-color: rgba(241, 128, 23, 1);
        }"))),
      leafletOutput("mymap"))
    
    server<-function(input, output, session) {
      output$mymap <- renderLeaflet({
        leaflet(quakes) %>% addTiles() %>% addMarkers(
          clusterOptions = markerClusterOptions(iconCreateFunction=JS("function (cluster) {    
        var childCount = cluster.getChildCount(); 
        var c = ' marker-custom-';  
        if (childCount < 100) {  
          c += 'large';  
        } else if (childCount < 1000) {  
          c += 'medium';  
        } else { 
          c += 'small';  
        }    
        return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
    
      }"))
        )
      })
    }
    
    shinyApp(ui,server)
    

    Couldn't figure out how to have custom CSS in the leaflet outside of a shiny app.