0
votes

since many days I can't solve my problem. At the beginning I get some data from API (I refresh API call every 5 sec to get the newest data). The data contain information about locations (lat and long) and some labels written to those locations. I want to create an object of selectInput and use choices assigned to labels. If I choose a label from a drop-down list in the selectInput object I want to filter simultaneously the next API call within 5 seconds. The main task is to filter the data visible on the map after choosing a value from the drop-down list.

Labels change every few minutes, but the location coordinates change every few seconds.

I'm using renderUI on server side and uiOutput on UI side. Looking forward for some help, thanks.

library("httr")
library("jsonlite")
library("shiny")
library("leaflet")
library("dplyr")


ui <- shinyUI(fluidPage(
  navbarPage("Title",
             tabPanel("MAP",

                      leafletOutput("mymap", width = "auto", height = "560px")
             )
  ),
  uiOutput("loc")
  )
  )

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

  autoInvalidate <- reactiveTimer(5000)

  reData <- eventReactive(autoInvalidate(), {

    # # example data
    # lat <- c(20.51,20.52,20.65)
    # long <- c(10.33,13.43,23.54)
    # labels <- c('John','Peter','Jolie')
    # data <- data.frame(lat, long, labels)

    # API call #1 response
    get_data <- GET(call1)
    get_data_text <- content(get_data, "text")
    get_data_json <- fromJSON(get_data_text, flatten = TRUE)
    data <- get_data_json$result

    # handling empty API response
    while(class(data) == "list"){
      Sys.sleep(1)
      get_trams <- GET(call1)
      get_data_text <- content(get_data, "text")
      get_data_json <- fromJSON(get_data_text, flatten = TRUE)
      data <- get_data_json$result
    }


    # saving data before filtering - purpose of getting labels for the drop-down list and
    # creating a sorted list for selectInput function
    list_of_vals <- data
    uniq_first_lines <- c("all", unique(as.character(sort(as.numeric(list_of_vals$FirstLine)))))
    sorted_factor <- factor(uniq_first_lines, levels=uniq_first_lines)
    my_new_list <- split(uniq_first_lines, sorted_factor)


    # filter data
    if(input$loc != "all") {
      data <- data %>%
      filter_at(
        vars(one_of("FirstLine")),
        any_vars(.==input$loc))
    }

    rownames(data) <- NULL


    return(list(data=data, my_new_list=my_new_list))
  }, ignoreNULL = FALSE)


  output$loc <-renderUI({
    selectInput("loc", label = h4("Choose location"),
                choices = reData()$my_new_list ,selected = "all"
    )
  })


  points <- eventReactive(autoInvalidate(), {
    cbind(reData()$trams_data$Lon, reData()$trams_data$Lat)
  },ignoreNULL = FALSE)

  labels <- eventReactive(autoInvalidate(), {
    paste("line: ", reData()$trams_data$FirstLine)
  },ignoreNULL = FALSE)

  output$mymap <- renderLeaflet({
    leaflet() %>%
      addTiles()
  })

  observeEvent(autoInvalidate(), {
    leafletProxy("mymap") %>%
      clearMarkers() %>%
      addMarkers(
        data = points(),
        label = labels()
      )
  },ignoreNULL = FALSE)
})


shinyApp(ui, server)
1
Hum...I am not sure I understand. Why not simply put your reactiveTimer(5000) in a reactive dataset and also include your selectInput() argument? Also, your example is not reproducible.MLavoie
@MLavoie You mean reactive dataset as the eventReactive function? I don't get it, where I should put that selectInput() argument. I understand reactives till some point, but here I have no idea what to do. up: I have added some example data structure, that's all what I can provide.boplight

1 Answers

0
votes

I am going with a minimal example and with the small dataset you provided. You can adapt my example for your needs but I want to show you the use of a reactive dataset so you can filter by labels.

Are you looking for something like that:

library("httr")
library("jsonlite")
library("shiny")
library("leaflet")
library("dplyr")


# # example data
lat <- c(20.51,20.52,20.65)
long <- c(10.33,13.43,23.54)
labels <- c('John','Peter','Jolie')
data <- data.frame(lat, long, labels)


ui <- shinyUI(fluidPage(
  navbarPage("Title",
             tabPanel("MAP",
                      leafletOutput("mymap", width = "auto", height = "560px")
             )
  ),
  uiOutput("labels")
)
)

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


  output$labels <- renderUI({
       selectInput("labels", label = h4("Choose label"), choices = c("John", "Peter", "Jolie") ,selected = "John")

  })


  reData <- reactive({

    autoInvalidate <- reactiveTimer(5000)
    data <- data %>% dplyr::filter(input$labels == labels)

  })

  output$mymap <- renderLeaflet({
    leaflet(reData()) %>%
      setView(10, 20, zoom = 5) %>%
      addTiles() %>%
    addMarkers()
  })

#  observeEvent(autoInvalidate(), {
 #   leafletProxy("mymap") %>%
  #    clearMarkers() %>%
   #   addMarkers(
    #    data = points(),
     #   label = labels()
    #  )
#  },ignoreNULL = FALSE)


})


shinyApp(ui, server)