Eadan Fahey
Eadan Fahey

Reputation: 373

R Shiny Leaflet - clearShapes() not working?

I have a dataset (tst_geo.csv) of the form:

lat, lon, time
10, 20, 1
10, 20, 2
10, 20, 3
40, 40, 4
40, 40, 5
40, 40, 6
0, 0, 7
0, 0, 8
0, 0, 9

R code:

library(shiny)
library(leaflet)
library(plyr)

ui <- fluidPage(
    sidebarLayout(
        
        sidebarPanel(
            uiOutput("slider")
        ),
        mainPanel(
            leafletOutput("map")
        )
    )
)

server <- function(input, output, session){
    
    df <- read.csv("tst_geo.csv", header=TRUE)
    df['time'] <- as.numeric(df$time)
    
    #make dynamic slider
    output$slider <- renderUI({
        sliderInput("time_span", "Time Span", step=1, min=min(df$time), 
                    max=max(df$time), value = c(min(df$time), max(df$time)))
    })
    
    filter_df <- reactive({
        df[df$time >= input$time_span[1] & df$time <= input$time_span[2], ]
    })
    
    output$map <- renderLeaflet(
        leaflet() %>% addTiles()
    )
    
    observe({
        points_df <- ddply(filter_df(), c("lat", "lon"), summarise, count = length(timestamp))
        cat(nrow(points_df))
        leafletProxy("map", data = points_df) %>% clearShapes() %>% addCircles()
    })
    
}

shinyApp(ui, server)

I have a slider to only show points within a certain time range.

However, inside the observe function the points are not being cleared when I call clearShapes().

Do you have any ideas why this is happening?

Upvotes: 1

Views: 835

Answers (1)

Yihui Xie
Yihui Xie

Reputation: 30174

The culprit is renderUI() in this case. Because you used renderUI(), the rendering of the slider is delayed. By the time the observer runs for the first time, the slider is not there yet, and input$time_span is initially NULL, so filter_df() returns an empty data frame. I don't see a particular reason of using renderUI() in this case (perhaps you have a reason), and you can either just move sliderInput() to ui.R, or check if (is.null(input$time_span)) before you add circles to the map, or change observe() to observeEvent() (if you are using a recent version of shiny):

observeEvent(input$time_span, {
    points_df <- ddply(filter_df(), c("lat", "lon"), summarise, count = length(timestamp))
    cat(nrow(points_df))
    leafletProxy("map", data = points_df) %>% clearShapes() %>% addCircles()
})

Upvotes: 3

Related Questions