8.3 Progress bars
- good for long-running tasks
- you need to be able to divide the big task into a known number of small pieces that each take roughly the same amount of time
8.3.1 Shiny
Use withProgress()
and incProgress()
ui <- fluidPage(
numericInput("steps", "How many steps?", 10),
actionButton("go", "go"),
textOutput("result")
)
server <- function(input, output, session) {
data <- eventReactive(input$go, {
withProgress(message = "Computing random number", {
for (i in seq_len(input$steps)) {
Sys.sleep(0.5)
incProgress(1 / input$steps)
}
runif(1)
})
})
output$result <- renderText(round(data(), 2))
}
Check out this app: https://hadley.shinyapps.io/ms-progress
8.3.2 Waiter
waiter
package uses an R6 object
ui <- fluidPage(
waiter::use_waitress(),
numericInput("steps", "How many steps?", 10),
actionButton("go", "go"),
textOutput("result")
)
server <- function(input, output, session) {
data <- eventReactive(input$go, {
# Create a new progress bar
waitress <- waiter::Waitress$new(max = input$steps)
# Automatically close it when done
on.exit(waitress$close())
for (i in seq_len(input$steps)) {
Sys.sleep(0.5)
# increment one step
waitress$inc(1)
}
runif(1)
})
output$result <- renderText(round(data(), 2))
}
–> example app: https://shiny.john-coene.com/waiter/
8.3.3 Spinners
- also use the
waiter()
package - instead of
Waitress
–>Waiter
ui <- fluidPage(
waiter::use_waiter(),
actionButton("go", "go"),
textOutput("result")
)
server <- function(input, output, session) {
data <- eventReactive(input$go, {
waiter <- waiter::Waiter$new()
waiter$show()
on.exit(waiter$hide())
Sys.sleep(sample(5, 1))
runif(1)
})
output$result <- renderText(round(data(), 2))
}
Check out this app: https://hadley.shinyapps.io/ms-spinner-1
You can use Waiter
for specific outputs, which will make the code simpler:
ui <- fluidPage(
waiter::use_waiter(),
actionButton("go", "go"),
plotOutput("plot"),
)
server <- function(input, output, session) {
data <- eventReactive(input$go, {
waiter::Waiter$new(id = "plot")$show()
Sys.sleep(3)
data.frame(x = runif(50), y = runif(50))
})
output$plot <- renderPlot(plot(data()), res = 96)
}
Check out this app: https://hadley.shinyapps.io/ms-spinner-2
Check out all the available spinners: https://shiny.john-coene.com/waiter/
–> example app for more spinners