14

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

我需要一个显示闪亮服务器正忙的指示器。我尝试过闪亮的孵化器,但是,问题是我无法为进度条设置最大值。我不想要这样的东西:https ://shiny.rstudio.com/gallery/progress-bar-example.html 我需要的是: 1- 显示一个繁忙的指示器消息和栏(即只是一个简单的动画条,不需要显示填充条)只要服务器正在计算 2- 无论您正在查看哪个选项卡,它都会显示。(不仅在相关选项卡中,而且在选项卡集顶部)

4

5 回答 5

15

2018 年更新:目前有一个很棒的包可以帮助您显示加载器:(shinycssloaders来源 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)
})
于 2014-10-02T11:46:41.377 回答
9

或者,您可以使用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)

在此处输入图像描述

于 2018-03-26T10:36:40.250 回答
3

使用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)

服务员演示

于 2020-04-21T08:54:12.780 回答
2

我发现使用 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)
于 2017-03-07T19:13:32.597 回答
1

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

      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)  
于 2016-06-24T12:58:57.943 回答