I've built an extensive Shiny app which relies heavily on Highcharter for its graphics. Now I'm trying to make a download button that allows the user to download a ZIP file with multiple PDF files, each having a different chart.
I managed to get it to work with ggPlot (hat-tip to Shiny R Zip multiple PDFS for download), but cannot seem to figure it out with Highcharts. I know part of the problem is because Highcharts doesn't output an image, but rather an SVG(? or perhaps JSON?). So I'm stuck on how to convert, within R/Shiny code, the chart to a PDF, since it's not rendered or displayed in the browser.
I tried first to render as SVG, then use rsvg_pdf()
(from library rsvg
) to convert to PDF, but to render as SVG we need to open a rendering device and close it with dev.off()
, which saves the file. I couldn't find a way to capture this in-between and then pass it to rsvg_pdf()
.
Instead, would the solution lie in invoking the (unix) command-line, and do conversion there? Is there a way to pass a chart to the Highcharts exporting module without it showing up for the end-user?
Thanks a lot for your help!
See below for a reproducible example:
ui.R
library(shiny)
shinyUI(
fluidPage(
headerPanel(title="testing Downloadhandler"),
sidebarLayout(
sidebarPanel(
selectInput("ngear", "Select the gear number", c("Cylinders" = "cyl", "Transmission" = "am", "Gears" = "gear")),
submitButton("Update!"),br(),
),
mainPanel(
tabsetPanel(type="tab",
tabPanel("Plot", plotOutput("plot"),
downloadButton("downloadZippedPlots", "Download Zipped Plot")
)
)
)
)
)
)
Server.R
library(shiny)
library(highcharter)
shinyServer(function(input,output){
mtreact <- reactive({
mtcars[,c("mpg", input$ngear)]
})
output$plot <- renderPlot({
boxplot(mtreact())
})
output$downloadZippedPlots <- downloadHandler(
filename = function(){
paste("mtcars-plots-zipped", "zip", sep=".")
},
content = function(fname){
fs <- c()
tmpdir <- tempdir()
setwd(tempdir())
for (column in c("cyl", "am", "gear")) {
path <- paste(column, "pdf", sep=".")
fs <- c(fs, path)
# --- This works ---
pdf(paste(column, "pdf", sep="."))
boxplot(mtcars[,c("mpg", column)])
dev.off()
# --- This doesn't work ---
hchart(mtcars, "bar", hcaes(x=mpg, y=!!column))
# --- This also doesn't work ---
this_chart <- hchart(mtcars, "bar", hcaes(x=mpg, y=!!column))
print(this_chart)
dev.off()
}
zip(zipfile=fname, files=fs)
},
contentType = "zip"
)
})