Home > OS >  How to pass a reactive plot generated in Shiny to Rmarkdown to generate dynamic reports
How to pass a reactive plot generated in Shiny to Rmarkdown to generate dynamic reports

Time:04-03

In short I would like to be able to generate a dynamic Rmarkdown report file (pdf or html) from my shiny app with a button click. For this I thought I will use parameterized Report for Shiny. But somehow I can not transfer the single puzzles to the desired aim:

With this code we can generate and download a reactive radarchart in R Shiny:

library(shiny)
library(radarchart)

js <- paste0(c(
  "$(document).ready(function(){",
  "  $('#downloadPlot').on('click', function(){",
  "    var el = document.getElementById('plot1');",
  "    // Clone the chart to add a background color.",
  "    var cloneCanvas = document.createElement('canvas');",
  "    cloneCanvas.width = el.width;",
  "    cloneCanvas.height = el.height;",
  "    var ctx = cloneCanvas.getContext('2d');",
  "    ctx.fillStyle = '#FFFFFF';",
  "    ctx.fillRect(0, 0, el.width, el.height);",
  "    ctx.drawImage(el, 0, 0);",
  "    // Download.",
  "    const a = document.createElement('a');",
  "    document.body.append(a);",
  "    a.download = 'radarchart.png';",
  "    a.href = cloneCanvas.toDataURL('image/png');",
  "    a.click();",
  "    a.remove();",
  "    cloneCanvas.remove();",
  "  });",
  "});"
), collapse = "\n")

ui <- pageWithSidebar(
  headerPanel('Radarchart Shiny Example'),
  sidebarPanel(
    checkboxGroupInput('selectedPeople', 'Who to include', 
                       names(radarchart::skills)[-1], selected="Rich"),
    actionButton('downloadPlot', 'Download Plot'),
    downloadButton('report', 'Generate Report')
  ),
  mainPanel(
    tags$head(tags$script(HTML(js))),
    chartJSRadarOutput("plot1", width = "450", height = "300"), width = 7
  )
)

server <- function(input, output) {
  output$plot1 <- renderChartJSRadar({
    chartJSRadar(skills[, c("Label", input$selectedPeople)], 
                 maxScale = 10, showToolTipLabel=TRUE) 
  })
}
shinyApp(ui, server)

enter image description here

What I would like to do is to implement: Generating downloadable reports enter image description here

CodePudding user response:

Basically your question already included all the building blocks. I only updated the report template to include the code to plot the radar chart. As a parameter I decided to pass the filtered dataset. In the server I only adjusted the specs for the params:

server <- function(input, output) {
  output$plot1 <- renderChartJSRadar({
    chartJSRadar(skills[, c("Label", input$selectedPeople)], 
                 maxScale = 10, showToolTipLabel=TRUE) 
  })
  
  output$report <- downloadHandler(
    filename = "report.html",
    content = function(file) {
      tempReport <- file.path(tempdir(), "report.Rmd")
      file.copy("report.Rmd", tempReport, overwrite = TRUE)
      
      params <- list(scores = skills[, c("Label", input$selectedPeople)])

      rmarkdown::render(tempReport, output_file = file,
                        params = params,
                        envir = new.env(parent = globalenv())
      )
    }
  )
}

Report.Rmd

---
title: "Dynamic report"
output: html_document
params:
  scores: NA
---

```{r}
chartJSRadar(params$scores, maxScale = 10, showToolTipLabel=TRUE)
```

enter image description here

  • Related