Adjust size of Shiny progress bar and center it
I wrote a progress bar function in the package shinyWidgets
, you can put it in a modal, but it's tricky to use with shiny::showModal
, so you can create your own modal manually like the below. It's more code to write but it works fine.
library("shiny")
library("shinyWidgets")
ui <- fluidPage(
actionButton(inputId = "go", label = "Launch long calculation"), #, onclick = "$('#my-modal').modal().focus();"
# You can open the modal server-side, you have to put this in the ui :
tags$script("Shiny.addCustomMessageHandler('launch-modal', function(d) {$('#' + d).modal().focus();})"),
tags$script("Shiny.addCustomMessageHandler('remove-modal', function(d) {$('#' + d).modal('hide');})"),
# Code for creating a modal
tags$div(
id = "my-modal",
class="modal fade", tabindex="-1", `data-backdrop`="static", `data-keyboard`="false",
tags$div(
class="modal-dialog",
tags$div(
class = "modal-content",
tags$div(class="modal-header", tags$h4(class="modal-title", "Calculation in progress")),
tags$div(
class="modal-body",
shinyWidgets::progressBar(id = "pb", value = 0, display_pct = TRUE)
),
tags$div(class="modal-footer", tags$button(type="button", class="btn btn-default", `data-dismiss`="modal", "Dismiss"))
)
)
)
)
server <- function(input, output, session) {
value <- reactiveVal(0)
observeEvent(input$go, {
shinyWidgets::updateProgressBar(session = session, id = "pb", value = 0) # reinitialize to 0 if you run the calculation several times
session$sendCustomMessage(type = 'launch-modal', "my-modal") # launch the modal
# run calculation
for (i in 1:10) {
Sys.sleep(0.5)
newValue <- value() + 1
value(newValue)
shinyWidgets::updateProgressBar(session = session, id = "pb", value = 100/10*i)
}
Sys.sleep(0.5)
# session$sendCustomMessage(type = 'remove-modal', "my-modal") # hide the modal programmatically
})
}
shinyApp(ui = ui, server = server)
Generate progress bar in modal in shiny app, that closes automatically
The original progressbar
provided in shiny
is exactly what you need.
But I use css
to make the progessbar
display in the middle in the screen.
You can find the detail of using progress bar in shiny here.
library("shiny")
ui <- fluidPage(
actionButton(inputId = "go", label = "Launch long calculation"), #, onclick = "$('#my-modal').modal().focus();"
# css to center the progress bar
tags$head(
tags$style(
HTML(".shiny-notification {
height: 100px;
width: 800px;
position:fixed;
top: calc(50% - 50px);
left: calc(50% - 400px);
font-size: 250%;
text-align: center;
}
"
)
)
)
)
server <- function(input, output, session) {
value <- reactiveVal(0)
observeEvent(input$go, {
withProgress(message = 'Calculation in progress', value = 0,detail="0%", {
# run calculation
for (i in 1:10) {
Sys.sleep(0.5)
newValue <- value() + 1
value(newValue)
incProgress(1/10,detail = paste0(i*10,"%"))
}
Sys.sleep(0.5)
})
})
}
shinyApp(ui = ui, server = server)
Change style and position of the message box generated by withProgress()
Update
This is an updated version so you can refer to this example, the example is taken from here
server <- function(input, output) {
output$plot <- renderPlot({
input$goPlot # Re-run when button is clicked
# Create 0-row data frame which will be used to store data
dat <- data.frame(x = numeric(0), y = numeric(0))
withProgress(message = 'Making plot', value = 0, {
# Number of times we'll go through the loop
n <- 10
for (i in 1:n) {
# Each time through the loop, add another row of data. This is
# a stand-in for a long-running computation.
dat <- rbind(dat, data.frame(x = rnorm(1), y = rnorm(1)))
# Increment the progress bar, and update the detail text.
incProgress(1/n, detail = paste("Doing part", i))
# Pause for 0.1 seconds to simulate a long computation.
Sys.sleep(0.1)
}
})
plot(dat$x, dat$y)
})
}
ui <- shinyUI(basicPage(
plotOutput('plot', width = "300px", height = "300px"),
actionButton('goPlot', 'Go plot')
))
shinyApp(ui = ui, server = server)
Original Post
This is related to your previous question too. So you would probably want to change css
style of the progress bar. Feel free to play around and do more research if you want a fancier css
progress bar.
Note: during the calculations I have also disabled the button so users do not click the button multiple times forcing the computation to repeat itself. You can further look into shinyjs
for more information. As you can see in the image below during the computation that button is disabled. It will be back up once it is finished
rm(list = ls())
library(shiny)
library(shinyIncubator)
library(shinyjs)
server <- function(input, output, session) {
observe({
if(input$aButton==0) return(NULL)
withProgress(session, min=1, max=15, expr={
disable("aButton")
for(i in 1:20) {
setProgress(message = 'Finished...',detail = paste0('Number ',i, ':20'))
Sys.sleep(0.1)
}
Sys.sleep(1.5)
})
enable("aButton")
})
}
ui <- fluidPage(
tags$head(tags$style(".shiny-progress {top: 50% !important;left: 50% !important;margin-top: -100px !important;margin-left: -250px !important; color: blue;font-size: 20px;font-style: italic;}")),
sidebarPanel(actionButton("aButton", "Let's go!"), width=2),
useShinyjs(),
mainPanel(progressInit())
)
shinyApp(ui = ui, server = server)
Adding a progress bar to indicate ggplotting progress in Shiny
It's not actually a progress bar as you'd like to generate. But you can display a loading message within a banner instead, which is why I suppose it could be useful here. Just copy the following code-snippet into the ui-part of your app and adjust the colors as needed.
info_loading <- "Shiny is busy. Please wait."
your_color01 <- # define a color for the text
your_color02 <- # define a color for the background of the banner
tags$head(tags$style(type="text/css",
paste0("
#loadmessage {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
padding: 5px 0px 5px 0px;
text-align: center;
font-weight: bold;
font-size: 100%;
color: ", your_color01,";
background-color: ", your_color02,";
z-index: 105;
}
"))),
conditionalPanel(condition="$('html').hasClass('shiny-busy')",
tags$div(info_loading,id="loadmessage"))
Don't hesitate to adjust the parameters (e.g. top position) as needed.
You may further see: shiny loading bar for htmlwidgets
Related Topics
Center Wrapped Items in a Space-Between Flexbox
How to Set a Floating Div's Width to Take Up Remaining Space Without Pushing Other Divs Down
CSS Form Checkbox Styling with Checked and After Tags
How to I Solve This SASS Interpolation Issue
Compass Font-Face Outputs Wrong Path to Font File
Display:Table-Cell Not Working in Ie9
Custom CSS for Mobile Development Using Phonegap/Cordova
Why Is Browser Showing Td's Larger Than My Specified Width Property
Bootstrap 4 Navigation Active Link Color
CSS Pseudo-Element: :Before(2);: Before and: :Before
Turn Off Animations in Capybara Tests
CSS Selector Wildcard Inside Class Name
CSS Transform Not Working in Ie 8
Svg Stroke-Dasharray Offset Not Consistent
Systematically Resolve Conflicting Styles in CSS
Should I Use The Svg Gradients Generated by Colorzilla for Ie9