Shiny for R DT:如何读取/保留页面长度和列可见性

时间:2016-07-04 10:18:39

标签: r datatables shiny

我对这个应用程序很新,所以请原谅我,如果它是显而易见的。我有一个可以根据地图中心重新计算的数据表。它工作正常。但是,我想阅读并保留(保留)某些设置:即页面长度和列可见性。目前,如果用户每页更改20个条目并移动地图,则会使用默认页面长度和列可视(使用按钮中的colvis)重新呈现它。我想我可以将它存储在某个变量中并在重新渲染表时检索它,但不知道如何从选项内部读取。 它内置于R Studio for Shiny 有什么想法吗?

编辑:我使用选项stateSave = TRUE获取有关页面长度和列可见性的数据,然后读取输入$ Btable_state $ length(我可以读取哪些列可见),但现在我的问题是:当re时 - 渲染表首先转到NULL值,覆盖输入$ Btable_state中存储的内容。只有在更改过滤器而不是通过重新呈现表本身的活动来改变它时,我如何捕获并影响它?

EDIT2:由于我的应用程序需要连接到我的Google工作表,因此无法复制的内容可以通过以下Github示例(vnijs / dt_state)进行尝试。如何在重新排序列时保留非默认页面长度(例如50)(但不将操作链接到selectizeInput,只保留最后一个正确的状态)

#ui.r
shinyUI(fluidPage(
  sidebarLayout(
    sidebarPanel(
      uiOutput("ui_view_vars"),
      tags$a(id = "refresh", href = "#", class = "action-button",
             list(icon("refresh"), "Clear state"),
             onclick = "window.location.reload();")
    ),
    mainPanel(
      tabPanel("View", DT::dataTableOutput("dataviewer")

      )
    )
  )
))

#server.r
library(shiny)
library(DT)

dat <- iris

## store state in global environment for now
if (!exists("r_state")) r_state <- list()

## Only used from a 'clean' start
r_state$dataviewer_search_columns <- list("","2.5...4","","","[\"setosa\"]")

shinyServer(function(input, output, session) {
  output$ui_view_vars <- renderUI({
    vars <- colnames(dat)

    ## using selectizeInput with drag_drop and DT
    selectizeInput("view_vars", "Select variables to show:", choices  = vars,
                   selected = vars, multiple = TRUE,
                   options = list(plugins = list('remove_button', 'drag_drop')))
  })

  ## make nested list
  mknl <- function(x) list(search = x)

  observeEvent(input$dataviewer_search_columns, {
    r_state$dataviewer_search_columns <<- input$dataviewer_search_columns
  })

  observeEvent(input$dataviewer_state, {
    r_state$dataviewer_state <<- input$dataviewer_state
  })

  observeEvent(input$refresh, {
    r_state <<- list()
  })

  output$dataviewer <- DT::renderDataTable({
    req(input$view_vars)

    search <- r_state$dataviewer_state$search$search
    if (is.null(search)) search <- ""

    DT::datatable(iris[,input$view_vars],
                  filter = list(position = "top", clear = TRUE),
                  rownames = FALSE,
                  selection = "none",
                  options = list(
                    stateSave = TRUE,
                    searchCols = lapply(r_state$dataviewer_search_columns, mknl),
                    search = list(search = search, regex = TRUE),
                    order = {if (is.null(r_state$dataviewer_state$order)) list()
                      else r_state$dataviewer_state$order},
                    processing = FALSE
                  ),
                  callback = DT::JS("$(window).unload(function() { table.state.clear(); })")
    )
  })

  output$tbl_col_search <- renderPrint(input$dataviewer_search_columns)

})

2 个答案:

答案 0 :(得分:1)

好的,看一下下面的例子,它应该保留你的分页。请注意,我添加了一个按钮,它应该从头开始将所有内容渲染到第一个值。请查看A client-side table示例和2.2 DataTables Information页面。

rm(list=ls())
library(shiny)
library(DT)

ui <- basicPage(actionButton("Go","Go"),DT::dataTableOutput('x1'))

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

  tableparams <- reactiveValues()
  observeEvent(input$Go,{
    if(is.null(input$x1_rows_current)){
      tableparams$pageLength <- 5
    }
    else{
      tableparams$pageLength <- length(input$x1_rows_current)
    }
  })
  my_data <- eventReactive(input$Go,{iris})
  output$x1 = DT::renderDataTable(datatable(my_data(),options = list(pageLength = tableparams$pageLength)))
})
shinyApp(ui = ui, server = server)

答案 1 :(得分:1)

我也有类似的需求,这些是我的发现:

  • 使用从当前行计算的方法自动查看页面长度值将需要一个反应式表达式(而不是按钮)。但这是行不通的,因为在刷新表时当前行将变为无效,这会阻止反应式表达式求值(它将停止,您不能通过检查null来跳过它)

  • 您实际的原始解决方案可以更好地工作,但是我们需要更具体一些,观察页面长度的变化而不是整个状态。 observeEvent(input$dataviewer_state$length。您的问题是NULL触发了该事件。也许是闪亮的更新,现在observeEvent默认不会被NULL触发。在ignoreNULL中查看有关observeEvent的帮助

  • 当使用stateSave = TRUE时,它将状态保存在html5本地存储中,该状态将在整个会话中保留,即使R全局环境为空,也可能使用户感到困惑。我使用stateDuration = -1来使用会话存储而不是本地存储。