#javascript #r #datatables #dt
#javascript #r #таблицы данных #dt
Вопрос:
Я использовал информацию из https://github.com/rstudio/shiny-examples/issues/9 для создания дочерних таблиц в DT datatable. Теперь я пытаюсь расширить этот код, чтобы получить большие дочерние таблицы. Почему-то большие дочерние таблицы отображаются не так хорошо. когда я нажимаю, чтобы развернуть, я думаю, что адресуется неправильная подтаблица.
Ниже вы можете найти мой код:
require(tibble)
require(tidyr)
require(dplyr)
require(DT)
bla = tibble(' '='amp;oplus;', name=c("N", "Unbefristet", "Befristet", "keine Angabe"),
val = c(2001, "85.72 %", "14.19 %", "3 %"),
bla = list(tibble(' '='amp;oplus;', name="test", val=190, bla = list(tibble(name="lol", val=120))),
tibble(' '='amp;oplus;', name="lala", val="34 %", bla = list(tibble(name="lol", val=120))),
tibble(' '='amp;oplus;', name=c("N", "dumm", "tra", "ra"), val=c(283, "22.66 Monate", "4 %", "3 %"), bla = list(tibble(name="lol", val=120))),
tibble(' '='amp;oplus;', name=c("N", "dumm", "tra", "ra"), val=c(23,355,12,124), bla = list(tibble(name="lol", val=120)))))
nested_columns <- which(sapply(bla,class)=="list") %>% setNames(NULL)
not_nested_columns <- which(!(seq_along(bla) %in% c(1,nested_columns)))
not_nested_columns_str <- not_nested_columns %>% paste(collapse="].replace(' ', '_') '_' d[") %>% paste0("d[",.,"].replace(' ', '_').replace('.','_').replace('%', '_')")
callback <- paste0("
table.column(1).nodes().to$().css({cursor: 'pointer'});
var myid = 1
// Format data object (the nested table) into another table
var format = function(d, myid) {
if(d[4] != null){
var result = ('<table id="child_' myid '">').replace('.','_') '<thead style=display:none;><tr>'
for (var col in d[",nested_columns,"]){
result = '<th>' col '</th>'
}
result = '</tr></thead></table>'
return result
}else{
return '';
}
}
var format_datatable = function(d, myid) {
var dataset = [];
for (i = 0; i < d[",nested_columns,"]['val'].length; i ) {
var datarow = [];
for (var col in d[",nested_columns,"]){
datarow.push(d[",nested_columns,"][col][i])
}
dataset.push(datarow)
}
var subtable = $(('table#child_' myid).replace('.','_')).DataTable({
'data': dataset,
'autoWidth': true,
'deferRender': true,
'info': false,
'lengthChange': false,
'ordering': false,
'paging': false,
'scrollX': false,
'scrollY': false,
'searching': false,
'columnDefs': [{'targets': 0, 'orderable': false, 'className': 'details-control'},
{'targets': 3, 'visible': false}]
});
};
table.on('click', 'td.details-control', function() {
var td = $(this), row = table.row(td.closest('tr'));
if (row.child.isShown()) {
row.child.hide();
td.html('amp;oplus;');
} else if($(this).html().charCodeAt(0)==8853){
myid
row.child(format(row.data(), myid)).show();
td.html('amp;CircleMinus;');
format_datatable(row.data(), myid)
}
});"
)
datatable(
bla,
escape = -2, # raw HTML in column 2
options = list(
columnDefs = list(
list(visible = FALSE, targets = c(0,nested_columns) ), # Hide row numbers and nested columns
list(orderable = FALSE, className = 'details-control', targets = 1) # turn first column into control column
)
),
callback = JS(callback)
)
Есть идеи, в чем моя ошибка в этом коде? Заранее спасибо.
Ответ №1:
Вот пример. Я надеюсь, что это поможет.
library(DT)
## data
dat <- data.frame(
Sr = c(1.5, 2.3),
Description = c("A - B", "X - Y")
)
## details of row 1
subsubdat1 <- data.frame(
Ref = c("UVW", "PQR"),
Case = c(99, 999),
stringsAsFactors = FALSE
)
subdat1 <- data.frame(
Chromosome = "chr18",
SNP = "rs2",
details = I(list(purrr::transpose(subsubdat1))),
stringsAsFactors = FALSE
)
subdat1 <- cbind(" " = "amp;oplus;", subdat1, stringsAsFactors = FALSE)
## details of row 2
subdat2 <- data.frame(
Chromosome = c("chr19","chr20"),
SNP = c("rs3","rs4"),
stringsAsFactors = FALSE
)
## merge the row details
subdats <- lapply(list(subdat1, subdat2), purrr::transpose)
## dataframe for the datatable
Dat <- cbind(" " = "amp;oplus;", dat, details = I(subdats))
## the callback
callback = JS(
"table.column(1).nodes().to$().css({cursor: 'pointer'});",
"// Format the nested table into another table",
"var childId = function(d){",
" var tail = d.slice(2, d.length - 1);",
" return 'child_' tail.join('_').replace(/[\s|\.]/g, '_');",
"};",
"var format = function (d) {",
" if (d != null) {",
" var id = childId(d);",
" var html = ",
" '<table class="display compact" id="' id '"><thead><tr>';",
" for (var key in d[d.length-1][0]) {",
" html = '<th>' key '</th>';",
" }",
" html = '</tr></thead></table>'",
" return html;",
" } else {",
" return '';",
" }",
"};",
"var rowCallback = function(row, dat, displayNum, index){",
" if($(row).hasClass('odd')){",
" for(var j=0; j<dat.length; j ){",
" $('td:eq(' j ')', row).css('background-color', 'papayawhip');",
" }",
" } else {",
" for(var j=0; j<dat.length; j ){",
" $('td:eq(' j ')', row).css('background-color', 'lemonchiffon');",
" }",
" }",
"};",
"var headerCallback = function(thead, data, start, end, display){",
" $('th', thead).css({",
" 'border-top': '3px solid indigo',",
" 'color': 'indigo',",
" 'background-color': '#fadadd'",
" });",
"};",
"var format_datatable = function (d) {",
" 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(d);",
"console.log(d);",
" 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,",
" '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,",
" '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'});",
" }",
"};",
"table.on('click', 'td.details-control', function () {",
" var tbl = $(this).closest('table');",
" var td = $(this),",
" row = $(tbl).DataTable().row(td.closest('tr'));",
" if (row.child.isShown()) {",
" row.child.hide();",
" td.html('amp;oplus;');",
" } else {",
" row.child(format(row.data())).show();",
" td.html('amp;CircleMinus;');",
" format_datatable(row.data());",
" }",
"});")
## datatable
datatable(Dat, callback = callback, escape = -2,
options = list(
columnDefs = list(
list(visible = FALSE, targets = ncol(Dat)),
list(orderable = FALSE, className = 'details-control', targets = 1),
list(className = "dt-center", targets = "_all")
)
))
Комментарии:
1. Как мы будем обрабатывать те случаи, когда некоторые строки имеют дочерние, а некоторые нет?
Ответ №2:
Подход, который мы используем классически, — это data.frame, однако это плохой подход.
Вы должны использовать библиотеку library (data.table), а не data.frame. Также необходимо открыть браузер, чтобы увидеть результаты.