4
votes

I have a leaflet map with 75 overlay groups that I want to turn visible/invisible using the layer control panel. The problem is, that with that amount of groups my layer control panel reaches the end of my map and therefore not all of the groups are visible in the layers control panel.

The following minimal reproducible example shows the problem in detail:

library(leaflet)
leaflet(width = 400, height = 100) %>%
  addTiles() %>%
  # Overlay groups
  addCircleMarkers(lng = 9, lat = 47, color = 'red', group = 'red') %>%
  addCircleMarkers(lng = 8, lat = 46, color = 'blue', group = 'blue') %>%
  addCircleMarkers(lng = 8, lat = 47, color = 'green', group = 'green') %>%
  addCircleMarkers(lng = 9, lat = 46, color = 'yellow', group = 'yellow') %>%
  addCircleMarkers(lng = 8.5, lat = 46.5, color = 'purple', group = 'purple') %>%
  # Layers control
  addLayersControl(
    overlayGroups = c('red', 'green', 'blue', 'yellow', 'purple'),
    options = layersControlOptions(collapsed = TRUE))

This leads to the following map where the purple point is not available on the layers control panel enter image description here

Is there a possibility to force the layers control panel to arrange the layers in more than one column?

3

3 Answers

2
votes

I found a solution that works for me. It doesn't use a multi column layout, but works with an automated overflow on the layers control panel, which allows to navigate to all layers.

Since the addLayersControl function doesn't have the parameters to control the column layout of the Layers Control, one has to twerk around with JavaScript and CSS to establish the multi column layout. On the search for an really easy alternative I've stumbled upon the following on https://groups.google.com/forum/#!topic/leaflet-js/aoImrdIoF2Q

.leaflet-control-layers {
  max-height: 60px;
  overflow: auto;
}

This does establish an auto overflow layout which is nearly as good as the two column layout for my application. This snippet needs to be placed in the CSS section of the .html File containing the leaflet-map. So after 'knitting' the leaflet map to a .html File you have to reopen the .html file and place that snippet in the <body> section of the .html file.

    <body>
    <style type="text/css">
      .leaflet-control-layers {
        max-height: 60px;
        overflow: auto;
      }
    </style>
    ...<rest of document>...
    </body>

The result is a layers control panel that allows to navigate through all layers.

Scrolled up: layers control panel upper position Scrolled down: layers control panel scrolled down

1
votes

For this to work you have a couple of solutions... More elegant, cleaner and harder would be to modify the original leaflet-control-layer control or create a new one.

See leaflet-src.js on how 'leaflet-control-layers' div is created and you'll see what I am talking about.

Easier and 'dirtier' solution would be to use jQuery after the layers are added, go over the 'leaflet-control-layers-base' div, count it and apply some custom css that will add elements that have an index of 4 and above (for example) to another div which would be on the right from the first one (not a difficult thing to do right?). Of course you can measure the height of the map and compare it to the height of the div containing your layers and base your calculation on that (this would be a more generic solution).

So the answer is YES, you can do that.

1
votes

Following @symbolrush's answer, the <body> section may need to be edited a little if it already contains parameters.

Before (html file created by leaflet):

...
</head>
<body style="background-color:white;">
<div id="htmlwidget_container">
...

After @symbolrush's edits:

...
</head>
<body>
<style="background-color:white;"></style> #might not be necessary
<style type="text/css">
      .leaflet-control-layers {
        max-height: 600px;
        overflow: auto;
      }
    </style>
<div id="htmlwidget_container">
...