【问题标题】:How To Add totals to a DT::datatable?如何将总计添加到 DT::datatable?
【发布时间】:2017-08-13 12:24:49
【问题描述】:

我正在尝试将总计添加到数据表页脚。使用来自不同来源的代码,我使用 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)

【问题讨论】:

标签: javascript r shiny dt


【解决方案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】:

    看起来您使用的示例程序与我在 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)
    

    【讨论】:

      【解决方案3】:

      我设法用上面的答案解决了同样的问题,以下是我减少重复 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));",
                                              "})",
                                    "}"
                            ))
              ))
      }
      

      【讨论】:

        猜你喜欢
        • 2017-05-16
        • 2020-12-17
        • 1970-01-01
        • 2010-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 2012-10-25
        相关资源
        最近更新 更多