Pagedown: Using chrome_print() inside a Shiny App

Created on 27 Mar 2019  路  8Comments  路  Source: rstudio/pagedown

Hey,

I was thinking about implementing a shinyPrint() function that would allow capturing screenshots of current divs of the app.

My first try was:

shinyPrint <- function(
    id, 
    con,
    session = shiny::getDefaultReactiveDomain()
){
    # get the url
    url <- sprintf(
        "%s//%s:%s", 
        session$clientData$url_protocol, 
        session$clientData$url_hostname, 
        session$clientData$url_port
    )
    # screenshot the object
    pagedown::chrome_print(
        url, 
        output = con,  # temp file
        format = tools::file_ext(con), # extension of the temp file
        selector = sprintf("#%s", session$ns(id)) # to be sure to have the correct id
    )
}

On our old friend the Old Faithful Geyser Application :

ui <- fluidPage(
    titlePanel("Old Faithful Geyser Data"),
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins","Number of bins:",1,50,30)
        ),
        mainPanel(
            plotOutput("distPlot"), 
            downloadButton("foo", "foo")
        )
    )
)


server <- function(input, output, session) {

    output$distPlot <- renderPlot({
        x    <- faithful[, 2]
        bins <- seq(min(x), max(x), length.out = input$bins + 1)
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
    })

    output$foo <- downloadHandler(
        filename = function() {
            paste('data-', Sys.Date(), '.png', sep='')
        },
        content = function(con) {
            shinyPrint(id = "distPlot", con)
        }
    )
}

shinyApp(ui = ui, server = server)

But when I try to run that, I have a blank output:

Screenshot 2019-03-27 at 15 13 07

Running

# Just to be sure it's not related to the fact that it's a tempfile
output = tempfile(fileext = "png")
pagedown::chrome_print(
  "http://127.0.0.1:6745/", 
  output = output,
  format = "png",
  selector = "#distPlot"
)
browseURL(output)

From another R session works, though.

More information (if ever this helps)

If I launch the very same app, but add a Sys.Sleep() of 60 seconds, if I try to do a chrome_print() from another session, it times out.

So my guess is that chrome_print() fails to catch a Shiny app while it's busy.

Not sure if this is an issue you want to dig into. Just, if ever it's easy to fix, a shinyPrint() function wrapping chrome_print() would be nifty.

Colin

All 8 comments

Running chrome_print() inside any later tasks (such as a Shiny app, because shiny uses httpuv, which uses later to run the server) is very likely to be problematic because of this:
https://github.com/rstudio/pagedown/blob/fa26bc5a7dfad43aa8d9e62e512ee339e68e3b98/R/chrome.R#L129

This is the major caveat of chrome_print(). Hopefully https://github.com/r-lib/later/pull/84 will save us.

Ok, so... let's wait :)

I can make a PR to use a private event loop so that it's safer -- but the new version of later has not yet been released to CRAN. Do you want a PR now that has a Remotes field? You could hold off merging if you don't want to take a dependency on a package that's only on Github.

@wch Joe has already submitted a PR #127. Thanks!

Ah, I didn't notice that. Great!

So chrome_print still can't be used in a ShinyApp? or is there a fix in the dev version?

I haven't tested so far but with the current CRAN version, pagedown::chrome_print(..., async = TRUE) should work in a Shiny app.

Ok. I was getting some errors when attempting to print a .Rmd file. I needed to install chrome on my remote machine. Thanks!

Was this page helpful?
0 / 5 - 0 ratings