Reputation: 23
I want to create an interactive leaflet map with Shiny. The creation works fine, but despite changes at selectInput() and clicking "go!" the old markers are not deleted and no new markers are set. Can you please help me?
Operating System: Windows 10 64-Bit RStudio R Version: R version 4.0.0
geocodes <- data.frame("customer" = c("John", "Ahmet", "Zara"),
"longitude" = c(8.71, 8.59, 8.98),
"latitude" = c(51.2, 51.3, 51.1))
# UI
ui <- dashboardPage(
dashboardHeader(title = "CustomerLocation Dashboard"),
dashboardSidebar(
selectInput("account", label = "Account",
choices = c(unique(geocodes$customer)),
multiple = TRUE),
actionButton("go", "Go!")
),
dashboardBody(
tags$style(type = "text/css", "#map {height: calc(100vh - 80px) !important;}"),
leafletOutput("mymap", height=1000)
)
)
# server
server <- function(input, output, session){
reactiveDf <- reactive({
if(is.null(input$account)){
geocodes
} else{
geocodes[geocodes$customer %in% input$account,]
}
})
output$mymap <- renderLeaflet({
leaflet(geocodes) %>%
addProviderTiles("OpenStreetMap",
group = "OpenStreetMap"
) %>%
addAwesomeMarkers(
lng = ~longitude,
lat = ~latitude,
icon = customIcon,
clusterOptions = markerClusterOptions(),
label = ~customer,
popup = ~popup
)
})
eventReactive(input$go,{
leafletProxy("mymap", data = reactiveDf()) %>%
clearShapes() %>%
clearPopups() %>%
clearMarkers() %>%
addAwesomeMarkers(
data = reactiveDf(),
lng = ~longitude,
lat = ~latitude,
icon = customIcon,
clusterOptions = markerClusterOptions(),
label = ~customer,
popup = ~popup
)
})
}
shinyApp(ui, server)
Upvotes: 2
Views: 839
Reputation: 46
Three fixes that I've identified:
c(unique(geocodes$customer))
transforms this input to c(1,2,3)
. And when you later try subset the customer names "John", "Ahmet", and "Zara" by c(1,2,3) - this is incompatible and fails. selectInput("account", label = "Account",
choices = c(unique(geocodes$customer)),
multiple = TRUE),
Change to:
selectInput("account", label = "Account",
choices = unique(geocodes$customer),
multiple = TRUE),
clearMarkers()
in leafletProxy()
won't clear the markers like you expect, but changing the original map from rendering with geocodes
to reactiveDf()
(which still returns the geocodes
data frame if input$account
is null) appears to solve that issue.output$mymap <- renderLeaflet({
leaflet(geocodes) %>%
addProviderTiles("OpenStreetMap",
group = "OpenStreetMap"
) %>%
addAwesomeMarkers(
lng = ~longitude,
lat = ~latitude,
icon = customIcon,
clusterOptions = markerClusterOptions(),
label = ~customer,
popup = ~popup
)
})
Change to:
output$mymap <- renderLeaflet({
leaflet(reactiveDf()) %>%
addProviderTiles("OpenStreetMap",
group = "OpenStreetMap"
) %>%
addAwesomeMarkers(
lng = ~longitude,
lat = ~latitude,
icon = customIcon,
clusterOptions = markerClusterOptions(),
label = ~customer,
popup = ~popup
)
})
If you are willing to change the architecture a little bit:
observeEvent
to redefine geocodes
according to input$account
and to trigger leafletProxy() along with it. I suppose we are both missing some step with regards to creating the reactive data frame for the leafletProxy
, perhaps we can't completely change the data source going from the initial renderLeaflet
to the leafletProxy
?observeEvent(input$go, {
if(is.null(input$account)){
geocodes = geocodes
} else{
geocodes = geocodes[geocodes$customer %in% input$account,]
}
leafletProxy("mymap") %>%
clearShapes() %>%
clearPopups() %>%
clearMarkers() %>%
addMarkers(
data = geocodes,
lng = ~longitude,
lat = ~latitude,
label = ~customer,
)
}
)
Edit: Another option would be to define a group for each marker layer, and call showGroup() and hideGroup() to manipulate which markers are visually shown.
I hope this helps
Upvotes: 3