Progress Bar
#| standalone: true
#| components: [viewer]
#| viewerHeight: 200
library(shiny)
library(bslib)
ui <- page_fluid(
actionButton("run", "Compute"),
textOutput("txt")
)
server <- function(input, output, session) {
text <- reactiveVal()
output$txt <- renderText({ text() })
observe({
withProgress(
message = 'Calculation in progress',
detail = 'This may take a while...',
value = 0,
{
for (i in 1:15) {
incProgress(1/15)
Sys.sleep(0.25)
}
text("Done computing!")
}
)
}) |>
bindEvent(input$run)
}
shinyApp(ui, server)
library(shiny)
library(bslib)
ui <- page_fluid(
actionButton("run", "Compute"),
textOutput("txt")
)
server <- function(input, output, session) {
text <- reactiveVal()
output$txt <- renderText({ text() })
observe({
withProgress(
message = 'Calculation in progress',
detail = 'This may take a while...',
value = 0,
{
for (i in 1:15) {
incProgress(1/15)
Sys.sleep(0.25)
}
text("Done computing!")
}
)
}) |>
bindEvent(input$run)
}
shinyApp(ui, server)
Relevant Functions
-
withProgress
withProgress(expr, min = 0, max = 1, value = min + (max - min) * 0.1, message = NULL, detail = NULL, style = getShinyOption("progress.style", default = "notification"), session = getDefaultReactiveDomain(), env = parent.frame(), quoted = FALSE)
-
incProgress
incProgress(amount = 0.1, message = NULL, detail = NULL, session = getDefaultReactiveDomain())
-
setProgress
setProgress(value = NULL, message = NULL, detail = NULL, session = getDefaultReactiveDomain())
-
Progress
Progress
Details
With Shiny, you can display a progress bar while a computation runs by running the computation within a special function. Here’s how:
- Wrap the computation to run in
withProgress()
.withProgress()
creates a panel with a progress bar that is displayed during the computation. For example, you might set up a progress bar like this:
Set the minimum and maximum values of the progress bar when you call
withProgress()
. These provide the outer bounds for the progress to display. For example, in the code above, when the bar is at 1, it would appear empty. When it is at 8, it would appear half full. When it is at 15, it would appear complete.Update the progress bar object as the computation runs. Updating the object is simple: you can call
setProgress()
orincProgress()
from within the computation to change the location of the progress bar, as well as the message it displays. For example the code below would update the progress bar above to half finished, and change the message that accompanies the bar to “Almost there!”.
Finding opportunities to update the bar while the computation runs is more tricky. To have a responsive bar, you will need to interlace set calls with the computation that runs. If the computation is a function from an external package, you may only be able to alert the user when the computation begins and when it finishes, which is unlikely to be satisfying:
withProgress(
min=1,
max=15,
{
setProgress(1, message = "Here we go")
# computation()
setProgress(15, message = "Finished!")
}
)
If the computation involves separate functions run in sequence, you can update the progress bar after each function:
withProgress(
min=1,
max=15,
{
setProgress(1, message = "Here we go")
# computation1()
setProgress(5, message = "Working hard")
# computation2()
setProgress(10, message = "Almost there")
# computation3()
setProgress(15, message = "Finished!")
}
)
If the computation is a function that you have written, you can write the function to accept a progress bar object to update as it runs. To do this, use Progress
/ Progress
provides an alternative, object-oriented API for building a progress bar in Shiny.