library(shiny)
library(shinyjs)
library(ggplot2)
library(future)
library(promises)
library(ipc)
plan(multicore)
ui <- fluidPage(useShinyjs(),
tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "style.css")),
HTML("<!-- common header-->
<div id='headerSection'>
<h1 style='color:white;'>Asynchronous download PDF report.</h1>
<span style='font-size: 1.2em'>
<span>Created by </span>
<a href='http://gerinberg.com'>Ger Inberg</a>
•
<span>December 2018</span>
•
<a href='http://gerinberg.com/shiny'>More apps</a> by Ger
</span>
</div>"),
plotOutput("plot"),
fluidRow(column(width = 6, tags$label(HTML("‌")), tags$br(), downloadButton("report", "Download report")),
column(width = 6, sliderInput("cylinders", "Minimum number of cylinders", value = 4, min = 4, max = 8))))
server <- function(input, output, session) {
result_val <- reactiveVal()
body_content <- reactive({
plot_content()
})
plot_content <- reactive({
data <- mtcars[mtcars$cyl >= input$cylinders, ]
ggplot(data, aes(x=cyl, y=mpg)) + geom_boxplot(aes(group=cyl)) + ggtitle("Miles per Gallon vs Number of Cylinders") + theme(plot.title = element_text(hjust = 0.5))
})
output$plot <- renderPlot({
plot_content()
})
createReport <- function(body, filename) {
# simulating expensive operation by a sleep
Sys.sleep(20)
pdf(file = filename)
plot(body)
dev.off()
}
output$report <- downloadHandler(
filename = function() { "report.pdf" },
content = function(file) {
shinyjs::disable("report")
result_val(NULL)
body <- body_content()
progress <- AsyncProgress$new(message = 'Creating report', detail = 'Please have some patience.')
future({
createReport(body, file)
progress$close()
return(1)
}) %...>% result_val()
}
)
observeEvent(result_val(), {
shinyjs::enable("report")
})
}
shinyApp(ui, server, options = list(display.mode = "showcase"))
#headerSection {
margin: -20px 0 20px;
color: #FAFAFA;
padding: 10px 10px;
box-shadow: 0 0 7px #000;
background: gray;
}
#headerSection a {
color: white !important;
text-decoration: underline;
}