使用 DT 中的样式渲染其他列中的文本

问题描述 投票:0回答:1

我有一个包含值及其关联增量的表,并且希望在单个列中显示这两个信息。

下面是一个可重现的示例,其中 ab 是当前值,它们的增量是 a.deltab.delta。我不想只显示 ab 中的值,例如,如果 a=12 和 a.delta=7,我想显示 '(+7) 12' 并设置增量值的样式(如果为负则为红色,如果为正则为绿色),但保持列按 a 的值排序。

library(tibble)
library(dplyr)
library(DT)

# data
set.seed(99)
df <- tibble::tibble(
  a = runif(10, min = 0, max = 20),
  b = runif(10, min = 0, max = 20),
  a.prev = runif(10, min = 0, max = 20),
  b.prev = runif(10, min = 0, max = 20)
) %>%
  dplyr::mutate(a.delta = a - a.prev, b.delta = b - b.prev) %>%
  dplyr::mutate(dplyr::across(dplyr::everything(), ~ round(.x, 0))) %>%
  dplyr::select(!dplyr::ends_with(".prev"))

# table with all data
DT::datatable(
  df,
  class = "display compact nowrap",
  options = list(dom = "t", paging = FALSE, searching = FALSE)
)

我尝试过使用 HTML 和

escape=FALSE
,但排序不再起作用,而且样式变得更难。这可以通过 JS 回调来完成吗?不幸的是,我对 JS 不太了解,但从其他例子来看,我怀疑这是可能的。

r datatables dt
1个回答
0
投票

这是一种使用自定义 JS 渲染函数的可能选项。为了完成这项工作,需要一些额外的数据整理,即我们必须将值和增量嵌套在一个列表中,该列表在幕后将转换为 JS 对象:

library(dplyr, warn = FALSE)
library(DT)

set.seed(99)

df <- tibble(
  a = runif(10, min = 0, max = 20),
  b = runif(10, min = 0, max = 20),
  a.prev = runif(10, min = 0, max = 20),
  b.prev = runif(10, min = 0, max = 20)
) %>%
  mutate(a.delta = a - a.prev, b.delta = b - b.prev) %>%
  mutate(across(everything(), ~ round(.x, 0))) %>%
  select(!ends_with(".prev")) |>
  mutate(row = row_number()) |>
  tidyr::nest(.by = row, a = starts_with("a"), b = starts_with("b")) |>
  select(-row) |>
  mutate(
    across(c(a, b), ~ lapply(.x, \(x) {
      x <- as.list(x)
      names(x) <- c("value", "delta")
      x
    }))
  )


DT::datatable(
  df,
  options = list(
    paging = FALSE,
    searching = FALSE,
    columnDefs =
      list(
        list(
          targets = 1:2,
          render = list(
            "_" = JS(
              "
              function ( data, type, row ) {
                if ( type === 'display' ) { // Data to display
                  let color = 'red';
                  if (data.delta > 0) color = 'green';
                  return '(<span style=\"color: ' + color + ';\">' + 
                    data.delta + '</span>) ' + 
                    data.value;
                }
                return data.value;
              }
              "
            )
          )
        )
      )
  )
)

© www.soinside.com 2019 - 2024. All rights reserved.