Update data in shiny application without refreshing the whole application
Asked Answered
C

1

7

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.

Claviform answered 10/3, 2016 at 8:16 Comment(6)
This is very common with DT package. You will need to build some custom JS to take care of that. Alternatively you can use xtable as the blinking isnt that noticeable. have a look here #26977360Champion
Is the data reload just adding new lines or updating already existing values? You could use dataTableProxy to change the table without re-rendering it. If you just want the table_rows_selected to stay on your new table, you can also set them programatically after updating the data.Zacarias
It can be a new table with few rows changed but most of the time it will be value updating. @Zacarias can you explain what do you mean by "set them programatically" part?Claviform
I would suggest doing something like the experience of editing your question on stackoverflow. A banner pops up that tells the user new data is available. User clicks the banner to manually update the data table. Of course this only works if your data update relatively infrequently.Calamity
Can you provide a working example?Sopping
Added a working example.Claviform
Z
11

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.

Zacarias answered 16/3, 2016 at 13:37 Comment(5)
Just a note that this requires the development version of DT, as the dataTableProxy command is not available in the release version. You need devtools::install_github('rstudio/DT')Calamity
Thank you for your answer. Could you revise your answer based on my update of the question? The problem is that I need a row that is identified by some id value.Claviform
Just save the id value, something like save <- pollData()[idvar,input$table_rows_selected] and select them with which(pollData()[idvar,]==save)Subrogate
@Subrogate can you be more specific, where should I put those lines of code?Claviform
I updated the code to do what you want, if the user selects a row with an "b" in column a of the sample data, this row will be selected when the data changes.Zacarias

© 2022 - 2024 — McMap. All rights reserved.