3

I generated these 2 random dataset about geographical coordinates (e.g. each point represents an imaginary restaurant in France):

    id = 1:1000
    long = 2.2945 + rnorm( 1000, 0.1085246 , 0.1)
    lat = 48.8584 + rnorm( 1000, 0.009036273 , 0.1)
    
    my_data_1 = data.frame(id, lat, long)

id = 1:1000
    long = 2.2945 + rnorm( 1000, 0.1085246 , 0.1)
    lat = 48.8584 + rnorm( 1000, 0.009036273 , 0.1)
    

   my_data_2 = data.frame(id, lat, long)

I then made these 4 maps:

library(leaflet)
library(leaflet.extras)


map1 = my_data_1 %>%
    leaflet() %>%
    addTiles() %>%
    addHeatmap(lng=~long,lat=~lat,max=100,radius=20,blur=10)


map2 = my_data_2 %>%
    leaflet() %>%
    addTiles() %>%
    addHeatmap(lng=~long,lat=~lat,max=100,radius=20,blur=10)


map3 = my_data_1 %>% 
  leaflet() %>% 
  addTiles() %>% 
  addMarkers(clusterOption=markerClusterOptions())

map4 = my_data_2 %>% 
  leaflet() %>% 
  addTiles() %>% 
  addMarkers(clusterOption=markerClusterOptions())

I would like to combine all these 4 maps into a single map (i.e. a single html file). That is, I would like there to be a window on the right side with 4 toggle buttons :map1, map2, map3, map4. I would like that someone could click these 4 buttons and the corresponding map would load. (only one map can be loaded at a time)

I found this link over here that shows how to combine maps (https://rstudio.github.io/leaflet/showhide.html) - but I do not think that this can be directly used to solve the problem I am working on. This would have been useful if I had different "classes" of restaurants (e.g. cafes, vegan restaurant, fancy restaurant, etc.) and I wanted to toggle between the different restaurants on the same map - however, I want to toggle between 4 completely different maps.

  • I am wondering: is there a straightforward option within the "leaflet" library that can be used to do this? Or does a function need to be written to accomplish this?

For example: c(map1, map2, map3, map4)

Thank you!

2 Answers 2

3

You could use the package htmltools and shinyRPG (this is not a Shiny app). Last time I looked, shinyRPG wasn't a Cran package, you'll have to get this from Github.

devtools::install_github("RinteRface/shinyRPG")

Leaving your code as is, I used rpgSelect to create the selection list and a lot of the formatting.

tagSel <- rpgSelect(
  "selectBox",
  "Selections:",
  c(setNames(1:4, paste0("map", 1:4))), # left is values, right is labels
  multiple = T
)
tagSel$attribs$class <- 'select'
tagSel$children[[2]]$attribs$onchange <- "getOps(this)"

Then I used htmltools to create one htmlwidget that contains all four graphs and a selection list (not buttons). I did add a bit of styling.

First, browsable() so that the JS, CSS, and R widgets are consolidated into one object. In the tags$head or <head>, I've got 2 JS scripts and one element for styles.

The first <script> stacks the maps on top of each other. The second <script> changes the map that you see based on your selection. The styles address the selection box (.select), the options (#selectBox), and the space allocated for the maps versus the selection list. The <body> contains the four maps and the selection list.

browsable(tagList(list(
  tags$head(
    tags$script(HTML("setTimeout(function(){ /* stack maps */
            $('[id^=\"htmlwidget-\"]').css({top: 0, 
                                            position:'absolute',
                                            'z-index': -10});
            $('[id^=\"htmlwidget-\"]').first().css({'z-index': 1000});
            }, 100)")),
    tags$script(HTML("function getOps(sel) { /* activate select */
            graphy = document.querySelectorAll('[id^=\"htmlwidget-\"]');
            $('[id^=\"htmlwidget-\"]').css({'z-index': -10});
            for(i = 0; i < sel.length; i++) {
              opt = sel.options[i];
              if ( opt.selected ) {
                console.log(opt);
                graphy[i].style.zIndex = '1000';
              } else {
                graphy[1].style.zIndex = '-10';
              }
            }
          }")),
    tags$style(".select{ 
                 position: relative; width: 13ch;
                 border: 2px solid #003b70;
                 margin: 0 2px;
                 border-radius: 5px; font-size: 1.1em;
                 text-align: center; line-height: 1.25em;
               }
               #selectBox{
                 background-color: #003b70;
                 width: 10ch; text-align: center;
                 color: white; font-weight: bold;
                 line-height: 1.25em;
               }
               .yaLeft{
                position: relative;
                float: left; width: 85%;
                height: 80ch;
               }
               .yaRight{
                 float: right; width: 15%;}")),
  div(div(class = "yaLeft",
          map1, map2, map3, map4), 
      div(class = "yaRight", tagSel))))) 

enter image description here

enter image description here

0
1

Perhaps flexdashboard is what you are looking for leaving you with a html document.

Using Rmd file:

---
title: "maps"
output: flexdashboard::flex_dashboard
---
    
```{r setup, include=FALSE}
#library(flexdashboard)
library(leaflet)
library(leaflet.extras)
id = 1:1000
long = 2.2945 + rnorm( 1000, 0.1085246 , 0.1)
lat = 48.8584 + rnorm( 1000, 0.009036273 , 0.1)
my_data_1 = data.frame(id, lat, long)
id = 1:1000
long = 2.2945 + rnorm( 1000, 0.1085246 , 0.1)
lat = 48.8584 + rnorm( 1000, 0.009036273 , 0.1)
my_data_2 = data.frame(id, lat, long)

```    
  
   
Column {.tabset}
-------------------------------------
   
### map 1

```{r}
map1 = my_data_1 %>%
    leaflet() %>%
    addTiles() %>%
    addHeatmap(lng=~long,lat=~lat,max=100,radius=20,blur=10)
map1
```   
 
### map 2
    
```{r}
map2 = my_data_2 %>%
    leaflet() %>%
    addTiles() %>%
    addHeatmap(lng=~long,lat=~lat,max=100,radius=20,blur=10)
map2
```

### map 3
    
```{r}
map3 = my_data_1 %>% 
  leaflet() %>% 
  addTiles() %>% 
  addMarkers(clusterOption=markerClusterOptions())
map3

```

### map 4
    
```{r}
map4 = my_data_2 %>% 
  leaflet() %>% 
  addTiles() %>% 
  addMarkers(clusterOption=markerClusterOptions())
map4
```

enter image description here

4
  • @ user63230: thank you so much! This looks great! Just to clarify - I have to copy/paste your code into a R markdown page and then "knit" this to a RMD file? thank you so much!
    – stats_noob
    Commented Aug 10, 2022 at 7:14
  • 1
    yes, open Rmarkdown document, copy and paste the code and press knit
    – user63230
    Commented Aug 10, 2022 at 8:27
  • Another question - is there a way to change the name of each of the "tabs"? And is it possible to add any visualization with these tabs (e.g. mix and match bar charts and geographical maps ... by just pasting the code into these blocks? Thank you so much!
    – stats_noob
    Commented Aug 15, 2022 at 4:06
  • I think I will follow this example to do this: beta.rstudioconnect.com/jjallaire/…
    – stats_noob
    Commented Aug 15, 2022 at 4:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.