3

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 https://shiny.rstudio.com/articles/generating-reports.html

The code from this site looks like:

app.R

shinyApp(
  ui = fluidPage(
    sliderInput("slider", "Slider", 1, 100, 50),
    downloadButton("report", "Generate report")
  ),
  server = function(input, output) {
    output$report <- downloadHandler(
      # For PDF output, change this to "report.pdf"
      filename = "report.html",
      content = function(file) {
        # Copy the report file to a temporary directory before processing it, in
        # case we don't have write permissions to the current working dir (which
        # can happen when deployed).
        tempReport <- file.path(tempdir(), "report.Rmd")
        file.copy("report.Rmd", tempReport, overwrite = TRUE)

        # Set up parameters to pass to Rmd document
        params <- list(n = input$slider)

        # Knit the document, passing in the `params` list, and eval it in a
        # child of the global environment (this isolates the code in the document
        # from the code in this app).
        rmarkdown::render(tempReport, output_file = file,
          params = params,
          envir = new.env(parent = globalenv())
        )
      }
    )
  }
)

report.Rmd

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

```{r}
# The `params` object is available in the document.
params$n
```

A plot of `params$n` random points.

```{r}
plot(rnorm(params$n), rnorm(params$n))
```

I have tried a lot like here:

How to pass table and plot in Shiny app as parameters to R Markdown?

Shiny: pass a plot variable to Rmarkdown document when generating a downloadable report

BUT for me it is not possible to transform my code to the provided example code above! The desired output would be something like this after clicking a "Generate Report" button:

enter image description here

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.