2

I have been trying to find a solution to this problem for quite some time. I tried appshot, but my tables and graphs show as blank.

Any help or recommendations would be very appreciated.

David
  • 432
  • 3
  • 10
  • Welcome to SO! Can you please add some more detail about what you are trying to achieve? It sounds like you want to take a screen shot..? – J.Con Oct 01 '19 at 22:12
  • Hey J.Con, I appreciate the reply. I'd like users to be able to download a static copy of the entire shiny app, with reactive values populated in tables and graphs, in order for them to share their results with others. Whether that be a pdf, image, etc. I'd like to preserve the current format of the html output as well. Thanks. – David Oct 01 '19 at 22:17

2 Answers2

3

You could use html2canvas JavaScript library to take screenshots.

For creating the prompt for download, I referenced this post: How to save img to user's local computer using HTML2canvas

And, to run arbitrary JavaScript, you need to load shinyjs library in R.

Please see the example app below:

library(shiny)
library(shinyjs)
library(DT)
library(ggplot2)

ui <- fluidPage(
    tags$head(
        # include html2canvas library
        tags$script(src = "http://html2canvas.hertzen.com/dist/html2canvas.min.js"),
        # script for creating the prompt for download
        tags$script(
            "
            function saveAs(uri, filename) {

                var link = document.createElement('a');

                if (typeof link.download === 'string') {

                    link.href = uri;
                    link.download = filename;

                    //Firefox requires the link to be in the body
                    document.body.appendChild(link);

                    //simulate click
                    link.click();

                    //remove the link when done
                    document.body.removeChild(link);

                } else {

                    window.open(uri);

                }
            }
            "
        )
    ),
    useShinyjs(),
    actionButton("screenshot","Take Screenshot"),
    dataTableOutput("table"),
    plotOutput("plot")


)

server <- function(input, output, session) {
    observeEvent(input$screenshot,{
        shinyjs::runjs(
            'html2canvas(document.querySelector("body")).then(canvas => {
                saveAs(canvas.toDataURL(), "shinyapp.png");
           });'
        )
    })


    output$table <- renderDataTable(iris)

    output$plot <- renderPlot(ggplot(data = iris) + 
                                  geom_point(aes(x = Sepal.Length, y = Sepal.Width)))
}

shinyApp(ui, server)
yusuzech
  • 5,896
  • 1
  • 18
  • 33
0

You can now use a dedicated package for this called shinyscreenshot. It uses the html2canvas library under the hood, but makes it very easy to use - simply call shinyscreenshot::screenshot() whenever you want to take a picture, and it'll download a PNG.

DeanAttali
  • 25,268
  • 10
  • 92
  • 118