12

I am trying to build a web app with shiny and I would like to display the resulting plot of a R function in a popup window rather than in mainPanel. For instance, for the below example (from http://shiny.rstudio.com/articles/action-buttons.html), clicking on "Go" button would show the same plot but in a popup window.

I tried to add some javascript, but I have not succeeded yet... Can anyone help ?

Thank you in advance !

library(shiny)
ui <- fluidPage(
    actionButton("go", "Go"),
    numericInput("n", "n", 50),
 plotOutput("plot")
)
server <- function(input, output) {
  randomVals <- eventReactive(input$go, {
  runif(input$n)
  })
  output$plot <- renderPlot({
   hist(randomVals())
 })
}
shinyApp(ui, server)
Erica Fary
  • 363
  • 1
  • 2
  • 10

3 Answers3

16

Look into shinyBS package which offers modal popups. Example below shows the plot upon button click.

EDIT - Added a download button to the Modal

rm(list = ls())
library(shiny)
library(shinyBS)

shinyApp(
  ui =
    fluidPage(
      sidebarLayout(
        sidebarPanel(numericInput("n", "n", 50),actionButton("go", "Go")),
        mainPanel(
          bsModal("modalExample", "Your plot", "go", size = "large",plotOutput("plot"),downloadButton('downloadPlot', 'Download'))
        )
      )
    ),
  server =
    function(input, output, session) {

      randomVals <- eventReactive(input$go, {
        runif(input$n)
      })

      plotInput <- function(){hist(randomVals())}

      output$plot <- renderPlot({
        hist(randomVals())
      })

      output$downloadPlot <- downloadHandler(
        filename = "Shinyplot.png",
        content = function(file) {
          png(file)
          plotInput()
          dev.off()
        }) 

    }
)

enter image description here

Pork Chop
  • 28,528
  • 5
  • 63
  • 77
  • Thank you a lot for your answer, it works perfectly ! If I can ask one more thing, how do you add a button to download the plot ? I try to add directly a line in html like: `` but it does not display... – Erica Fary Nov 26 '15 at 16:38
  • 1
    I edited my answer to include the download button, happy coding! – Pork Chop Nov 26 '15 at 18:05
  • Thank you again ! I tried first in this way but it did not work. I try again with your code and it works perfectly... I should have a mistake in the code just above... Solved now ! Thank you. – Erica Fary Nov 27 '15 at 17:36
  • Fantastic this can be done and great answer. Any idea how to get this also to work with a `plotly_click` event? Can't seem to get it to work. – Gopala Apr 27 '16 at 16:17
  • @Gopala, maybe you can create a question, I can look into it with your example. Please be explicit what you want to achieve, I can write a bit of `Javascript` to complete it too – Pork Chop Apr 27 '16 at 16:51
  • http://stackoverflow.com/questions/36897594/use-bsmodal-in-the-shinybs-package-with-plotly-r-plotly-click-to-generate-new-pl – Gopala Apr 27 '16 at 18:06
8

Using native Shiny functionality

library(shiny)

ui <- fluidPage(
  actionButton("go", "Go"),
  numericInput("n", "n", 50)
)

server <- function(input, output) {
  randomVals <- eventReactive(input$go, {
    runif(input$n)
  })
  
  output$plot <- renderPlot({
    hist(randomVals())
  })
  
  observeEvent(input$go, {
    showModal(modalDialog(
      plotOutput("plot"),
      footer = NULL,
      easyClose = TRUE
    ))
  })
}

shinyApp(ui, server)

modal demo

Aurèle
  • 12,545
  • 1
  • 31
  • 49
3

You could use a conditional panel to show/hide an absolute panel containing your plot, setting the condition to some js variable toggled by a function attached to your button .

e.g.

conditionalPanel("popupActive==1",
                        absolutePanel(id = "popup", class = "modal", 
                                      fixed = FALSE, draggable = TRUE,
                                      top = 200, right = "auto", left = 400, 
                                      bottom = "auto",
                                      width = 500, height = 500,
                        plotOutput(#output plot stuff#)
                        )
                        )

Then toggle the value of popupActive in js to show/hide

  HTML('<head><script>popupActive = 0; function myFunction(){popupActive=!popupActive;} </script></head>'), HTML('<button id="go" type="button" class="btn btn-default action-button" onclick="myFunction()">Go</button>'),
user5219763
  • 1,284
  • 12
  • 19
  • Thank you a lot for your answer. However, I'm newbie in shiny/javascript/etc. and I try to add `HTML(''), HTML('') ` but it still does not work. And the value of popupActive should be toggled to 0 when popup window is closed... Excuse my ignorance, but may I ask you a more explicit (i.e. with js) answer ? – Erica Fary Nov 26 '15 at 08:18
  • 1
    Pork Chops answer is the way to go; shinyBS looks like a really useful package. For completeness though I've edited my answer to include an example of the some js that would work. The only modification you needed was to create the popActive global variable, and then to toggle it on button clicks... `popupActive=!popupActive` – user5219763 Nov 26 '15 at 15:24