在闪亮的应用程序中的数据表单元格中包含sparkline htmlwidget,而无需借助(很多)JavaScript

时间:2017-10-31 17:38:03

标签: r shiny dt htmlwidgets sparklines

我正在使用sparkline包生成条形图,以便放入Shiny应用中datatable的单元格中。我已经设法在独立的datatable中生成所需的输出,但是当我将它放入Shiny应用程序时它不起作用。它可能与spk_add_deps()如何识别htmlwidgets有关。我尝试过移动spk_add_deps()函数并传递各种标识符,但没有任何效果。

我确实在这里找到了基本相同的问题Render datatable with sparklines in Shiny 但是给定的解决方案(1)依赖于在回调函数中编写迷你图的JavaScript代码(违背了具有R sparkline()函数的目的)和(2)似乎如果迷你图在查看器中呈现则我们不能让它们在Shiny应用程序中渲染,而不必编写所有JavaScript。

这是演示:

# Preliminary, load packages and build a demo table with the sparkline code merged in
library(shiny)
library(DT)
library(data.table)
library(sparkline)

## Create demo data sets
my_mtcars <- data.table(mtcars, keep.rownames = TRUE)
names(my_mtcars)[1] <- 'car_id'

set.seed(0)
data_for_sparklines <- data.table(car_id = rep(my_mtcars$car_id, 5),
                                  category = 1:5,
                                  value = runif(160))

sparkline_html <- data_for_sparklines[, .(sparkbar = spk_chr(value, type = 'bar')), by = 'car_id']
my_mtcars <- merge(my_mtcars, sparkline_html, by = 'car_id')

现在,如果我自己渲染数据表,则会出现迷你图条形图:

spk_add_deps(datatable(my_mtcars, escape = FALSE))

datatable showing sparkline bar charts

但是,如果我将其嵌入到一个闪亮的应用程序中,该列是空白的:

ui <- shinyUI(fluidPage(
  dataTableOutput('myTable')
))

server <- shinyServer(function(input, output, session) {
  output$myTable <- renderDataTable(spk_add_deps(datatable(my_mtcars, escape = FALSE)))
}) 

shinyApp(ui = ui, server = server)

enter image description here

2 个答案:

答案 0 :(得分:3)

使用htmlwidgets包找到解决方案。

library(htmlwidgets)

然后使用spk_add_deps()代替getDependency()在Shiny UI函数中加载迷你图依赖项:

ui <- shinyUI(fluidPage(
  getDependency('sparkline'),
  dataTableOutput('myTable')
))

由于我不完全理解的原因,请在renderDataTable()中向HTMLwidgets staticRender()函数添加回调:

server <- shinyServer(function(input, output, session) {
  staticRender_cb <- JS('function(){debugger;HTMLWidgets.staticRender();}') 
  output$myTable <- renderDataTable(my_mtcars,
                                    escape = FALSE,
                                    options = list(drawCallback = staticRender_cb))
}) 

但就是这样,只需要让它们在Shiny应用中呈现即可。

答案 1 :(得分:1)

仅供参考,如果遇到任何问题的初始代码并想使用它而又没有光泽的人(就像我一样),该代码只会在表格的第一页上创建迷你图 。您需要添加

options = list(
  fnDrawCallback = htmlwidgets::JS(
    '
function(){
  HTMLWidgets.staticRender();
}
'
  )
如果要在表格的所有页面上显示迷你图,请在DT :: datatable()代码中