带有父子关系的Shiny中的可折叠数据表 [英] Collapsible Datatable in Shiny with Parent/Child relation

查看:63
本文介绍了带有父子关系的Shiny中的可折叠数据表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用Shiny创建可折叠的数据表.该代码在本地运行但不在闪亮服务器上运行时有效.我收到一条错误消息:"DataTables警告:表id = DataTables_Table_0- [<-.. data.frame ( * tmp * ,, j,value = list(list(structure(list(:替换元素2有3行,需要10"

I have a requirement to create a collapsible datatable using shiny. The code is working when run locally but not on the shiny-server. I get a error saying "DataTables warning: table id=DataTables_Table_0 - Error in [<-.data.frame(*tmp*,,j,value = list(list(structure(list(: replacement element 2 has 3 rows, need 10"

我当前使用的是1.10.4-3版本的data.table软件包

I'm currently using data.table package which is 1.10.4-3 version

代码:

       colnames(selected_df_final) <- c('tcluster_id','TIME FIRST RCVD','ALERT NAME', 'NODE ID', 'DESCRIPTION', 'MANAGER CLASS')

      mtcars_dt = data.table(selected_df_final)
      setkey(mtcars_dt, tcluster_id)

      cyl_dt = unique(mtcars_dt[, list(tcluster_id)])
      setkey(cyl_dt, tcluster_id)

      mtcars_dt = 
        mtcars_dt[, list("_details" = list(purrr::transpose(.SD))), by = list(tcluster_id)]
      mtcars_dt[, ' ' := '&oplus;']

      cyl_dt = merge(cyl_dt, mtcars_dt, all.x = TRUE )
      setcolorder(cyl_dt, c(length(cyl_dt),c(1:(length(cyl_dt) - 1))))

      ## the callback
      ## the callback
      callback_js = JS(
        "table.column(1).nodes().to$().css({cursor: 'pointer'});",
        "",
        "// make the table header of the nested table",
        "var format = function(d, childId){",
        "  if(d != null){",
        "    var html = ", 
        "      '<table class=\"display compact hover\" id=\"' + childId + '\"><thead><tr>';",
        "    for (var key in d[d.length-1][0]) {",
        "      html += '<th>' + key + '</th>';",
        "    }",
        "    html += '</tr></thead></table>'",
        "    return html;",
        "  } else {",
        "    return '';",
        "  }",
        "};",
        "",
        "// row callback to style the rows of the child tables",
        "var rowCallback = function(row, dat, displayNum, index){",
        "  if($(row).hasClass('odd')){",
        "    $(row).css('background-color', 'papayawhip');",
        "    $(row).hover(function(){",
        "      $(this).css('background-color', '#E6FF99');",
        "    }, function() {",
        "      $(this).css('background-color', 'papayawhip');",
        "    });",
        "  } else {",
        "    $(row).css('background-color', 'lemonchiffon');",
        "    $(row).hover(function(){",
        "      $(this).css('background-color', '#DDFF75');",
        "    }, function() {",
        "      $(this).css('background-color', 'lemonchiffon');",
        "    });",
        "  }",
        "};",
        "",
        "// header callback to style the header of the child tables",
        "var headerCallback = function(thead, data, start, end, display){",
        "  $('th', thead).css({",
        "    'border-top': '3px solid indigo',", 
        "    'color': 'indigo',",
        "    'background-color': '#fadadd'",
        "  });",
        "};",
        "",
        "// make the datatable",
        "var format_datatable = function(d, childId){",
        "  var dataset = [];",
        "  var n = d.length - 1;",
        "  for(var i = 0; i < d[n].length; i++){",
        "    var datarow = $.map(d[n][i], function (value, index) {",
        "      return [value];",
        "    });",
        "    dataset.push(datarow);",
        "  }",
        "  var id = 'table#' + childId;",
        "  if (Object.keys(d[n][0]).indexOf('_details') === -1) {",
        "    var subtable = $(id).DataTable({",
        "                 'data': dataset,",
        "                 'autoWidth': true,",
        "                 'deferRender': true,",
        "                 'info': false,",
        "                 'lengthChange': false,",
        "                 'ordering': d[n].length > 1,",
        "                 'order': [],",
        "                 'paging': false,",
        "                 'scrollX': false,",
        "                 'scrollY': false,",
        "                 'searching': false,",
        "                 'sortClasses': false,",
        "                 'rowCallback': rowCallback,",
        "                 'headerCallback': headerCallback,",
        "                 'columnDefs': [{targets: '_all', className: 'dt-center'}]",
        "               });",
        "  } else {",
        "    var subtable = $(id).DataTable({",
        "            'data': dataset,",
        "            'autoWidth': true,",
        "            'deferRender': true,",
        "            'info': false,",
        "            'lengthChange': false,",
        "            'ordering': d[n].length > 1,",
        "            'order': [],",
        "            'paging': false,",
        "            'scrollX': false,",
        "            'scrollY': false,",
        "            'searching': false,",
        "            'sortClasses': false,",
        "            'rowCallback': rowCallback,",
        "            'headerCallback': headerCallback,",
        "            'columnDefs': [", 
        "              {targets: -1, visible: false},", 
        "              {targets: 0, orderable: false, className: 'details-control'},", 
        "              {targets: '_all', className: 'dt-center'}",
        "             ]",
        "          }).column(0).nodes().to$().css({cursor: 'pointer'});",
        "  }",
        "};",
        "",
        "// display the child table on click",
        "table.on('click', 'td.details-control', function(){",
        "  var tbl = $(this).closest('table'),",
        "      tblId = tbl.attr('id'),",
        "      td = $(this),",
        "      row = $(tbl).DataTable().row(td.closest('tr')),",
        "      rowIdx = row.index();",
        "  if(row.child.isShown()){",
        "    row.child.hide();",
        "    td.html('&oplus;');",
        "  } else {",
        "    var childId = tblId + '-child-' + rowIdx;",
        "    row.child(format(row.data(), childId)).show();",
        "    td.html('&CircleMinus;');",
        "    format_datatable(row.data(), childId);",
        "  }",
        "});")

      ## datatable
      datatable(cyl_dt, callback = callback_js, escape = -2,
                options = list(
                  columnDefs = list(
                    list(visible = FALSE, targets = ncol(cyl_dt)),
                    list(orderable = FALSE, className = 'details-control', targets = 1),
                    list(className = "dt-center", targets = "_all")
                  )
                ))

推荐答案

我能够使其正常运行.下面是相同的闪亮服务器代码.使它工作的代码是添加SERVER = FALSE.

I was able to make it work. Below is an shiny-server code for the same. The code that made it work was adding SERVER = FALSE.

library(data.table)
library(DT)
library(shiny)

ui <- fluidPage(fluidRow(DT::dataTableOutput(width = "100%", "table")))

server <- function(input, output) {

  output$table = DT::renderDataTable({

    mtcars_dt = data.table(mtcars)
    setkey(mtcars_dt, cyl)

    cyl_dt = unique(mtcars_dt[, list(cyl)])
    setkey(cyl_dt, cyl)

    mtcars_dt = 
      mtcars_dt[, list("_details" = list(purrr::transpose(.SD))), by = list(cyl)]
    mtcars_dt[, ' ' := '&oplus;']

    cyl_dt = merge(cyl_dt, mtcars_dt, all.x = TRUE )
    setcolorder(cyl_dt, c(length(cyl_dt),c(1:(length(cyl_dt) - 1))))

    ## the callback
    callback = JS(
      "table.column(1).nodes().to$().css({cursor: 'pointer'});",
      "",
      "// make the table header of the nested table",
      "var format = function(d, childId){",
      "  if(d != null){",
      "    var html = ",
      "      '<table class=\"display compact hover\" id=\"' + childId + '\"><thead><tr>';",
      "    for (var key in d[d.length-1][0]) {",
      "      html += '<th>' + key + '</th>';",
      "    }",
      "    html += '</tr></thead></table>'",
      "    return html;",
      "  } else {",
      "    return '';",
      "  }",
      "};",
      "",
      "// row callback to style the rows of the child tables",
      "var rowCallback = function(row, dat, displayNum, index){",
      "  if($(row).hasClass('odd')){",
      "    $(row).css('background-color', 'papayawhip');",
      "    $(row).hover(function(){",
      "      $(this).css('background-color', '#E6FF99');",
      "    }, function() {",
      "      $(this).css('background-color', 'papayawhip');",
      "    });",
      "  } else {",
      "    $(row).css('background-color', 'lemonchiffon');",
      "    $(row).hover(function(){",
      "      $(this).css('background-color', '#DDFF75');",
      "    }, function() {",
      "      $(this).css('background-color', 'lemonchiffon');",
      "    });",
      "  }",
      "};",
      "",
      "// header callback to style the header of the child tables",
      "var headerCallback = function(thead, data, start, end, display){",
      "  $('th', thead).css({",
      "    'border-top': '3px solid indigo',",
      "    'color': 'indigo',",
      "    'background-color': '#fadadd'",
      "  });",
      "};",
      "",
      "// make the datatable",
      "var format_datatable = function(d, childId){",
      "  var dataset = [];",
      "  var n = d.length - 1;",
      "  for(var i = 0; i < d[n].length; i++){",
      "    var datarow = $.map(d[n][i], function (value, index) {",
      "      return [value];",
      "    });",
      "    dataset.push(datarow);",
      "  }",
      "  var id = 'table#' + childId;",
      "  if (Object.keys(d[n][0]).indexOf('_details') === -1) {",
      "    var subtable = $(id).DataTable({",
      "                 'data': dataset,",
      "                 'autoWidth': true,",
      "                 'deferRender': true,",
      "                 'info': false,",
      "                 'lengthChange': false,",
      "                 'ordering': d[n].length > 1,",
      "                 'order': [],",
      "                 'paging': false,",
      "                 'scrollX': false,",
      "                 'scrollY': false,",
      "                 'searching': false,",
      "                 'sortClasses': false,",
      "                 'rowCallback': rowCallback,",
      "                 'headerCallback': headerCallback,",
      "                 'columnDefs': [{targets: '_all', className: 'dt-center'}]",
      "               });",
      "  } else {",
      "    var subtable = $(id).DataTable({",
      "            'data': dataset,",
      "            'autoWidth': true,",
      "            'deferRender': true,",
      "            'info': false,",
      "            'lengthChange': false,",
      "            'ordering': d[n].length > 1,",
      "            'order': [],",
      "            'paging': false,",
      "            'scrollX': false,",
      "            'scrollY': false,",
      "            'searching': false,",
      "            'sortClasses': false,",
      "            'rowCallback': rowCallback,",
      "            'headerCallback': headerCallback,",
      "            'columnDefs': [",
      "              {targets: -1, visible: false},",
      "              {targets: 0, orderable: false, className: 'details-control'},",
      "              {targets: '_all', className: 'dt-center'}",
      "             ]",
      "          }).column(0).nodes().to$().css({cursor: 'pointer'});",
      "  }",
      "};",
      "",
      "// display the child table on click",
      "table.on('click', 'td.details-control', function(){",
      "  var tbl = $(this).closest('table'),",
      "      tblId = tbl.attr('id'),",
      "      td = $(this),",
      "      row = $(tbl).DataTable().row(td.closest('tr')),",
      "      rowIdx = row.index();",
      "  if(row.child.isShown()){",
      "    row.child.hide();",
      "    td.html('&oplus;');",
      "  } else {",
      "    var childId = tblId + '-child-' + rowIdx;",
      "    row.child(format(row.data(), childId)).show();",
      "    td.html('&CircleMinus;');",
      "    format_datatable(row.data(), childId);",
      "  }",
      "});")

    ## datatable
    datatable(cyl_dt, callback = callback, escape = -2,
              options = list(
                columnDefs = list(
                  list(visible = FALSE, targets = ncol(cyl_dt)),
                  list(orderable = FALSE, className = 'details-control', targets = 1),
                  list(className = "dt-center", targets = "_all")
                )
              ))
},server = FALSE)
}

shinyApp (ui = ui, server = server)

这篇关于带有父子关系的Shiny中的可折叠数据表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆