问题描述
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)