Here is a modified version of the 'basic' example which is more-or-less self-contained.
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()
})
}
)
and here is an example of doing the same with DTedit
, tested on current develop
version (which will later become 2.2.4
)
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')
)
)
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)
Note that the column containing the sparkline data is excluded from editing, as there is no current method to edit sparkline data.
And here is some a modified example which uses shinyalert
(version 2.0.0) to allow sparkline data to be edited! Note that this example requires the current develop
branch of DTedit
(or version 2.2.4+, when 2.2.4 is released), as this example relies on a bugfix to an error which occurs when only one column can be edited.
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', 'spark2'),
spark = c(
sparkline::spk_chr(values = 1:3, elementId = 'spark1'),
sparkline::spk_chr(values = 3:1, elementId = 'spark2')
)
)
table_react <- shiny::reactiveVal(table)
server <- function(input, 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, output,
name = 'sparkline',
thedata = table_react,
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();}')
),
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'),
shiny::uiOutput('sparkline')
)
shiny::shinyApp(ui = ui, server = server)