Shiny + JS:基于数据透视值的条件格式

时间:2016-05-30 18:08:01

标签: javascript jquery r shiny rpivottable

我使用的是rpivotTable htmlwidget,它包含了优秀的PivotTable.js库。我想根据单元格的值有条件地格式化数据透视表。

为此,我尝试调整函数here。这是一个rpivotTable的最小Shiny应用程序:

rm(list = ls())
library(shiny)
library(shinydashboard)
library(rpivotTable)
library(dplyr)

#==========================================================
# simulate some data for the pivot table
#==========================================================
df_pivot = data_frame(
  factor1 = sample(rep(LETTERS[1:2], 100)),
  factor2 = sample(rep(LETTERS[5:6], 100)),
  factor3 = sample(rep(LETTERS[19:20], 100)),
  value = abs(rnorm(200))
)

#==========================================================
# ui
#==========================================================
pivot_body = dashboardBody({
  tags$head(includeScript("pivot.js"))
  tags$head(
    tags$style(
      HTML(
        ".realGone { background-color: #F08080 !important; }"
      )
    )
  )
  rpivotTableOutput(outputId = "pivot_output")
})

pivot_header = dashboardHeader(title = "Some title.")
pivot_sidebar = dashboardSidebar()

pivot_ui = dashboardPage(
  header = pivot_header,
  sidebar = pivot_sidebar,
  body = pivot_body
)

#==========================================================
# server
#==========================================================
pivot_server = shinyServer(function(input, output, session) {
  output$pivot_output = renderRpivotTable({
    rpivotTable(
      data = df_pivot,
      rows = "factor1",
      cols = "factor2"
    )
  })
})

#==========================================================
# run the app
#==========================================================
pivot_app = shinyApp(
  ui = pivot_ui,
  server = pivot_server
)

runApp(pivot_app)

这是我对JS函数的改编 - 基本思想是查找类.pvtVal的元素,为它们添加一个类并根据这个类应用CSS样式。

$(document).ready(function(){
var $labels = $('.pvtVal');
console.log("Reached here.");
  for (var i=0; i<$labels.length; i++) {
    if ($labels[i].innerHTML < 12) {
            $('.pvtVal').eq(i).addClass('expired');
        } else if ($labels[i].innerHTML > 12 && $labels[i].innerHTML < 14) {
          $('.pvtVal').eq(i).addClass('dead');
      } else if ($labels[i].innerHTML > 14) {
        $('.pvtVal').eq(i).addClass('realGone');
      }
  }
});

但是当我检查控制台中的元素时,它们似乎没有添加realGone类。我的猜测是我误解了$document().ready的作用。

1 个答案:

答案 0 :(得分:3)

您的代码存在一些问题。

  1. dashboardBody应该是一个包含多个参数而不是代码列表的函数。
  2. 正确:dashboardBody(item1, item2, item3)

    错误:dashboardBody({line1, line2, line3})

    1. .pvtVal表格单元格由pivotTable.js创建,因此在pivotTable.js完成后运行您自己的Javascript至关重要。不幸的是,这发生在document.readywindow.load事件之后。我使用了Running jQuery after all other JS has executed中的技术来连续轮询页面并查看表格单元格是否出现。
    2. 完整的工作代码

      app.R

      rm(list = ls())
      library(shiny)
      library(shinydashboard)
      library(rpivotTable)
      library(dplyr)
      
      #==========================================================
      # simulate some data for the pivot table
      #==========================================================
      df_pivot = data_frame(
          factor1 = sample(rep(LETTERS[1:2], 100)),
          factor2 = sample(rep(LETTERS[5:6], 100)),
          factor3 = sample(rep(LETTERS[19:20], 100)),
          value = abs(rnorm(200))
      )
      
      #==========================================================
      # ui
      #==========================================================
      pivot_body = dashboardBody(
          tags$head(
              tags$style(
                  HTML(
                      ".realGone { background-color: #F08080 !important; }"
                  )
              )
          ),
          rpivotTableOutput(outputId = "pivot_output"),
          tags$script(src="pivot.js")
      
      )
      
      pivot_header = dashboardHeader(title = "Some title.")
      pivot_sidebar = dashboardSidebar()
      
      pivot_ui = dashboardPage(
          header = pivot_header,
          sidebar = pivot_sidebar,
          body = pivot_body
      )
      
      #==========================================================
      # server
      #==========================================================
      pivot_server = shinyServer(function(input, output, session) {
          output$pivot_output = renderRpivotTable({
              rpivotTable(
                  data = df_pivot,
                  rows = "factor1",
                  cols = "factor2"
              )
          })
      })
      
      #==========================================================
      # run the app
      #==========================================================
      
      shinyApp(ui = pivot_ui, server = pivot_server)
      

      pivot.js(确保将其放在www文件夹中,该文件夹应该是项目根目录的子文件夹)

      $(window).load(function(){
          var i = setInterval(function() {
              if ($(".pvtVal").length) {
                  clearInterval(i);
      
                  $(".pvtVal").each(function(index) {
      
                      var value = parseInt($(this).text());
      
                      if (value < 12) {
                          $(this).addClass("expired");
                      } else if (value > 12 && value < 14) {
                          $(this).addClass("dead");
                      } else {
                          $(this).addClass("realGone");
                      }
                  });
              }
          }, 100);
      });