2

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"
  )
})
rvrvrv
  • 881
  • 3
  • 9
  • 29

0 Answers0