How to add titles to a layer control box in a Leaflet map in R
28 May, 2021
tl;dr
htmlwidgets::onRender(map, "
function() {
$('.leaflet-control-layers-overlays').prepend('');
$('.leaflet-control-layers-list').prepend('');
}
")
Minimal example code here.
Introduction
Leaflet maps have this concept of layer control, which you can use to show or hide map layers (like points or markers, or shapes). The layers are controlled by a box that's usually in the top-right corner of the map. The layer levels are labelled, but there's no parameter that allows you to add a title to the control box (neither for the base layers part, or the overlay part). This is somewhat analogous to a title in a legend, so it's a pretty useful thing to be able to add. This brief post shows how you can add a title (or two) to a layer control box, using some JavaScript in a Leaflet map made in R.
Doing the thing
We're going to take advantage of the htmlWidgets::onRender
function to insert some JavaScript into the map after it's been rendered. You can see an example of another use case of that in the docs.
The layer control box can have two components: One for the base layer, and one for the overlays. The base layer defines the tiles used by the map, while the overlays can be any typical GIS objects, like shapes, lines, markers, and so on. The base layer and the overlay components are accessed by the following classes, respectively:
.leaflet-control-layers-list
.leaflet-control-layers-overlays
The strategy (first described by Saurabh Yadav here) is simply to prepend the title to those classes. The example that Saurabh gave was this:
$(".leaflet-control-layers-overlays").prepend("");
That's pretty much exactly what we're going to do, and we'll insert it with htmlWidgets::onRender
like this:
htmlwidgets::onRender(map, "
function() {
$('.leaflet-control-layers-overlays').prepend('');
}
")
(map
is our Leaflet map object. I try to do everything I can in a pipe, so I'll usually be piping the map object into the onRender
call.)
Here's a minimal working example. We're plotting the location of earthquakes off Fiji (using the base R quakes
dataset), and we'll give the user the option of showing or hiding the quakes, as well as the option of selecting the base map to use. For the former option, that of showing or hiding the quakes, we'll insert a title by prepending it to the .leaflet-control-layers-overlays
class. The latter option, asking which base map to display, will have a title supplied by prepending a label to the .leaflet-control-layers-list
class. A couple of notes:
addTiles
will supply the default OpenStreetMap tiles, but we'll still need to supply thegroup
argument so that we can select it withaddLayersControl
.- We need to do the same for the CartoDB provider tiles, as well as the circles (
group = "Show quakes"
). - We need to be sure to specify
baseGroups
andoverlapGroups
inaddLayersControl
, and these need to correspond to the previously definedgroup
parameters.
library(leaflet)
leaflet(quakes) %>%
addTiles(group = "OpenStreetMap") %>%
addProviderTiles(providers$CartoDB.Positron, group = "Positron") %>%
addCircles(~long, ~lat, group = "Show quakes") %>%
addLayersControl(
baseGroups = c("OpenStreetMap", "Positron"),
overlayGroups = "Show quakes",
options = layersControlOptions(collapsed = FALSE)) %>%
htmlwidgets::onRender("
function() {
$('.leaflet-control-layers-overlays').prepend('');
$('.leaflet-control-layers-list').prepend('');
}
")
Here's a Shiny app with the minimal example on my server.
Enjoy.
References
- Add title to layers control box in Leaflet using R - Stack Overflow
- javascript - Add a title to leaflet layers control - Stack Overflow
- Leaflet for R - Show/Hide Layers
- Layer Groups and Layers Control - Leaflet - a JavaScript library for interactive maps