Search code examples
rshinygooglevisdt

Update data in shiny application without refreshing the whole application


I have an application for real time data visualization build with R shiny library. I do periodic data reload from file using reactivePoll function. What I do not like about this is that whenever data reloads the whole application refreshes.

So for example if I have DT table output with selection and I use this selection input$table_rows_selected it resets to NULL whenever data reloads which is not user-friendly at all.

Is it overall possible to change data output without interrupting user?

UPDATE.

Can this be achieved with any other package for displaying tables - googleVis or other?

Working example.

library(shiny)
library(DT)

runApp(shinyApp(
  ui = fluidPage(dataTableOutput('table')),
  server = function(input, output, session) {
    pollData <- reactivePoll(4000, session,
                             checkFunc = function(){ Sys.time() },
                             valueFunc = function(){ data.frame(id = sample(letters[1:3]), a = runif(3), b = runif(3), c = runif(3)) })
    output$table <- renderDataTable({pollData()})
    proxy <- dataTableProxy('table')
    observeEvent(pollData(), {
      selectRows(proxy, input$table_rows_selected)
    })}
))

I have taken this example from @NicE answer and added id column. The point is that @NicE answer is OK if one needs certain row to be selected when that row is identified by the row number.

Now suppose I need a row to be selected when that row is identified by some id value. That is if I select a row with id equal b, then the next time data reloads I want the row to be selected with the same id value.


Solution

  • You could use a dataTableProxy to select rows when the datable is created after a pollData update. Here's an example, the dataframe is refreshed every 4 seconds:

    library(shiny)
    library(DT)
    
    ui <- fluidPage(dataTableOutput("table"))
    
    server <- function(input,output,session){
            values <- reactiveValues()
            pollData <- reactivePoll(4000, session,
                                     checkFunc=function(){
                                             Sys.time()
                                     },
                                     valueFunc=function(){                             
                                             data.frame(a=sample(c("a","b","c"),3),b=runif(3),c=runif(3),stringsAsFactors = F)
                                     })
    
            output$table <- renderDataTable({ pollData()})
    
            observe({
                    values$selected <- pollData()$a[input$table_rows_selected]
            })
    
            proxy = dataTableProxy('table')
            observeEvent(pollData(),{
                    selectRows(proxy, which(pollData()$a %in% values$selected))
            })
    }
    
    shinyApp(ui,server)
    

    Update: on the above code, when the data changes, the selected rows are the ones that have the same first column as previously.