R DT覆盖默认选择颜色

时间:2019-06-12 18:15:35

标签: css r shiny datatables dt

之前也有类似的问题问 R Shiny DataTable selected row color Background color of DT::datatable in shiny DT datatable selected row color: inconsistent behavior on IE and chrome

但是,在我的情况下,上述解决方案均无效。

我将DT表放在仪表板的侧边栏中,因为我想使用该表来控制其他页面的行为,并且希望该表始终可见。

这是示例代码

if (!require("pacman")) install.packages("pacman")
pacman::p_load(shiny, shinydashboard, DT, data.table, ggplot2)
sidebar_width <- 260
header <- dashboardHeader(title = "Dashboard", 
                          titleWidth = sidebar_width, 
                          dropdownMenuOutput("messageMenu"))
sidebar <- dashboardSidebar(
  width = sidebar_width,
  sidebarMenu(
    id = "tabs",
    menuItem("menu 1", icon = icon("bar-chart-o"), tabName = "charts"
             ),
    br(), br(), br(),
    fluidRow(
      # tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "www/styles.css")),
      column(11, offset = 0, DTOutput("control_dt"))
    )
  ))
body <- dashboardBody()
ui <- dashboardPage(header, sidebar, body,skin = "green")
server <- function(input, output, session) {
  output$control_dt <- renderDT({
    DT::datatable(mtcars[1:10, 1:2], 
                  selection = list(mode = "multiple",
                                       selected = 1,
                                       target = 'row'),
                  options = list(
                    columnDefs = list(list(className = 'dt-center',
                                           targets = "_all")),
                    dom = "t",
                    pageLength = 10),
                  style = "bootstrap",
                  class = "table-condensed",
                  rownames = TRUE
                  ) %>%
      formatStyle("cyl", target = 'row',
                  color = styleEqual(c(4, 6, 8),
                                     c("red", "gray", "yellow")))
  })
}
shinyApp(ui, server)

我的问题是我根据行的值对行使用了不同的颜色。选择一行后,它将始终使用固定的背景颜色和颜色,因此我的自定义颜色会丢失。

由于自定义颜色是根据数据/代码动态计算的,因此我不能仅将其硬编码在CSS中。在应用中找到的选择器与之前的答案不同,因为我为DT使用了引导程序样式,

.table.dataTable tbody td.active, .table.dataTable tbody tr.active td {
    background-color: rgb(0, 117, 176);
    color: white;
}

现在,我尝试使用可替换背景颜色的自定义CSS,但是我不知道如何取消设置白色并使计算出的颜色生效。我尝试了color:unset,但没有用。

指定的颜色是由使用数据表回调的DT格式函数生成的,然后在行元素中进行了定义:

<tr role="row" class="even active" style="color: rgb(252, 141, 98);">
<td class=" dt-center">B</td>
<td class=" dt-center">20</td>
<td class=" dt-center">4</td></tr>

2 个答案:

答案 0 :(得分:0)

我唯一的解决方案是使用行回调将类添加到td,并在CSS中设置!important

更新: 我有一个更简单的解决方案,请参阅底部。

library(shiny)
library(shinydashboard)
library(DT)

rowCallback <- c(
  "function(row, data, displayNum, displayIndex){", 
  "  var x = data[2];", # 2 is the index of the 'cyl' column
  "  if(x == 4){",
  "    $('td', row).addClass('red');",
  "  } else if(x == 6){",
  "    $('td', row).addClass('gray');",
  "  } else if(x == 8){",
  "    $('td', row).addClass('yellow')",
  "  }",
  "}"
)

css <- "
table.dataTable tbody tr td.red {color: red !important}
table.dataTable tbody tr td.gray {color: gray !important}
table.dataTable tbody tr td.yellow {color: yellow !important}
"

sidebar_width <- 260
header <- dashboardHeader(title = "Dashboard", 
                          titleWidth = sidebar_width, 
                          dropdownMenuOutput("messageMenu"))

sidebar <- dashboardSidebar(
  width = sidebar_width,
  sidebarMenu(
    id = "tabs",
    menuItem("menu 1", icon = icon("bar-chart-o"), tabName = "charts"
    ),
    br(), br(), br(),
    fluidRow(
      tags$head(tags$style(HTML(css))),
      column(11, offset = 0, DTOutput("control_dt"))
    )
  ))

body <- dashboardBody()

ui <- dashboardPage(header, sidebar, body,skin = "green")

server <- function(input, output, session) {
  output$control_dt <- renderDT({
    DT::datatable(mtcars[1:10, 1:2], 
                  selection = list(mode = "multiple",
                                   selected = 1,
                                   target = 'row'),
                  options = list(
                    rowCallback = JS(rowCallback),
                    columnDefs = list(list(className = 'dt-center',
                                           targets = "_all")),
                    dom = "t",
                    pageLength = 10),
                  style = "bootstrap",
                  class = "table-condensed",
                  rownames = TRUE
    ) 
  })
}

shinyApp(ui, server)

更新

我刚刚找到了一个更简单的解决方案,不需要行回调:

css <- "table.table.dataTable tbody tr.active td {color: unset}"

fluidRow(
  tags$head(tags$style(HTML(css))),
  column(11, offset = 0, DTOutput("control_dt"))
)

并使用友好的formatStyle

......
) %>%
  formatStyle("cyl", target = 'row',
              color = styleEqual(c(4, 6, 8),
                                 c("red", "gray", "yellow")))

答案 1 :(得分:0)

我在其他没有此问题的类似表中发现了细微的差别。

使用formatStyle定位行时,行div会获得颜色样式,该颜色样式是在引导样式中选择了行之后才应用的。

如果使用formatStyle定位列,则特定的单元格将获得具有最高优先级并保留颜色的颜色样式。

所以我可以使用一个列值专门格式化每一列,这样颜色就不会被选择覆盖。

... %>%
    formatStyle("cyl", 
                  color = styleEqual(c(4, 6, 8),
                                     c("red", "gray", "yellow"))) %>%
      formatStyle("mpg", valueColumns = "cyl",
                  color = styleEqual(c(4, 6, 8),
                                     c("red", "gray", "yellow")))

这解决了问题,但是我不满意,因此我不会将其标记为答案。如果有更好的解决方案,我会将其标记为答案。

更新:根据@StéphaneLaurent的建议,我们可以使用更简单的语法,因为该参数可以采用向量。

... %>%
      formatStyle(c("cyl", "mpg"), valueColumns = "cyl",
                  color = styleEqual(c(4, 6, 8),
                                     c("red", "gray", "yellow")))