leaflet icon indicating copy to clipboard operation
leaflet copied to clipboard

Using BeautifyMarker with Leaflet for R

Open nash1119 opened this issue 3 years ago • 8 comments

I am trying to use the BeautifyMarker plugin with Leaflet for R by loading the plugin and utilizing the onRender() function (technique described here https://gist.github.com/jcheng5/c084a59717f18e947a17955007dc5f92. I am unable to load the plugin successfully. I think my assignments in htmlDependency() might be the issue, but I can't seem to figure this out. Thank you!!

library(leaflet)
library(htmltools)
library(htmlwidgets)
library(fontawesome)

beautifyPlugin <- htmlDependency("Leaflet.BeautifyMarker", "1.0.9",
                                 src = c(href = "https://cdn.jsdelivr.net/npm/[email protected]/package.json"),
                                 script = "https://cdn.jsdelivr.net/npm/[email protected]/leaflet-beautify-marker-icon.min.js",
                                 stylesheet = "https://cdn.jsdelivr.net/npm/[email protected]/leaflet-beautify-marker-icon.min.css"
)

registerPlugin <- function(map, plugin) {
  map$dependencies <- c(map$dependencies, list(plugin))
  map
}

leaflet() %>% setView(-122.23, 37.75, zoom = 10)%>%
  addTiles()%>%
  registerPlugin(beautifyPlugin) %>%
  onRender("function(el, x) {
           L.marker([37.77, -122.40] ,
           {icon: L.BeautifyIcon.icon()
           }).addTo(this).bindPopup('test');
           }")

Created on 2020-09-23 by the reprex package (v0.3.0)

nash1119 avatar Sep 23 '20 14:09 nash1119

Your src argument points to a package.json and should instead point to https://cdn.jsdelivr.net/npm/[email protected]/

Then your script and stylesheet just need the filenames, without the src path.

This should work:

beautifyPlugin <- htmlDependency("Leaflet.BeautifyMarker", "1.0.9",
                                 src = c(href="https://cdn.jsdelivr.net/npm/[email protected]/"),
                                 script = "leaflet-beautify-marker-icon.min.js",
                                 stylesheet = "leaflet-beautify-marker-icon.min.css"
)

trafficonese avatar Sep 23 '20 14:09 trafficonese

This worked. Thank you so much!!!

nash1119 avatar Sep 23 '20 14:09 nash1119

@trafficonese follow up question: This worked to utilize the plugin, but the fontawesome icons don't seem to be accessible. I'm wondering if I need to include the fontawesome stylesheet in my dependencies as well.

library(leaflet)
library(htmltools)
library(htmlwidgets)
library(fontawesome)

beautifyPlugin <- htmlDependency("Leaflet.BeautifyMarker", "1.0.9",
                                 src = c(href="https://cdn.jsdelivr.net/npm/[email protected]/"),
                                 script = "leaflet-beautify-marker-icon.min.js",
                                 stylesheet = list("leaflet-beautify-marker-icon.min.css", c(href = "https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"))
)

Created on 2020-09-23 by the reprex package (v0.3.0)

nash1119 avatar Sep 23 '20 14:09 nash1119

I think you have to create a new htmlDependency and register that too:

fontawesomePlugin <- htmlDependency("Leaflet.BeautifyMarkerFA", "1.0.9",
                                 src = c(href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/"),
                                 stylesheet = "font-awesome.min.css"
)

leaflet() %>% setView(-122.23, 37.75, zoom = 10)%>%
  addTiles()%>%
  registerPlugin(fontawesomePlugin) %>%
  registerPlugin(beautifyPlugin) %>%
  onRender("function(el, x) {
           L.marker([37.77, -122.40] ,
           {icon: L.BeautifyIcon.icon()
           }).addTo(this).bindPopup('test');
           }")

trafficonese avatar Sep 23 '20 15:09 trafficonese

Worked perfectly, thank you!

nash1119 avatar Sep 23 '20 15:09 nash1119

@trafficonese another related issue:

Utilizing my plugins with leaflet() seems to be working just fine. However, when I try to utilize them with renderLeaflet(), they are not working. Do you know how to solve this or what the issue might be?

Functioning perfectly:

library(leaflet)
library(htmltools)
library(htmlwidgets)
library(fontawesome)

beautifyPlugin <- htmlDependency("Leaflet.BeautifyMarker", "1.0.9",
                                 src = c(href="https://cdn.jsdelivr.net/npm/[email protected]/"),
                                 script = "leaflet-beautify-marker-icon.min.js",
                                 stylesheet = "leaflet-beautify-marker-icon.min.css"
)

fontawesomePlugin <- htmlDependency("Leaflet.BeautifyMarkerFA", "1.0.9",
                                    src = c(href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/"),
                                    stylesheet = "font-awesome.min.css"
)

registerPlugin <- function(map, plugin) {
  map$dependencies <- c(map$dependencies, list(plugin))
  map
}

leaflet() %>% setView(-74.96, 39.77, zoom = 10) %>% addTiles()%>%
  registerPlugin(fontawesomePlugin) %>% 
  registerPlugin(beautifyPlugin) %>%
  onRender(paste0("function(el, x) {
    L.marker([39.77, -74.96] , 
        {icon: L.BeautifyIcon.icon({ icon:'child', iconShape: 'circle' }) }).addTo(this).bindPopup('test');
 }"))

Created on 2020-11-03 by the reprex package (v0.3.0)

Not functioning (from within my server.R file):

    output$map <- renderLeaflet({
        leaflet()%>%addProviderTiles("Esri.WorldGrayCanvas")%>%
            addPolygons(data = shape, color = "black", weight = 1.5, opacity = 1, fill = TRUE, fillOpacity = 0, label = ~NAME, labelOptions = labelOptions(style = list("color" = "black", "font-family" = "serif", "box-shadow" = "3px 3px rgba(0,0,0,0.25)", "font-size" = "15px", "border-color" = "rgba(0,0,0,0.5)")))%>%
            addLegend(position = "topright", colors = c("#483D8B", "#00BFFF"), opacity = 1,labels = c("Externally Provided", "Internally Provided"))%>%
            registerPlugin(fontawesomePlugin) %>% 
            registerPlugin(beautifyPlugin) %>%
            onRender(paste0("function(el, x) {
            L.marker([39.77, -74.96] , 
            {icon: L.BeautifyIcon.icon({ icon:'child', iconShape: 'circle' }) }).addTo(this).bindPopup('test');
                            }"))
    })
#> Error in renderLeaflet({: could not find function "renderLeaflet"

Created on 2020-11-03 by the reprex package (v0.3.0)

nash1119 avatar Nov 03 '20 21:11 nash1119

I don't know how you got this error could not find function "renderLeaflet", but you're right, the code snippet doesnt work right away in a shiny app.

Apparently you have to include the HTML-dependencies earlier on, otherwise you will see an error in the browser console, saying that

L.BeautifyIcon is undefined

For Font Awesome, you could include an invisible shiny icon, then you dont have to load the css files. If you have some icons in your shiny-app already, you dont even have to do this.

This should work:

library(shiny)  
library(leaflet)
library(htmlwidgets)

ui <- fluidPage(
  tags$head(tags$link(rel="stylesheet", href="https://cdn.jsdelivr.net/npm/[email protected]/leaflet-beautify-marker-icon.css")),
  tags$head(tags$script(src="https://cdn.jsdelivr.net/npm/[email protected]/leaflet-beautify-marker-icon.js")),
  div(style="display:none", icon("gear")),
  leafletOutput("map")
)

server <- function(input, output, session) {
  output$map <- renderLeaflet({
    leaflet()%>%
      addProviderTiles("Esri.WorldGrayCanvas")%>%
      onRender("function(el, x) {
                  L.marker([39.77, -74.96], {
                    icon: L.BeautifyIcon.icon({
                      icon: 'child',
                      iconShape: 'circle' })
                    }).addTo(this).bindPopup('test');
               }")
  })
}
shinyApp(ui, server)

trafficonese avatar Nov 04 '20 15:11 trafficonese

Thank you @trafficonese , this worked for rendering my output map. However, I cannot seem to get it to work with leafletProxy().

My ultimate goal is to utilize the BeautifyMarker plugin reactively. I am trying to place icons on a map given user selection. I had this fully functional using an R plugin (mapkey icons), but it was not a robust enough solution for the level of customizing icons I need. BeautifyMarker is much more appropriate but I just keep running into implementation issues. Do you know how to make this functional with leafletProxy() or what the issue is? Thank you so much!!

library(shiny)
library(shinyWidgets)
#> Warning: package 'shinyWidgets' was built under R version 4.0.3
library(leaflet)

library(data.table)
#> Warning: package 'data.table' was built under R version 4.0.3
library(tigris)
#> To enable 
#> caching of data, set `options(tigris_use_cache = TRUE)` in your R script or .Rprofile.

library(fontawesome)

#read in data
prog_dat = fread("Categories.csv")
#> Error in fread("Categories.csv"): File 'Categories.csv' does not exist or is non-readable. 

#convert to data table
prog_dat = as.data.table(prog_dat)
#> Error in as.data.table(prog_dat): object 'prog_dat' not found

#Counties Shapefile
shape <- tigris::counties(state = "NJ")
#>   |                                                                              |                                                                      |   0%  |                                                                              |                                                                      |   1%  |                                                                              |=                                                                     |   1%  |                                                                              |=                                                                     |   2%  |                                                                              |==                                                                    |   2%  |                                                                              |==                                                                    |   3%  |                                                                              |==                                                                    |   4%  |                                                                              |===                                                                   |   4%  |                                                                              |===                                                                   |   5%  |                                                                              |====                                                                  |   5%  |                                                                              |====                                                                  |   6%  |                                                                              |=====                                                                 |   6%  |                                                                              |=====                                                                 |   7%  |                                                                              |=====                                                                 |   8%  |                                                                              |======                                                                |   8%  |                                                                              |======                                                                |   9%  |                                                                              |=======                                                               |   9%  |                                                                              |=======                                                               |  10%  |                                                                              |=======                                                               |  11%  |                                                                              |========                                                              |  11%  |                                                                              |========                                                              |  12%  |                                                                              |=========                                                             |  12%  |                                                                              |=========                                                             |  13%  |                                                                              |=========                                                             |  14%  |                                                                              |==========                                                            |  14%  |                                                                              |==========                                                            |  15%  |                                                                              |===========                                                           |  15%  |                                                                              |===========                                                           |  16%  |                                                                              |============                                                          |  16%  |                                                                              |============                                                          |  17%  |                                                                              |============                                                          |  18%  |                                                                              |=============                                                         |  18%  |                                                                              |=============                                                         |  19%  |                                                                              |==============                                                        |  19%  |                                                                              |==============                                                        |  20%  |                                                                              |==============                                                        |  21%  |                                                                              |===============                                                       |  21%  |                                                                              |===============                                                       |  22%  |                                                                              |================                                                      |  22%  |                                                                              |================                                                      |  23%  |                                                                              |================                                                      |  24%  |                                                                              |=================                                                     |  24%  |                                                                              |=================                                                     |  25%  |                                                                              |==================                                                    |  25%  |                                                                              |==================                                                    |  26%  |                                                                              |===================                                                   |  26%  |                                                                              |===================                                                   |  27%  |                                                                              |===================                                                   |  28%  |                                                                              |====================                                                  |  28%  |                                                                              |====================                                                  |  29%  |                                                                              |=====================                                                 |  29%  |                                                                              |=====================                                                 |  30%  |                                                                              |=====================                                                 |  31%  |                                                                              |======================                                                |  31%  |                                                                              |======================                                                |  32%  |                                                                              |=======================                                               |  32%  |                                                                              |=======================                                               |  33%  |                                                                              |=======================                                               |  34%  |                                                                              |========================                                              |  34%  |                                                                              |========================                                              |  35%  |                                                                              |=========================                                             |  35%  |                                                                              |=========================                                             |  36%  |                                                                              |==========================                                            |  36%  |                                                                              |==========================                                            |  37%  |                                                                              |==========================                                            |  38%  |                                                                              |===========================                                           |  38%  |                                                                              |===========================                                           |  39%  |                                                                              |============================                                          |  39%  |                                                                              |============================                                          |  40%  |                                                                              |============================                                          |  41%  |                                                                              |=============================                                         |  41%  |                                                                              |=============================                                         |  42%  |                                                                              |==============================                                        |  42%  |                                                                              |==============================                                        |  43%  |                                                                              |==============================                                        |  44%  |                                                                              |===============================                                       |  44%  |                                                                              |===============================                                       |  45%  |                                                                              |================================                                      |  45%  |                                                                              |================================                                      |  46%  |                                                                              |=================================                                     |  46%  |                                                                              |=================================                                     |  47%  |                                                                              |=================================                                     |  48%  |                                                                              |==================================                                    |  48%  |                                                                              |==================================                                    |  49%  |                                                                              |===================================                                   |  49%  |                                                                              |===================================                                   |  50%  |                                                                              |===================================                                   |  51%  |                                                                              |====================================                                  |  51%  |                                                                              |====================================                                  |  52%  |                                                                              |=====================================                                 |  52%  |                                                                              |=====================================                                 |  53%  |                                                                              |=====================================                                 |  54%  |                                                                              |======================================                                |  54%  |                                                                              |======================================                                |  55%  |                                                                              |=======================================                               |  55%  |                                                                              |=======================================                               |  56%  |                                                                              |========================================                              |  56%  |                                                                              |========================================                              |  57%  |                                                                              |========================================                              |  58%  |                                                                              |=========================================                             |  58%  |                                                                              |=========================================                             |  59%  |                                                                              |==========================================                            |  59%  |                                                                              |==========================================                            |  60%  |                                                                              |==========================================                            |  61%  |                                                                              |===========================================                           |  61%  |                                                                              |===========================================                           |  62%  |                                                                              |============================================                          |  62%  |                                                                              |============================================                          |  63%  |                                                                              |============================================                          |  64%  |                                                                              |=============================================                         |  64%  |                                                                              |=============================================                         |  65%  |                                                                              |==============================================                        |  65%  |                                                                              |==============================================                        |  66%  |                                                                              |===============================================                       |  66%  |                                                                              |===============================================                       |  67%  |                                                                              |===============================================                       |  68%  |                                                                              |================================================                      |  68%  |                                                                              |================================================                      |  69%  |                                                                              |=================================================                     |  69%  |                                                                              |=================================================                     |  70%  |                                                                              |=================================================                     |  71%  |                                                                              |==================================================                    |  71%  |                                                                              |==================================================                    |  72%  |                                                                              |===================================================                   |  72%  |                                                                              |===================================================                   |  73%  |                                                                              |===================================================                   |  74%  |                                                                              |====================================================                  |  74%  |                                                                              |====================================================                  |  75%  |                                                                              |=====================================================                 |  75%  |                                                                              |=====================================================                 |  76%  |                                                                              |======================================================                |  76%  |                                                                              |======================================================                |  77%  |                                                                              |======================================================                |  78%  |                                                                              |=======================================================               |  78%  |                                                                              |=======================================================               |  79%  |                                                                              |========================================================              |  79%  |                                                                              |========================================================              |  80%  |                                                                              |========================================================              |  81%  |                                                                              |=========================================================             |  81%  |                                                                              |=========================================================             |  82%  |                                                                              |==========================================================            |  82%  |                                                                              |==========================================================            |  83%  |                                                                              |==========================================================            |  84%  |                                                                              |===========================================================           |  84%  |                                                                              |===========================================================           |  85%  |                                                                              |============================================================          |  85%  |                                                                              |============================================================          |  86%  |                                                                              |=============================================================         |  86%  |                                                                              |=============================================================         |  87%  |                                                                              |=============================================================         |  88%  |                                                                              |==============================================================        |  88%  |                                                                              |==============================================================        |  89%  |                                                                              |===============================================================       |  89%  |                                                                              |===============================================================       |  90%  |                                                                              |===============================================================       |  91%  |                                                                              |================================================================      |  91%  |                                                                              |================================================================      |  92%  |                                                                              |=================================================================     |  92%  |                                                                              |=================================================================     |  93%  |                                                                              |=================================================================     |  94%  |                                                                              |==================================================================    |  94%  |                                                                              |==================================================================    |  95%  |                                                                              |===================================================================   |  95%  |                                                                              |===================================================================   |  96%  |                                                                              |====================================================================  |  96%  |                                                                              |====================================================================  |  97%  |                                                                              |====================================================================  |  98%  |                                                                              |===================================================================== |  98%  |                                                                              |===================================================================== |  99%  |                                                                              |======================================================================|  99%  |                                                                              |======================================================================| 100%

# Define UI for application 
ui <- fluidPage(
  
  tags$head(tags$link(rel="stylesheet", href="https://cdn.jsdelivr.net/npm/[email protected]/leaflet-beautify-marker-icon.css")),
  tags$head(tags$script(src="https://cdn.jsdelivr.net/npm/[email protected]/leaflet-beautify-marker-icon.js")),
  div(style="display:none", icon("gear")),
  
  sidebarLayout(
    
    sidebarPanel(
      
      #user select data types
      pickerInput(inputId = "programtype", label = "Program Type(s):", choices = c("AM" = "1",
                                                                                   "BM" = "2",
                                                                                   "CM" = "3",
                                                                                   "CN" = "4",
                                                                                   "DA" = "5",
                                                                                   "DP" = "6",
                                                                                   "EA" = "7",
                                                                                   "EP" = "8",
                                                                                   "FE" = "9",
                                                                                   "GS" = "10",
                                                                                   "HT" = "11",
                                                                                   "IP" = "12",
                                                                                   "MH" = "13",
                                                                                   "M" = "14",
                                                                                   "PP" = "15",
                                                                                   "PE" = "16",
                                                                                   "RE" = "17",
                                                                                   "RP" = "18",
                                                                                   "SB" = "19",
                                                                                   "SO" = "20",
                                                                                   "S" = "21",
                                                                                   "TP" = "22"), selected = NULL, options = pickerOptions(actionsBox = TRUE, liveSearchNormalize = TRUE, liveSearchStyle = "startsWith"), multiple = TRUE),
      
      
      width = 3
      
    ),
    
    mainPanel(
      leafletOutput("map", height = 700),
      width = 9
    ),
    position = "right"
  )
)

# Define server logic
server <- function(input, output) {
  
  #filter data based on user selection
  filteredData <- reactive({
    prog_dat%>%
      dplyr::filter(Proj_Code %in% input$programtype)
  })
  
  #Icon Names
  iconName <- reactive({
    ifelse(filteredData()$Proj_Code== 1, "exclamation-triangle", ifelse(
      filteredData()$Proj_Code== 2,"wrench", ifelse(
        filteredData()$Proj_Code== 3, "folder-open", ifelse(
          filteredData()$Proj_Code== 4, "bell", ifelse(
            filteredData()$Proj_Code== 5, "balance-scale", ifelse(
              filteredData()$Proj_Code== 6, "plus", ifelse(
                filteredData()$Proj_Code== 7, "graduation-cap", ifelse(
                  filteredData()$Proj_Code== 8, "briefcase", ifelse(
                    filteredData()$Proj_Code== 9, "users", ifelse(
                      filteredData()$Proj_Code== 10, "transgender-alt", ifelse(
                        filteredData()$Proj_Code== 11, "binoculars", ifelse(
                          filteredData()$Proj_Code== 12, "gift", ifelse(
                            filteredData()$Proj_Code== 13, "comments", ifelse(
                              filteredData()$Proj_Code== 14, "compass", ifelse(
                                filteredData()$Proj_Code== 15, "info-circle", ifelse(
                                  filteredData()$Proj_Code== 16, "child", ifelse(                                    
                                    filteredData()$Proj_Code== 17, "forward", ifelse(
                                      filteredData()$Proj_Code== 18, "home", ifelse(
                                        filteredData()$Proj_Code== 19,"pencil", ifelse(
                                          filteredData()$Proj_Code== 20, "puzzle-piece", ifelse(
                                            filteredData()$Proj_Code== 21, "cog", "car")
                                        )
                                      )
                                    )
                                  )
                                )
                              )
                            )
                          )
                        ) 
                      )
                    )
                  )   
                )  
              )  
            )
          )
        )
      )
    )
    )
  })
  
  #render map
  output$map <- renderLeaflet({
    leaflet()%>%addProviderTiles("Esri.WorldGrayCanvas")%>%
      addPolygons(data = shape, color = "black", weight = 1.5, opacity = 1, fill = TRUE, fillOpacity = 0, label = ~NAME, labelOptions = labelOptions(style = list("color" = "black", "font-family" = "serif", "box-shadow" = "3px 3px rgba(0,0,0,0.25)", "font-size" = "15px", "border-color" = "rgba(0,0,0,0.5)")))
  })
  
  #add icons to map based on user selection
  observe({
    leafletProxy("map", data = filteredData())%>%
      onRender(paste0("function(el, x) {
                  L.marker([",~Latitude,",",~Longitude,"], {
                    icon: L.BeautifyIcon.icon({
                      icon:'" ,iconName(), "',
                      iconShape: 'circle' })
                    }).addTo(this).bindPopup('test');
               }"))
  })
  
}

shinyApp(ui = ui, server = server)
#> 
#> Listening on http://127.0.0.1:3697
#> Warning: sf layer has inconsistent datum (+proj=longlat +datum=NAD83 +no_defs).
#> Need '+proj=longlat +datum=WGS84'
#> Warning: Error in eval: object 'prog_dat' not found

Created on 2020-11-08 by the reprex package (v0.3.0)

nash1119 avatar Nov 06 '20 15:11 nash1119