Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

jcheng5
Copy link
Member

@jcheng5 jcheng5 commented Aug 21, 2020

Fixes #420
Fixes #440

  • Make tests pass
  • Remove dependency on unexported function in htmlwidgets

htmlwidgets provides built-in support for the JS function, which lets you mark widget data string values in R to be evaluated as JS code when the widget data is deserialized in the browser. This isn't supported natively in Shiny though, so leafletProxy did not automatically inherit this behavior. The changes in this PR reimplement that mechanism for leafletProxy.

Minimal reproducible example

From this SO post by @NilsOle, the following app should show the same behavior regardless of using leafletProxy or renderLeaflet. After clicking either button, zoom out to see clusters.

library(shiny)
library(dplyr)
library(leaflet)

ui <- fluidPage(
  titlePanel("Hello Shiny!"),
  sidebarLayout(
    sidebarPanel(
      actionButton(inputId = "my_button1",
                   label = "Use leafletProxy()"),
      actionButton(inputId = "my_button2",
                   label = "Use renderLeaflet()")
    ),
    mainPanel(
      leafletOutput(
        outputId = "map",
        width = "100%",
        height = "300px"
      )
    )
  )
)

server <- function(input, output, session) {

  some_data <- data.frame(
    "lon"=c(4.905167,4.906357,4.905831),
    "lat"=c(52.37712,52.37783,52.37755),
    "number_var"=c(5,9,7),
    "name"=c("Jane","Harold","Mike"),
    stringsAsFactors = F
  )

  output$map <- renderLeaflet({
    return(
      leaflet(data = some_data[0,]) %>%
         addProviderTiles(providers$CartoDB.Positron) %>%
        fitBounds(
          min(some_data$lon),
          min(some_data$lat),
          max(some_data$lon),
          max(some_data$lat)
        ) %>%
        addMarkers(
          lng = ~lon,
          lat = ~lat,
          clusterOptions = markerClusterOptions(
            iconCreateFunction = JS(paste0("function(cluster) {",
                                           "return new L.DivIcon({",
                                           "html: '<div style=\"background-color:rgba(77,77,77,0.5)\"><span>' + cluster.getChildCount() + '</div><span>',",
                                           "className: 'marker-cluster'",
                                           "});",
                                           "}"))



          )
        )
    )
  })

  observeEvent(input$my_button1,{
      leafletProxy(mapId = "map",
                   session = session,
                   data = some_data) %>%
        addProviderTiles(providers$CartoDB.Positron) %>%
        clearMarkerClusters() %>%
        clearMarkers() %>%
        fitBounds(
          min(some_data$lon),
          min(some_data$lat),
          max(some_data$lon),
          max(some_data$lat)
        ) %>%
        addMarkers(
          lng = ~lon,
          lat = ~lat,
          clusterOptions = markerClusterOptions(
            iconCreateFunction = JS(paste0("function(cluster) {",
                                           "console.log('Here comes cluster',cluster); ",
                                           "return new L.DivIcon({",
                                           "html: '<div style=\"background-color:rgba(77,77,77,0.5)\"><span>' + cluster.getChildCount() + '</div><span>',",
                                           "className: 'marker-cluster'",
                                           "});",
                                           "}"))
          )
        )
  })

  observeEvent(input$my_button2,{
    output$map <- renderLeaflet({

      leaflet(data = some_data) %>%
        addProviderTiles(providers$CartoDB.Positron) %>%
        fitBounds(
          min(some_data$lon),
          min(some_data$lat),
          max(some_data$lon),
          max(some_data$lat)
        ) %>%
        addMarkers(
          lng = ~lon,
          lat = ~lat,
          clusterOptions = markerClusterOptions(
            iconCreateFunction = JS(paste0("function(cluster) {",
                                           "console.log('Here comes cluster',cluster); ",
                                           "return new L.DivIcon({",
                                           "html: '<div style=\"background-color:rgba(77,77,77,0.5)\"><span>' + cluster.getChildCount() + '</div><span>',",
                                           "className: 'marker-cluster'",
                                           "});",
                                           "}"))
          )
        )
    })
  })
}

shinyApp(ui = ui, server = server)

PR task list:

  • Update NEWS
  • Add tests (where appropriate)
    • R code tests: tests/testthat/
    • Visual tests: R/zzz_viztest.R
  • Update documentation with devtools::document()

@jcheng5 jcheng5 requested a review from schloerke August 25, 2020 22:12
@jcheng5 jcheng5 added this to the v2.1 milestone Aug 25, 2020
@jcheng5
Copy link
Member Author

jcheng5 commented Aug 26, 2020

  • Before merging, add a unit test that includes JS() on a leafletProxy call.

@jcheng5 jcheng5 force-pushed the js-literals-leafletproxy branch from 57008ce to 75e50f3 Compare September 22, 2021 18:04
@schloerke schloerke force-pushed the js-literals-leafletproxy branch from 75e50f3 to 385895a Compare September 22, 2021 19:24
@schloerke
Copy link
Contributor

@jcheng5 I rebased off of master to get a clean GHA check. (No code changes needed for the rebase)

@jcheng5 jcheng5 merged commit 117b9e7 into master Sep 22, 2021
@jcheng5 jcheng5 deleted the js-literals-leafletproxy branch September 22, 2021 20:29
@nicocriscuolo
Copy link

nicocriscuolo commented Sep 24, 2021

@jcheng5 I saw that the previous issues have been closed and everything was redirected to this one. What should be the working example to create custom cluster icons with JS() and make everything work in leafletProxy()? With the code above markers starts clustering when I zoom out, but there is no icon for the clusters.

Thanks again really a lot for working on solving this!

@jcheng5
Copy link
Member Author

jcheng5 commented Oct 4, 2021

@nicocriscuolo Just to confirm--you tried it after running remotes::install_github("rstudio/leaflet") and restarting?

@nicocriscuolo
Copy link

nicocriscuolo commented Oct 5, 2021

@jcheng5 I can confirm that after installing this leaflet version everything works perfectly. Thanks really a lot for solving this!

@futluz
Copy link

futluz commented Mar 15, 2022

@jcheng5...i tried this.... remotes::install_github("rstudio/leaflet") - unfortunately didn't work for me. Would be grateful for any sugggestions'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

iconCreateFunction does NOT work when adding Markers with leafletProxy iconCreateFunction does not work when used in leafletProxy
4 participants