Adjust Size of Shiny Progress Bar and Center It

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 cssstyle 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)

Sample Image

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



Leave a reply



Submit