In my application, I create plots depending on my users ui inputs and the datasets they upload. I would now like to add the functionality to show the plot in a new tab rather than just providing a normal downloadHandler
.
Here is a simplified version of my current implementation. (Note: Both examples posted here do not work in the RStudio browser. Use an external browser instead)
library(shinyjs)
library(shiny)
library(ggplot2)
addResourcePath(prefix = "plot", tempdir())
save_plot <- function(input, path) {
n <- input$n
df <- data.frame(x = 1:n, y = cumsum(rnorm(n)))
gg <- ggplot(df, aes(x,y)) + geom_line()
ggsave(gg, filename = path)
}
shinyApp(
fluidPage(
useShinyjs(),
sliderInput("n", "n", 100, 1000, 500),
actionButton("newtab", "open plot in new tab")
),
function(input, output, session){
observeEvent(input$newtab, {
save_plot(input, file.path(tempdir(), "plot.png"))
shinyjs::runjs("window.open('plot/plot.png', '_blank')")
})
}
)
My issue with this implementation is the popup blocker which (rather quietly) stops the new tabs from opening. I don't want to make my users disable their popup blockers just to use my web application.
Another thing I tried was to use a link and listen to the clicks like so
shinyApp(
fluidPage(
useShinyjs(),
sliderInput("n", "n", 100, 1000, 500),
tags$a(id = "link", href = "plot/plot.png", target = "_blank",
"open plot in new tab")
),
function(input, output, session){
shinyjs::onclick("link", {
save_plot(input, file.path(tempdir(), "plot.png"))
})
}
)
Here, the first plot looks good, but when pressing a second time, the old plot gets shown because save_plot
takes longer than the creation of a new tab. Also, I would like to have the option to style the ui element that triggers the new tab rather than being limited to a link.
I feel like I'm getting really close to a satisfying solution. Any help would be appreciated.