(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
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)
})
})
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.
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.
I think the easiest option would be using busyIndicator function in the shinysky package. For more information follow this link