Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Group names not unique over many maps - addLayersControl gets confused in Quarto #78

Open
ivanlambert1975 opened this issue Oct 4, 2023 · 4 comments
Labels
duplicate This issue or pull request already exists

Comments

@ivanlambert1975
Copy link

Hi Thomas,

thank you very much for a very useful leaflet library. Thank you for your time and effort in developing leaflegend !

I think I've found an issue with leaflegand. I'm rendering many maps (tens of them) within one Quarto document.
I use a standard function to output one of many thousands of leaflet maps over many geographies.

I've noticed that the group names when refenced in a leaflegend object appear shared over all chunks?
This means that leaflegend works really great in a single map, but over subsequent maps in Quarto documents, the controls don't work or the groups cannot be reliably interacted within an addLayersControl - which appears an issue to me.

Please see the simplest example below I could make to demonstrate this unexpected behaviour.
See how the lower map's controls affect the layers in the separate map above when this QMD is rendered.
When more and more maps are added beyond these, the layersControl simply doesn't respond at all.
I've tried many different workarounds over the last few hours and haven't succeeded in finding a scalable solution to resolve the issue. Please can you advise?

many thanks,
ivan


title: "Test6"
author: "BI"
date: "04/10/2023"
execute:
echo: false
format:
html:
fig-width: 12
fig-height: 10
code-fold: true
embed-resources: false
css: styles.css
grid:
sidebar-width: 220px
body-width: 1400px
margin-width: 150px
gutter-width: 1.5rem

#| include: true
#| layout-ncol: 1
#| fig.width: 12
#| fig.height: 10
#| class-output: output



library(leaflet)
library(leaflegend)
set.seed(21)
data("gadmCHE")
gadmCHE@data$x <- sample(c('A', 'B', 'C'), nrow(gadmCHE@data), replace = TRUE)
factorPal <- colorFactor(c('#1f77b4', '#ff7f0e' , '#2ca02c'), gadmCHE@data$x)
n <- 10
awesomeMarkers <- data.frame(
  marker = sample(c('Font Awesome', 'Ionic', 'Glyphicon'), n, replace = TRUE),
  lng = runif(n, gadmCHE@bbox[1,1], gadmCHE@bbox[1,2]),
  lat = runif(n, gadmCHE@bbox[2,1], gadmCHE@bbox[2,2])
)
n2 <- 30
symbolMarkers <- data.frame(
  x = runif(n2, 0, 100),
  y = runif(n2, 10, 30),
  lng = runif(n2, gadmCHE@bbox[1,1], gadmCHE@bbox[1,2]),
  lat = runif(n2, gadmCHE@bbox[2,1], gadmCHE@bbox[2,2])
)
numericPal <- colorNumeric(hcl.colors(10, palette = 'zissou'),
                           symbolMarkers$y)
iconSet <- awesomeIconList(
  `Font Awesome` = makeAwesomeIcon(icon = "font-awesome", library = "fa",
                                   iconColor = 'rgb(192, 255, 0)',
                                   markerColor = 'lightgray',
                                   squareMarker = TRUE, iconRotate = 30
  ),
  Ionic = makeAwesomeIcon(icon = "ionic", library = "ion",
                          iconColor = 'gold', markerColor = 'gray',
                          squareMarker = FALSE),
  Glyphicon = makeAwesomeIcon(icon = "plus-sign", library = "glyphicon",
                              iconColor = '#ffffff',
                              markerColor = 'black', squareMarker = FALSE)
)
leaflet() |>
  addTiles() |>
  addPolygons(data = gadmCHE, color = ~factorPal(x), fillOpacity = .5,
              opacity = 0, group = 'Polygons') |>
  addLegendFactor(pal = factorPal, shape = 'polygon', fillOpacity = .5,
                  opacity = 0, values = ~x, title = 'addLegendFactor',
                  position = 'topright', data = gadmCHE, group = 'Polygons') |>
  addAwesomeMarkers(data = awesomeMarkers, lat = ~lat, lng = ~lng,
                    icon = ~iconSet[marker],
                    group = 'Awesome Icons') |>
  addLegendAwesomeIcon(iconSet = iconSet, title = 'addLegendAwesomeIcon',
                       position = 'bottomleft',
                       group = 'Awesome Icons') |>
  addSymbolsSize(data = symbolMarkers, fillOpacity = .7, shape = 'plus',
                 values = ~x, lat = ~lat, lng = ~lng, baseSize = 20,
                 fillColor = ~numericPal(y), color = 'black',
                 group = 'Symbols') |>
  addLegendSize(pal = numericPal, shape = 'plus', color = 'black',
                fillColor = 'transparent', baseSize = 20, fillOpacity = .7,
                values = ~x, orientation = 'horizontal',
                title = 'addSizeLegend', position = 'bottomright',
                group = 'Symbols', data = symbolMarkers) |>
  addLegendNumeric(pal = numericPal, values = ~y, title = 'addLegendNumeric',
                   orientation = 'horizontal', fillOpacity = .7, width = 150,
                   height = 20, position = 'bottomright', group = 'Symbols',
                   data = symbolMarkers) |>
  addLayersControl(overlayGroups = c('Polygons', 'Awesome Icons', 'Symbols'),
                   position = 'topleft',
                   options = layersControlOptions(collapsed = TRUE))

#| include: true
#| layout-ncol: 1
#| fig.width: 12
#| fig.height: 10
#| class-output: output



library(leaflet)
library(leaflegend)
set.seed(21)
data("gadmCHE")
gadmCHE@data$x <- sample(c('A', 'B', 'C'), nrow(gadmCHE@data), replace = TRUE)
factorPal <- colorFactor(c('#1f77b4', '#ff7f0e' , '#2ca02c'), gadmCHE@data$x)
n <- 10
awesomeMarkers <- data.frame(
  marker = sample(c('Font Awesome', 'Ionic', 'Glyphicon'), n, replace = TRUE),
  lng = runif(n, gadmCHE@bbox[1,1], gadmCHE@bbox[1,2]),
  lat = runif(n, gadmCHE@bbox[2,1], gadmCHE@bbox[2,2])
)
n2 <- 30
symbolMarkers <- data.frame(
  x = runif(n2, 0, 100),
  y = runif(n2, 10, 30),
  lng = runif(n2, gadmCHE@bbox[1,1], gadmCHE@bbox[1,2]),
  lat = runif(n2, gadmCHE@bbox[2,1], gadmCHE@bbox[2,2])
)
numericPal <- colorNumeric(hcl.colors(10, palette = 'zissou'),
                           symbolMarkers$y)
iconSet <- awesomeIconList(
  `Font Awesome` = makeAwesomeIcon(icon = "font-awesome", library = "fa",
                                   iconColor = 'rgb(192, 255, 0)',
                                   markerColor = 'lightgray',
                                   squareMarker = TRUE, iconRotate = 30
  ),
  Ionic = makeAwesomeIcon(icon = "ionic", library = "ion",
                          iconColor = 'gold', markerColor = 'gray',
                          squareMarker = FALSE),
  Glyphicon = makeAwesomeIcon(icon = "plus-sign", library = "glyphicon",
                              iconColor = '#ffffff',
                              markerColor = 'black', squareMarker = FALSE)
)
leaflet() |>
  addTiles() |>
  addPolygons(data = gadmCHE, color = ~factorPal(x), fillOpacity = .5,
              opacity = 0, group = 'Polygons') |>
  addLegendFactor(pal = factorPal, shape = 'polygon', fillOpacity = .5,
                  opacity = 0, values = ~x, title = 'addLegendFactor',
                  position = 'topright', data = gadmCHE, group = 'Polygons') |>
  addAwesomeMarkers(data = awesomeMarkers, lat = ~lat, lng = ~lng,
                    icon = ~iconSet[marker],
                    group = 'Awesome Icons') |>
  addLegendAwesomeIcon(iconSet = iconSet, title = 'addLegendAwesomeIcon',
                       position = 'bottomleft',
                       group = 'Awesome Icons') |>
  addSymbolsSize(data = symbolMarkers, fillOpacity = .7, shape = 'plus',
                 values = ~x, lat = ~lat, lng = ~lng, baseSize = 20,
                 fillColor = ~numericPal(y), color = 'black',
                 group = 'Symbols') |>
  addLegendSize(pal = numericPal, shape = 'plus', color = 'black',
                fillColor = 'transparent', baseSize = 20, fillOpacity = .7,
                values = ~x, orientation = 'horizontal',
                title = 'addSizeLegend', position = 'bottomright',
                group = 'Symbols', data = symbolMarkers) |>
  addLegendNumeric(pal = numericPal, values = ~y, title = 'addLegendNumeric',
                   orientation = 'horizontal', fillOpacity = .7, width = 150,
                   height = 20, position = 'bottomright', group = 'Symbols',
                   data = symbolMarkers) |>
  addLayersControl(overlayGroups = c('Polygons', 'Awesome Icons', 'Symbols'),
                   position = 'topleft',
                   options = layersControlOptions(collapsed = TRUE))

@tomroh
Copy link
Owner

tomroh commented Oct 5, 2023

@ivanlambert1975, I'm not following the example here. Are these two separate documents? Can you reconfigure into one quarto doc?

@tomroh
Copy link
Owner

tomroh commented May 9, 2024

Closing due to inactivity.

@tomroh tomroh closed this as completed May 9, 2024
@ajjitn
Copy link

ajjitn commented Nov 27, 2024

I just ran into this issue today, and am attaching a reproducible example below

The problem

When creating multiple leaflet maps (in a Quarto doc, or an Rmarkdown doc) with leaflegend, and I have the same group name across multiple maps, the group functionality will not work correctly within the addLayersControl() function. Only the last map's Layer Control will control the layer plotting, and will affect all layers across all maps.

I am guessing this is related to Issue #25 and PR #27

Steps to reproduce

  1. Open a new quarto document, and create one code chunk.

  2. Paste the following into the code chunk

#| echo: false
#| message: false

library(leaflet)
library(leaflegend)
library(sf)
library(mapview)

dc_libraries = st_read("https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Cultural_and_Society_WebMercator/MapServer/4/query?outFields=*&where=1%3D1&f=geojson")

library_map = leaflet() %>% 
  addProviderTiles("CartoDB.Positron") %>% 
  addCircles(data = dc_libraries, group = "DC Libraries")

# Make first map
library_map %>% 
  addLegendFactor(pal = colorFactor("blue", "Libraries"), 
                  shape = 'circle', 
                  opacity = 1, 
                  values = "Libraries", 
                  position = 'topright', 
                  group = 'Libraries'
                  ) %>% 
  addLayersControl(overlayGroups = c("Libraries"),
                   position = "bottomleft")

# Make second map, with same group name
library_map %>% 
  addLegendFactor(pal = colorFactor("red", "Libraries"), 
                  shape = 'circle', 
                  opacity = 1, 
                  values = "Libraries", 
                  position = 'topright', 
                  group = 'Libraries'
                  ) %>% 
  addLayersControl(overlayGroups = c("Libraries"),
                   position = "bottomleft")
  1. Render the code chunk, and play with the Layer Controls on map 1 and map 2. You will notice that only the Layer Control on map 2 works, and will affect the "Libraries" group in map 1.

Expected Behavior

Similar to Layer Controls in leaflet, layer controls should only affect the layers on the current map. And reusing layer names across different names should be supported.

@tomroh
Copy link
Owner

tomroh commented Nov 30, 2024

Try installing the dev branch. This is fixed in ae2348e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

3 participants