微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 DTedit 中使用迷你图

如何解决如何在 DTedit 中使用迷你图

我有一个使用 DT 的闪亮应用程序,如下(代码片段):

output$table <- DT::renderDataTable({
    DT::datatable(
      data = table,escape = FALSE,rownames = FALSE,selection = "single",options = list(...),fnDrawCallback = htmlwidgets::JS('function(){HTMLWidgets.staticRender();}')
    ))) %>%
    spk_add_deps()

其中 table 中的迷你图列是使用 sparklines 函数 spk_chr 创建的。 这按预期工作,我在使用 JS fnDrawCallback 的预期列中有很好的迷你图。 我需要在 DT 中编辑对象,因此我开始使用 DT 中的编辑功能。这也有效,但在美学上并不那么令人愉悦(恕我直言)。

因此,我想开始使用 DTedit。我编写了一个 shiny 应用程序,除了 sparklines 功能外,我可以使这项工作正常进行。我正在使用 David Fong 的 DTedit 版本(版本 2.2.1,请参阅 here)。函数 dtedit 返回一个 reactiveValues 对象并且不能传递给 spk_add_deps,因为后者需要一个 htlmwidget。 我很难找到一种方法来完成这项工作。如何将迷你图所需的依赖项添加dtedit 对象? 有人可以帮忙吗?

以下是使用 DTedit 的应用程序的相关部分:

table_react <- reactiveVal(table)

table_dt <- dtedit(
  input,output,name = 'table',thedata = table_react,datatable.rownames = FALSE,# needed for the format*() functions to work
  edit.cols = edit_month,datatable.call = function(...) { DT::datatable(...) },datatable.options = list(
                      dom = "t",ordering = FALSE,paging = FALSE,autoWidth = FALSE,scrollY = "100vh",scrollCollapse = FALSE,fnDrawCallback = htmlwidgets::JS('function(){HTMLWidgets.staticRender();}'),columnDefs = list(...),callback.update = KPI.update.callback
  ) 

解决方法

这是“基本”示例的修改版本,它或多或少是独立的。

library(shiny)
library(DT)
library(magrittr)
library(sparkline)
library(DTedit)

table <- data.frame(
  id = c('spark1','spark2'),spark = c(
    spk_chr(values = 1:3,elementId = 'spark1'),spk_chr(values = 3:1,elementId = 'spark2')
  )
)

shiny::shinyApp(
  ui = shiny::fluidPage(DT::DTOutput('table')),server = function(input,output) {
    output$table = DT::renderDataTable({
      DT::datatable(
        data = table,escape = FALSE,rownames = FALSE,selection = "single",options(fnDrawCallback = htmlwidgets::JS('function(){HTMLWidgets.staticRender();}'))
      ) %>%
        sparkline::spk_add_deps()
    })
  }
)

这里是对 DTedit 执行相同操作的示例,已在当前 develop 版本(以后将变为 2.2.4)上进行测试

library(shiny)
library(DT)
library(magrittr)
library(sparkline)
library(DTedit)

table <- data.frame(
  id = c('spark1',elementId = 'spark2')
  )
)

table_react <- shiny::reactiveVal(table)

server <- function(input,output) {

  sparkline_Results <- DTedit::dtedit(
    input,output,name = 'sparkline',thedata = table,datatable.rownames = FALSE,edit.cols = c("id"),# *not* editing the sparkline column!
    datatable.call = function(...) {
      arguments <- list(...)
      arguments$escape <- 1 # escape only the first column (not the sparkline column)
      do.call(DT::datatable,arguments) %>% # call DT::datatable with modified arguments
        sparkline::spk_add_deps()
    },datatable.options = list(
      fnDrawCallback = htmlwidgets::JS('function(){HTMLWidgets.staticRender();}')
    )
  )
}

ui <- shiny::fluidPage(
  shiny::h3('Sparkline example'),shiny::uiOutput('sparkline')
)

shiny::shinyApp(ui = ui,server = server)

请注意,包含迷你图数据的列从编辑中排除,因为当前没有编辑迷你图数据的方法。

这是一个修改示例,它使用 shinyalert(2.0.0 版)允许编辑迷你图数据!请注意,此示例需要 develop 的当前 DTedit 分支(或版本 2.2.4+,当 2.2.4 发布时),因为此示例依赖于一个错误修复,当只有一个列可以编辑。

library(shiny)
library(DT)
library(magrittr)
library(sparkline)
library(shinyalert) # version 2.0.0
library(DTedit) # version 2.2.4 (when released),or current 'develop' branch

table <- data.frame(
  id = c('spark1',spark = c(
    sparkline::spk_chr(values = 1:3,sparkline::spk_chr(values = 3:1,output) {

  my.callback.actionButton <- function(data,row,buttonID) {
    # data - the current copy of 'thedata'
    # row - the row number of the clicked button
    # buttonID - the buttonID of the clicked button

    # in this case,only one action button per row,# so no need to pay attention to buttonID

    shinyalert::shinyalert(
      html = TRUE,text = shiny::tagList(
        shiny::textInput(
          "sparkvector","List of numbers",paste(as.character(1:5),collapse = ",")
        )
      ),showCancelButton = TRUE,callbackR = function(x) {
        if (x == TRUE) {
          # only if closed without the 'escape/cancel'
          temp <- table_react()
          temp[row,2] <- sparkline::spk_chr(
            as.numeric(unlist(strsplit(input$sparkvector,","))),elementId = temp[row,1]
          )
          table_react(temp)
          # since table_react is a reactive,# dtedit will 'react' to the change in table_react
        }
      }
    )
    return(data)
  }

  sparkline_Results <- DTedit::dtedit(
    input,thedata = table_react,datatable.options = list(
      fnDrawCallback = htmlwidgets::JS('function(){HTMLWidgets.staticRender();}')
    ),action.buttons = list(
      myaction = list( # the 'myaction' name is arbitrary
        columnLabel = "Spark edit",buttonLabel = "Edit spark",buttonPrefix = "sparky"
      )
    ),callback.actionButton = my.callback.actionButton
  )

  shiny::observeEvent(
    sparkline_Results$thedata,ignoreInit = TRUE,{
    # update local copy of the table when DTedit's copy is edited
      table_react(sparkline_Results$thedata)
    })
}

ui <- shiny::fluidPage(
  shinyalert::useShinyalert(),shiny::h3('Sparkline example'),server = server)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。