So I want to create a shinydashboardPlus GUI for a long-running function long_run_op
that displays progress in the console. Here is a minimal example for that function:
long_run_op <- function() {
pb <- txtProgressBar(style=3, max=10)
for(i in 1:10) {Sys.sleep(0.1); setTxtProgressBar(pb, i)}
close(pb)
return(rnorm(10))
}
(If you're interested: I want to use the great keyATM::keyATM
, which cannot be used with shiny::withProgress
.)
Now I wish to display the console progress bar in the shiny app.
What I tried so far, is to use verbatimTextOutput
. This does only display the return value. Also, the server function uses <<-
, which does not only smell like bad practice, it does not even work -- the plot is never shown.
(EDIT: the plot not showing was because of a wrong function in the ui and is now fixed, thanks @stefan.)
ui <- shinydashboardPlus::dashboardPage(
header=shinydashboardPlus::dashboardHeader(),
sidebar = shinydashboardPlus::dashboardSidebar(),
body=shinydashboard::dashboardBody(
shinydashboardPlus::box(
status="primary", width=12,
shiny::actionButton("run", "Run")
),
shinydashboardPlus::box(
status="primary", width=12,
shiny::verbatimTextOutput("progress")
),
shinydashboardPlus::box(
status="primary", width=12,
shiny::plotOutput("result")
)
)
)
server <- function(input, output, session) {
observeEvent(input$run, {
ans <- NA
output$progress <- shiny::renderText({
ans <<- long_run_op()
})
output$result <- shiny::renderPlot({
plot(ans)
})
})
}
app <- shiny::shinyApp(ui, server)
shiny::runApp(app, launch.browser=TRUE)
Still on the shiny learning curve, I am stuck here. Is there a way to make this work? Extra points if I can make the progress bar disappear after the calculation has finished.
EDIT2: Will sink
help? Is there a way to display a textConnection
object in Shiny?
EDIT3: I come to think that because of the single-threaded nature of Shiny the only chance I have is to redirect stdout to something in the browser. Using two processes seems too complicated to me.
EDIT4: Found this post. It seems that it is well possible to intercept and displays messages/warning/errors, but not cat
output.