Show that Shiny is busy (or loading) when changing tab panels

后端 未结 3 1899
灰色年华
灰色年华 2020-12-07 16:14

(Code follows after problem description)

I am working on making a web app with Shiny, and some of the R commands that I am executing take minutes to complete. I foun

相关标签:
3条回答
  • 2020-12-07 16:38

    Via the Shiny Google group, Joe Cheng pointed me to the shinyIncubator package, where there is a progress bar function that is being implemented (see ?withProgress after installing the shinyIncubator package).

    Maybe this function will be added to the Shiny package in the future, but this works for now.

    Example:

    UI.R

    library(shiny)
    library(shinyIncubator)
    
    shinyUI(pageWithSidebar(
      headerPanel("Testing"),
      sidebarPanel(
        # Action button
        actionButton("aButton", "Let's go!")
      ),
    
      mainPanel(
        progressInit(),
        tabsetPanel(
          tabPanel(title="Tab1", plotOutput("plot1")),
          tabPanel(title="Tab2", plotOutput("plot2")))
      )
    ))
    

    SERVER.R

    library(shiny)
    library(shinyIncubator)
    
    shinyServer(function(input, output, session) {
      output$plot1 <- renderPlot({
        if(input$aButton==0) return(NULL)
    
        withProgress(session, min=1, max=15, expr={
          for(i in 1:15) {
            setProgress(message = 'Calculation in progress',
                        detail = 'This may take a while...',
                        value=i)
            print(i)
            Sys.sleep(0.1)
          }
        })
        temp <- cars + matrix(rnorm(prod(dim(cars))), nrow=nrow(cars), ncol=ncol(cars))
        plot(temp)
      })
    
      output$plot2 <- renderPlot({
        if(input$aButton==0) return(NULL)
    
        withProgress(session, min=1, max=15, expr={
          for(i in 1:15) {
            setProgress(message = 'Calculation in progress',
                        detail = 'This may take a while...',
                        value=i)
            print(i)
            Sys.sleep(0.1)
          }
        })
        temp <- cars + matrix(rnorm(prod(dim(cars))), nrow=nrow(cars), ncol=ncol(cars))
        plot(temp)
      })
    })
    
    0 讨论(0)
  • 2020-12-07 16:42

    Here is a possible solution using your original approach.

    First use an identifier for the tabs:

    tabsetPanel(
      tabPanel(title="Tab 1", loadingPanel, textOutput("tabText1")), 
      tabPanel(title="Tab 2", loadingPanel, textOutput("tabText2")),
      id="tab"
    )
    

    Then, if you connect tabText1 to input$tab:

      output$tabText1 <- renderText({
        if(input$goButton==0) return(NULL)
        input$tab
        return({
          print(paste("Slept for", sleep1(), "seconds."))
        })
      })
    

    you will see that it works when you go from the first tab to the second one.

    Update

    A cleanest option consists in defining a reactive object catching the active tabset. Just write this anywhere in server.R :

      output$activeTab <- reactive({
        return(input$tab)
      })
      outputOptions(output, 'activeTab', suspendWhenHidden=FALSE)
    

    See https://groups.google.com/d/msg/shiny-discuss/PzlSAmAxxwo/eGx187UUHvcJ for some explanation.

    0 讨论(0)
  • 2020-12-07 17:02

    I think the easiest option would be using busyIndicator function in the shinysky package. For more information follow this link

    0 讨论(0)
提交回复
热议问题