在 Shiny 应用程序中自定义 rhandsontable 颜色的正确方法

Correct way to customize color of rhandsontable inside a Shiny app

因此,我正在创建一个闪亮的应用程序,我想为使用 rhandsontable 生成的 table 中的一些行着色。

我正在学习这个非常好的教程:https://jrowen.github.io/rhandsontable/

具体来说,我对这部分感兴趣:

library(rhandsontable)
DF = data.frame(val = 1:10, bool = TRUE, big = LETTERS[1:10],
                small = letters[1:10],
                dt = seq(from = Sys.Date(), by = "days", length.out = 10),
                stringsAsFactors = FALSE)

col_highlight = 2
row_highlight = c(5, 7)

rhandsontable(DF, col_highlight = col_highlight, 
              row_highlight = row_highlight,
              width = 550, height = 300) %>%
  hot_cols(renderer = "
    function(instance, td, row, col, prop, value, cellProperties) {
      Handsontable.TextCell.renderer.apply(this, arguments);

      tbl = this.HTMLWidgets.widgets[0]

      hcols = tbl.params.col_highlight
      hcols = hcols instanceof Array ? hcols : [hcols] 
      hrows = tbl.params.row_highlight
      hrows = hrows instanceof Array ? hrows : [hrows] 

      if (hcols.includes(col) && hrows.includes(row)) {
        td.style.background = 'red';
      }
      else if (hcols.includes(col)) {
        td.style.background = 'lightgreen';
      }
      else if (hrows.includes(row)) {
        td.style.background = 'pink';
      }

      return td;
  }")

此代码在 RStudio 中有效,但在 Shiny 中无效(table 根本不显示)。网站上有解释,说如果在Shiny上使用这个,我们应该把那部分添加到代码中:

HTMLWidgets.widgets.filter(function(widget) {
  // this should match the table id specified in the shiny app
  return widget.name === "hot"
})[0];

但是,由于我对 javascript 一无所知,所以我对这部分应该放在哪里有些迷茫。我尝试了很多东西,包括:

 rhandsontable(DF, col_highlight = col_highlight, 
                  row_highlight = row_highlight,
                  width = 550, height = 300) %>%
      hot_cols(renderer = "
        function(instance, td, row, col, prop, value, cellProperties) {
          Handsontable.TextCell.renderer.apply(this, arguments);
          HTMLWidgets.widgets.filter(function(widget) {
            // this should match the table id specified in the shiny app
            return widget.name === \"hot\"
          })[0];
      ..

但还是不对。

对于熟悉 js 的人来说,这可能是一个非常基本的问题,但是正确的做法是什么?

为列和行着色的简单示例。

library(shiny)
library(rhandsontable)

ui <- shinyUI(bootstrapPage(
    rHandsontableOutput("hot")
))

server <- shinyServer(function(input, output) {
    output$hot <- renderRHandsontable({
        DF = data.frame(val = 1:10, big = LETTERS[1:10])
        col_highlight = c(0, 1)
        row_highlight = c(3)
    
        rhandsontable(DF, col_highlight = col_highlight, row_highlight = row_highlight) %>%
        hot_cols(renderer = "
            function(instance, td, row, col, prop, value, cellProperties) {
                Handsontable.renderers.NumericRenderer.apply(this, arguments);
                if (instance.params) {
                    hcols = instance.params.col_highlight
                    hcols = hcols instanceof Array ? hcols : [hcols]
                    hrows = instance.params.row_highlight
                    hrows = hrows instanceof Array ? hrows : [hrows]
                }
                if (instance.params && hcols.includes(col)) td.style.background = 'red';
                if (instance.params && hrows.includes(row)) td.style.background = 'yellow';
            }")
    })
})

shinyApp(ui, server)

在已接受的答案中关注处理布尔值的讨论。请注意,hot_col 可以指定要格式化的列。因此只需排除布尔列。例如,下面的代码只使用了第 1 列和第 2 列,第 3 列 bool 被删除了。

library(shiny)
library(rhandsontable)

ui <- shinyUI(bootstrapPage(
    rHandsontableOutput("hot")
))

server <- shinyServer(function(input, output) {
    output$hot <- renderRHandsontable({
        DF = data.frame(val = 1:10, big = LETTERS[1:10],bool=T)
        col_highlight = c(0, 1)
        row_highlight = c(3)
    
        rhandsontable(DF, col_highlight = col_highlight, row_highlight = row_highlight) %>%
        hot_col(col=c(1,2),renderer = "
            function(instance, td, row, col, prop, value, cellProperties) {
                Handsontable.renderers.NumericRenderer.apply(this, arguments);
                if (instance.params) {
                    hcols = instance.params.col_highlight
                    hcols = hcols instanceof Array ? hcols : [hcols]
                    hrows = instance.params.row_highlight
                    hrows = hrows instanceof Array ? hrows : [hrows]
                }
                if (instance.params && hcols.includes(col)) td.style.background = 'red';
                if (instance.params && hrows.includes(row)) td.style.background = 'yellow';
            }")
    })
})

shinyApp(ui, server)

结果如下: