rleafletr-leaflet

How to add subtitles in a Leaflet layer control of overlay groups?


I'd like to show subtitles in the control box for overlay groups of a leaflet map created in R. I found some examples (for instance https://github.com/ismyrnow/leaflet-groupedlayercontrol) but not applied to R language and I wonder if it's possible or not.

I created a reprex with three data sources, the idea would be to have in the overlay layer control something like:

Data type 1

⬞ Data1

⬞ Data2

Data type 2

⬞ Data3

How to apply this in R? Here's the reprex:

library(leaflet)
library(leaflet.esri)
library(htmlwidgets)
library(sf)

data1 <- data.frame(Lon=c(1,2), Lat=c(0.5,0.8))
data2 <- data1+0.1
data3 <- data1+0.2

map <- leaflet() %>%
  addTiles(group="OpenStreetMap", options = tileOptions(opacity=0.5)) %>%
  addEsriBasemapLayer(esriBasemapLayers$Imagery, group = "Satellite") %>%
  
  addMarkers(lng=data1$Lon, lat=data1$Lat, group="Data1") %>%
  addMarkers(lng=data2$Lon, lat=data2$Lat, group="Data2") %>%
  addMarkers(lng=data3$Lon, lat=data3$Lat, group="Data3") %>%
  
  addLayersControl(baseGroups=c("OpenStreetMap", "Satellite"), overlayGroups=c("Data1", "Data2", "Data3"), position="topleft", options=layersControlOptions(collapsed=F)) %>%  
  
  htmlwidgets::onRender("
        function() {
            $('.leaflet-control-layers-overlays').prepend('<b>TITLE 2</b>');
            $('.leaflet-control-layers-list').prepend('<b>TITLE 1</b>');
        }
    ")

map

Solution

  • I registered your linked example as a plugin:

    enter image description here

    library(leaflet)
    library(htmltools)
    
    groupedLayerControlPlugin <- htmlDependency(
      "@groupedLayerControl", "0.6.1",
      src = c(href = 'https://cdn.jsdelivr.net/npm/leaflet-groupedlayercontrol@0.6.1/dist/'), 
      script = 'leaflet.groupedlayercontrol.min.js',
      stylesheet = 'leaflet.groupedlayercontrol.min.css'
    )
    
    registerPlugin <- function(map, plugin) {
      map$dependencies <- c(map$dependencies, list(plugin))
      map
    }
    
    data1 <- data.frame(Lon = c(1, 2), Lat = c(0.5, 0.8))
    data2 <- data1 + 0.1
    data3 <- data1 + 0.2
    
    leaflet() |> 
      addTiles(group="OpenStreetMap", options = tileOptions(opacity = 0.5)) |>
      
      addMarkers(lng=data1$Lon, lat=data1$Lat, group="Data1") |> 
      addMarkers(lng=data2$Lon, lat=data2$Lat, group="Data2") |> 
      addMarkers(lng=data3$Lon, lat=data3$Lat, group="Data3") |> 
      
      registerPlugin(groupedLayerControlPlugin) |> 
      
      htmlwidgets::onRender("
        function() {
            
          var baseOverlays = {
            OpenStreetMap: this.layerManager.getLayerGroup('OpenStreetMap', true)
          }
          
          var groupedOverlays = {
            'Data Type 1': {
              'Data1': this.layerManager.getLayerGroup('Data1', true),
              'Data2': this.layerManager.getLayerGroup('Data2', true)
            },
            'Data Type 2': {
              'Data3': this.layerManager.getLayerGroup('Data3', true)
            }
          };
          
          var layerControl = L.control.groupedLayers(
            baseOverlays, 
            groupedOverlays, 
            {collapsed: false, position: 'topleft'}
          ).addTo(this);
          
          // https://github.com/ismyrnow/leaflet-groupedlayercontrol/issues/51
          L.DomEvent.disableClickPropagation(layerControl._container);
          L.DomEvent.disableScrollPropagation(layerControl._container);
          
          $('.leaflet-control-layers-list').prepend('<b>TITLE 1</b>');
    
        }"
      )