Reputation: 1699
I'm having trouble setting up this shiny with a leaflet map. My original post had two questions and it was suggested I should start a new post to address my second issue: how do I get the map to show my updated data after I have filtered by speed; my table gets updated whether I change "speed" or the map bounds, but the leaflet map does not update points based on the speed filter input.
REPRODUCIBLE CODE
library(shiny)
library(magrittr)
library(leaflet)
library(DT)
ships <-
read.csv(
"https://raw.githubusercontent.com/Appsilon/crossfilter-demo/master/app/ships.csv"
)
ui <- shinyUI(fluidPage(
titlePanel("Filter"),
sidebarLayout(
sidebarPanel(width = 3,
numericInput(
"speed_f", label = h5("Ship's Speed"), value = 100
)),
mainPanel(tabsetPanel(
type = "tabs",
tabPanel(
"Leaflet",
leafletOutput("leafletmap", width = "350px"),
dataTableOutput("tbl")
)
))
)
))
server <- function(input, output) {
in_bounding_box <- function(data, lat, long, bounds, speed) {
data %>%
dplyr::filter(
lat > bounds$south &
lat < bounds$north &
long < bounds$east & long > bounds$west &
speed > input$speed_f
)
}
output$leafletmap <- renderLeaflet({
leaflet() %>%
addProviderTiles("Esri.WorldImagery", group = "ESRI World Imagery") %>%
addCircleMarkers(
data = ships,
~ long ,
~ lat,
popup = ~ speed,
radius = 5 ,
stroke = FALSE,
fillOpacity = 0.8,
popupOptions = popupOptions(closeButton = FALSE)
)
})
data_map <- reactive({
if (is.null(input$leafletmap_bounds)) {
ships
} else {
bounds <- input$leafletmap_bounds
in_bounding_box(ships, lat, long, bounds, speed)
}
})
output$tbl <- DT::renderDataTable({
DT::datatable(
data_map(),
extensions = "Scroller",
style = "bootstrap",
class = "compact",
width = "100%",
options = list(
deferRender = TRUE,
scrollY = 300,
scroller = TRUE,
dom = 'tp'
)
)
})
}
shinyApp(ui = ui, server = server)
UPDATE
Making the following change data = data_map()
seems to work, with an exception:
output$leafletmap <- renderLeaflet({
leaflet() %>%
addProviderTiles("Esri.WorldImagery", group = "ESRI World Imagery") %>%
addCircleMarkers(
data = data_map(), #### THIS LINE HAS CHANGED
~ long ,
~ lat,
popup = ~ speed,
radius = 5 ,
stroke = FALSE,
fillOpacity = 0.8,
popupOptions = popupOptions(closeButton = FALSE)
)
})
However, the leaflet map does not let me zoom out of the area defined by the filtered points. Is there a way around this?
Upvotes: 4
Views: 5436
Reputation: 1106
If you define a reactive just for the map data and use that within renderLeaflet
it should allow you to then move out of the are defined. You don't need to change any of your other functions or reactives, just add the new reactive and make a couple of changes to renderLeaflet
as below
map_data_react <- reactive({
ships %>% dplyr::filter(speed > input$speed_f)
})
output$leafletmap <- renderLeaflet({
ships_data <- map_data_react() # Add this
ships_data %>% leaflet() %>%
addProviderTiles("Esri.WorldImagery", group = "ESRI World Imagery") %>%
addCircleMarkers(
~ long , # Removed `data = data_map()`
~ lat,
popup = ~ speed,
radius = 5 ,
stroke = FALSE,
fillOpacity = 0.8,
popupOptions = popupOptions(closeButton = FALSE)
)
})
Upvotes: 4