How to display a busy indicator in a shiny app?
Update 2018: Currently there is a great package to help you display loaders: shinycssloaders
(source: https://github.com/andrewsali/shinycssloaders)
I've been looking for this as well. Most people suggest a conditional panel like so:
conditionalPanel(
condition="!($('html').hasClass('shiny-busy'))",
img(src="images/busy.gif")
)
You could always give yourself more control and create the conditional handling (maybe depending on more stuff) like this in your ui.R:
div(class = "busy",
p("Calculation in progress.."),
img(src="images/busy.gif")
)
where some JavaScript handles the showing and hiding of that div:
setInterval(function(){
if ($('html').attr('class')=='shiny-busy') {
$('div.busy').show()
} else {
$('div.busy').hide()
}
},100)
with some extra css you could make sure your animated busy image gets a fixed postion where it will always be visible.
In any of the above cases i found that the "shiny-busy" condition is somewhat imprecise and unreliable: the div shows for a split second and disappears while computations are still going on...
I found a dirty solution to fix that problem, at least in my apps. Feel free to try it out and maybe someone could give an insight to how and why this solves the issue.
In your server.R you'll need to add two reactiveValues:
shinyServer(function(input, output, session) {
# Reactive Value to reset UI, see render functions for more documentation
uiState <- reactiveValues()
uiState$readyFlag <- 0
uiState$readyCheck <- 0
then, in your renderPlot function (or other output function where computations go on), you use these reactive values to reset the function:
output$plot<- renderPlot({
if (is.null(input$file)){
return()
}
if(input$get == 0){
return()
}
uiState$readyFlag
# DIRTY HACK:
# Everytime "Get Plot" is clicked we get into this function
# In order for the ui to be able show the 'busy' indicator we
# somehow need to abort this function and then of course seamlessly
# call it again.
# We do this by using a reactive value keeping track of the ui State:
# renderPlot is depending on 'readyFlag': if that gets changed somehow
# the reactive programming model will call renderPlot
# If readyFlag equals readyCheck we exit the function (= ui reset) but in the
# meantime we change the readyFlag, so the renderHeatMap function will
# immediatly be called again. At the end of the function we make sure
# readyCheck gets the same value so we are back to the original state
isolate({
if (uiState$readyFlag == uiState$readyCheck) {
uiState$readyFlag <- uiState$readyFlag+1
return(NULL)
}
})
isolate({plot <- ...})
# Here we make sure readyCheck equals readyFlag once again
uiState$readyCheck <- uiState$readyFlag
return(plot)
})
How to show Spinning Wheel or Busy Icon while waiting in Shiny
There is wonderful shinycssloaders
package https://github.com/andrewsali/shinycssloaders, now maintained here https://github.com/daattali/shinycssloaders, which does what you want:
library(shiny)
library(dplyr)
library(shinycssloaders)
ui <- fluidPage(
actionButton("plot","plot"),
plotOutput("Test") %>% withSpinner(color="#0dc5c1")
)
server <- function(input, output, session) {
data <- eventReactive(input$plot,{
rnorm(1:100000)
})
output$Test <- renderPlot({
plot(data())
})
}
shinyApp(ui = ui, server = server)
R Shiny display app is busy in a widget
In your case, it would be helpful a progressbar to check the state. This element would be appreciate by your users to indicate the state. Unfortunately, the progress bar would have to code before the functionality. It is a trick, you see a progress bar but this object stops when the function starts.
Here is the tutorial: http://shiny.rstudio.com/gallery/progress-bar-example.html
From my point of view, the progress bar is the best way to inform the web users of the website state but it is not completely perfect. Further you can change the style of the bar with CSS to customize and select your own colors, size...
Related Topics
Figures Captions and Labels in Knitr
How to Get Rstudio to Automatically Compile R Markdown Vignettes
How to Identify the Distribution of the Given Data Using R
Install a Local R Package with Dependencies from Cran Mirror
How to Make Object Created Within Function Usable Outside
Predicting Lda Topics for New Data
Kruskal-Wallis Test with Details on Pairwise Comparisons
R Web Application Introduction
Speeding Up Julia's Poorly Written R Examples
Circular Heatmap That Looks Like a Donut
Jupyter-Client Has to Be Installed But "Jupyter Kernelspec --Version" Exited with Code 127
Reordering Columns in a Large Dataframe
To Find Whether a Column Exists in Data Frame or Not
How to Apply Function Over Each Matrix Element's Indices
Ggplot2 Legend to Bottom and Horizontal
Rearrange Dataframe to a Table, the Opposite of "Melt"