我正在尝试将总计添加到数据表页脚。使用来自不同来源的代码,我使用Shiny编写了以下应用程序。问题是,当我运行它时,会出现以下消息:
“处理......”
并永远留在那里。
我的猜测是JS()代码,但无法调试。
library(shiny)
library(DT)
library(htmltools)
ui <- fluidPage(
fluidRow(
column(9, DT::dataTableOutput('withtotal'))
)
)
server <- function(input, output, session) {
# server-side processing
mtcars2 = mtcars[, 1:8]
#sketch <- htmltools::withTags(table(tableHeader(mtcars2), tableFooter(mtcars2)))
sketch = htmltools::withTags(table(tableFooter(c("",0,0,0,0,0,0,0))))
opts <- list( footerCallback = JS("function ( row, data, start, end, display ) {",
"var api = this.api();",
"var intVal = function ( i ) {",
"return typeof i === 'string' ?",
"i.replace(/[\\$,]/g, '')*1 :",
"typeof i === 'number' ?",
"i : 0;",
"};",
"if (api.column(COLNUMBER).data().length){",
"var total = api",
".column( COLNUMBER )",
".data()",
".reduce( function (a, b) {",
"return intVal(a) + intVal(b);",
"} ) }",
"else{ total = 0};",
"if (api.column(COLNUMBER).data().length){",
"var pageTotal = api",
".column( COLNUMBER, { page: 'current'} )",
".data()",
".reduce( function (a, b) {",
" return intVal(a) + intVal(b);",
"} ) }",
"else{ pageTotal = 0};",
"$( api.column(COLNUMBER).footer() ).html(",
"'$'+pageTotal",
");",
"}"))
output$withtotal = DT::renderDataTable(DT::datatable(mtcars2,container = sketch, options = opts))
}
options(shiny.error = browser)
# Run the application
shinyApp(ui = ui, server = server)
答案 0 :(得分:3)
您似乎正在使用我在shiny DataTables footer Callback sums中执行的相同示例程序 所以我对页脚回调问题的解决方案如下。这是我发现在逐列操作中最容易操作的。
library(shiny)
library(DT)
ui <- fluidPage(
title = 'Select Table Rows',
hr(),
h1('A Server-side Table'),
fluidRow(
column(9, DT::dataTableOutput('x3'))
)
)
server <- function(input, output, session) {
# server-side processing
mtcars2 = mtcars[, 1:8]
sketch <- htmltools::withTags(table(
class = "display",
style = "bootstrap",
tableHeader(colnames(mtcars2)),
tableFooter(colnames(mtcars2))
))
output$x3 = DT::renderDataTable(DT::datatable(mtcars2,
container = sketch,
extensions = 'Buttons',
options = list(
scrollX = TRUE,
scrollY = TRUE,
pageLength = 10,
order = list(list(1, 'asc')),
dom = 'Blrtip',
buttons = c('copy', 'csv', 'excel', 'pdf', 'print'),
footerCallback = JS(
"function( tfoot, data, start, end, display ) {",
"var api = this.api(), data;",
"total = api.column( 1, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
"total1 = api.column( 2, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
"total2 = api.column( 3, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
"total3 = api.column( 4, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
"total4 = api.column( 5, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
"total5 = api.column( 6, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
"total6 = api.column( 7, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
"total7 = api.column( 8, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
"$( api.column( 1 ).footer() ).html(total.toFixed(2));
$( api.column( 2 ).footer() ).html(total1.toFixed(2));
$( api.column( 3 ).footer() ).html(total2.toFixed(2));
$( api.column( 4 ).footer() ).html(total3.toFixed(2));
$( api.column( 5 ).footer() ).html(total4.toFixed(2));
$( api.column( 6 ).footer() ).html(total5.toFixed(2));
$( api.column( 7 ).footer() ).html(total6.toFixed(2));
$( api.column( 8 ).footer() ).html(total7.toFixed(2));",
"}"
))
))
}
shinyApp(ui = ui, server = server)
答案 1 :(得分:1)
这是不使用Shiny的版本。我使用了与上述@gscott相同的JavaScript,但这是用于独立表的。我在RMarkdown文档中使用了它。我为此苦苦挣扎的关键是container
参数,该参数将页脚添加到表中。
library(htmlwidgets)
library(DT)
library(htmltools)
sketch <- htmltools::withTags(table(
tableHeader(colnames(mtcars)),
tableFooter(c(0,0,0,0,0,0,0,0,0,0,0,0))
))
jsCode <- "function(row, data, start, end, display) {
var api = this.api(), data;
total = api.column(7, {page: 'current'}).data().reduce( function(a, b) { return a +
b}, 0);
total2 = api.column(6, {page: 'current'}).data().reduce( function(a, b) { return a
+ b}, 0);
total3 = api.column(2, {page: 'current'}).data().reduce( function(a, b) { return a
+ b}, 0);
$( api.column(7).footer() ).html('Total: ' + total.toFixed(2));
$( api.column(6).footer() ).html('Total: ' + total2.toFixed(2));
$( api.column(2).footer() ).html('Total: ' + total3.toFixed(2))
}"
DT::datatable(mtcars, container = sketch, options=list(scrollY=300, scrollX=TRUE, scroller=TRUE, footerCallback = JS(jsCode)))
答案 2 :(得分:0)
我设法通过上面的答案解决了相同的问题,下面是我的实现,以减少重复的JavaScript代码的数量。
我使用columns().eq(0).each()
遍历各列,然后汇总数据,并将结果添加到页脚中。
library(shiny)
library(DT)
ui <- fluidPage(
title = 'Select Table Rows', hr(), h1('A Server-side Table'),
fluidRow(
column(9, DT::dataTableOutput('x3'))
)
)
server <- function(input, output, session) {
mtcars2 = mtcars[, 1:8]
sketch <- htmltools::withTags(table(
class = "display", style = "bootstrap",
tableHeader(colnames(mtcars2)),
tableFooter(colnames(mtcars2))
))
output$x3 = DT::renderDataTable(DT::datatable(mtcars2,
container = sketch,
extensions = 'Buttons',
options = list(
scrollX = TRUE, scrollY = TRUE,
pageLength = 10, order = list(list(1, 'asc')),
dom = 'Blrtip', buttons = c('copy', 'csv', 'excel', 'pdf', 'print'),
footerCallback = JS(
"function( tfoot, data, start, end, display ) {",
"var api = this.api(), data;",
"api.columns().eq(0).each( function(index) {",
"var col = api.column(index);",
"if(index == 0) return $(api.column(index).footer()).html('Total')",
"var data = col.data();",
"total = data.reduce( function(a, b) { return a + b }, 0 );",
"$( api.column(index).footer() ).html(total.toFixed(2));",
"})",
"}"
))
))
}