闪亮的app忙指标

时间:2014-09-23 20:35:49

标签: r shiny shiny-server busyindicator

注意:我已经在闪亮的googlegroups和SO中阅读了关于此对象的几乎所有讨论。

我需要一个指示灯,显示闪亮的服务器正忙。我尝试过闪亮的孵化器,但问题是我无法为进度条设置最大值。 我不希望这样的事情:http://shiny.rstudio.com/gallery/progress-example.html 我需要的是: 1-只要服务器正在计算,就会显示忙碌指示符信息和条形图(即只是一个简单的动画条,不需要显示填充条) 2-无论您正在查看哪个标签,都会显示它。 (不仅在相关标签中,而且在标签集的顶部)

由于

5 个答案:

答案 0 :(得分:11)

更新2018:目前有一个很棒的软件包可以帮助您显示加载器:shinycssloaders source https://github.com/andrewsali/shinycssloaders

我也一直在寻找这个。大多数人建议像这样的条件小组:

conditionalPanel(
            condition="!($('html').hasClass('shiny-busy'))",
            img(src="images/busy.gif")
)

你可以随时给自己更多的控制,并在你的ui.R中创建条件处理(可能取决于更多的东西):

div(class = "busy",
    p("Calculation in progress.."),
    img(src="images/busy.gif")
)

其中一些JavaScript处理该div的显示和隐藏:

setInterval(function(){
  if ($('html').attr('class')=='shiny-busy') {
    $('div.busy').show()
  } else {
    $('div.busy').hide()
  }
},100)

通过一些额外的CSS,你可以确保你的动画繁忙图像获得一个固定的位置,它始终可见。

在上述任何一种情况下,我发现"闪亮的忙碌"条件有点不精确和不可靠:div显示一瞬间,并在计算仍在进行时消失... 我找到了一个解决这个问题的肮脏解决方案,至少在我的应用程序中。请随意尝试一下,也许有人可以深入了解解决问题的方式和原因。

在您的server.R中,您需要添加两个reactiveValues:

shinyServer(function(input, output, session) {

    # Reactive Value to reset UI, see render functions for more documentation
    uiState <- reactiveValues()
    uiState$readyFlag <- 0
    uiState$readyCheck <- 0

然后,在你的renderPlot函数(或其他计算继续的输出函数)中,你使用这些反应值来重置函数:

output$plot<- renderPlot({

    if (is.null(input$file)){
        return()
    }
    if(input$get == 0){
        return()
    }

    uiState$readyFlag

    # DIRTY HACK:
    # Everytime "Get Plot" is clicked we get into this function
    # In order for the ui to be able show the 'busy' indicator we
    # somehow need to abort this function and then of course seamlessly
    # call it again.
    # We do this by using a reactive value keeping track of the ui State:
    # renderPlot is depending on 'readyFlag': if that gets changed somehow
    # the reactive programming model will call renderPlot
    # If readyFlag equals readyCheck we exit the function (= ui reset) but in the
    # meantime we change the readyFlag, so the renderHeatMap function will 
    # immediatly be called again. At the end of the function we make sure 
    # readyCheck gets the same value so we are back to the original state

    isolate({
        if (uiState$readyFlag == uiState$readyCheck) {
            uiState$readyFlag <- uiState$readyFlag+1
            return(NULL)
        }
    })

    isolate({plot <- ...})

    # Here we make sure readyCheck equals readyFlag once again
    uiState$readyCheck <- uiState$readyFlag

    return(plot)
})

答案 1 :(得分:4)

或者,您可以使用shinycssloadershttps://github.com/andrewsali/shinycssloaders

library(shiny)
library(dplyr)
library(shinycssloaders)

ui <- fluidPage(

  actionButton("plot","plot"),
  plotOutput("Test") %>% withSpinner(color="#0dc5c1")
)



server <- function(input, output, session) {


  data <- eventReactive(input$plot,{
    rnorm(1:100000)
  })

  output$Test <- renderPlot({
    plot(data())
  })
}

shinyApp(ui = ui, server = server)

enter image description here

答案 2 :(得分:2)

使用waiter

library(shiny)
library(waiter)

ui <- fluidPage(
  use_waiter(),
  actionButton("plot","plot"),
  plotOutput("Test")
)
server <- function(input, output, session) {
  w <- Waiter$new(id = "Test")

  data <- eventReactive(input$plot,{
    w$show()
    rnorm(1:100000)
  })

  output$Test <- renderPlot({
    plot(data())
  })
}
shinyApp(ui = ui, server = server)

waiter demo

答案 3 :(得分:1)

我发现使用fadeIn()而不是show()有助于减轻这种闪烁的发生:

setInterval(function(){
                     if ($('html').attr('class')=='shiny-busy') {
                          setTimeoutConst = setTimeout(function(){
                                $('#loading-page').fadeIn(500);
                             }, delay);
                      } else {
                          clearTimeout(setTimeoutConst );
                          $('#loading-page').hide();
                      }
              },10)

答案 4 :(得分:0)

对于最新版本的闪亮,忙碌的div也会出现片刻,即使没有明显的计算(旧版本中也不是问题)。 Shiny似乎经常处于繁忙模式的短时间内。作为一种解决方案(补充上述讨论),可以包括对条件处理的闪亮繁忙的html类的另一个第二延迟验证。 JavaScript部分看起来像那样(例子还包括根据反应性textit检查两个不同的div.busy状态):

      if( ($('html').attr('class')=='shiny-busy') ){
                setTimeout(function() {
                if ($('html').attr('class')=='shiny-busy') {
                    if($('#textit').html()!='Waiting...' ){
                        $('div.busy1').show()
                    }
                    if($('#textit').html()=='Waiting...'){
                        $('div.busy2').show()
                    }
                }   
                },1000) 
              } else {
                $('div.busy1').hide()
                $('div.busy2').hide()
              }
            },100)