Search code examples
rshinyprogress-bar

Can you apply a progress bar from waitress to a modal Dialog?


In a shiny app, I have a plot which sometimes takes a bit of time to calculate. I would like to show the progress of this calculation with a progressbar from the waiter package. Is there a way to apply a waitress to a modalDialog? Below is a MWE where the waitress is applied to the full page, but I would find it way better if I just had one bar on the modalDialog.

I have checked the possibilities from the Demo: Applying it to the actionButton does not work in my actual app. Showing it as a notification would work, but I am not aware of any way to display the notification in the center of the screen rather than in a corner. I guess the "on elements" is what I am looking for, but my modalDialog does not have an input or output id.

library(shiny)
library(shinipsum)
library(waiter)
library(plotly)

complicated_function <- function(){
  waitress <- Waitress$new(theme = "overlay",min = 0,max = 20)
  for(i in 1:20){
    waitress$inc(1)
    Sys.sleep(0.2)
  }
  waitress$close()
  return(random_ggplotly())
}

ui <- fluidPage(
  useWaitress(),
  actionButton("plotButton", "Generate Plot")
)

server <- function(input,output,session){
  modal1 <- modalDialog(
    renderPlotly({
      complicated_function()
    })
  )
  observeEvent(input$plotButton,{
    showModal(modal1)
  })
}
shinyApp(ui, server)

Solution

  • You can try the attendantBar from the same package:

    library(shiny)
    library(shinipsum)
    library(waiter)
    library(plotly)
    
    complicated_function <- function(){
      att <- Attendant$new("progress-bar", hide_on_max = TRUE)
      for(i in 1:20){
        att$set(i * 10)
        Sys.sleep(0.2)
       }
      return(random_ggplotly())
    }
    
    
    ui <- fluidPage(
      useAttendant(),
      
      actionButton("plotButton", "Generate Plot")
    )
    
    server <- function(input,output,session){
      
      
      modal1 <- modalDialog(
        attendantBar("progress-bar"),
        renderPlotly({
    
          complicated_function()
        })
        
      )
      observeEvent(input$plotButton,{
        showModal(modal1)
        
      })
    }
    shinyApp(ui, server)