penguin
penguin

Reputation: 1377

How to dynamically load shiny outputs as soon as their dependencies are available?

I have a shiny application with one input object which is a dependency for 2 output objects.

First output object takes the input values directly and second output object needs further calculation on input object value.

I want to load first output object as soon as I change input object and load second output object after further calculation is over.

The problem is both the objects are loaded simultaneously even though the dependencies for first output object are available earlier than those of second.

Here is my reproducible code. I want to display plot1 as soon as I change slider1 and keep the spinner on for plot2 until it is available.

library("ggplot2")
library("shiny")
library("shinycssloaders")
ui <- fluidPage(
          sliderInput("slider1", label = "Slider 1", min = 0, max = 100, step = 1, value = c(0,100)),
          withSpinner(plotOutput("plot1")),
          withSpinner(plotOutput("plot2"))

)

server <- function(input, output, session) {
  output$plot1 <- renderPlot({
    ggplot() + geom_point(aes(
      x = runif(n = 100, min = 0, max = 100),
      y = runif(
        n = 100,
        min = input$slider1[1],
        max = input$slider1[2]
      )
    ))
  })

  plot2_min <- reactive({
    Sys.sleep(time = 2)
    input$slider1[1]
  })

  plot2_max <- reactive({
    Sys.sleep(time = 2)
    input$slider1[2]
  })

  output$plot2 <- renderPlot({
    ggplot() + geom_point(aes(
      x = runif(n = 100, min = 0, max = 100),
      y = runif(
        n = 100,
        min = plot2_min(),
        max = plot2_max()
      )
    ))
  })
}

shinyApp(ui, server)

Upvotes: 3

Views: 693

Answers (1)

Pork Chop
Pork Chop

Reputation: 29397

As per my comment All reactive expressions are processed together and will wait for all dependencies before rendering even if you slow the second one down. You can however delay the second reactive using the debounce functionality, for more info refer here: https://shiny.rstudio.com/reference/shiny/1.0.2/debounce.html

Example below does will show you how one might use it, I put 2 sec wait on it:

library(ggplot2)
library(shiny)
library(shinycssloaders)
library(magrittr)

ui <- fluidPage(
  sliderInput("slider1", label = "Slider 1", min = 0, max = 100, step = 1, value = c(0,100)),
  withSpinner(plotOutput("plot1")),
  withSpinner(plotOutput("plot2"))

)

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

  data1 <- reactive({
    data.frame(x = runif(n = 100, min = 0, max = 100),
                        y = runif(n = 100,min = input$slider1[1],max = input$slider1[2]))

  })

  output$plot1 <- renderPlot({
    ggplot() + geom_point(aes(data1()$x,data1()$y))
  })

  plot2_min <- eventReactive(data1(),{
    input$slider1[1]
  })

  plot2_max <- eventReactive(data1(),{
    input$slider1[2]
  })

  data2 <- reactive({
    data.frame(x = runif(n = 100, min = 0, max = 100),
               y = runif(n = 100,min = plot2_min(),max = plot2_max()))
  }) %>% debounce(2000)

  output$plot2 <- renderPlot({
    ggplot() + geom_point(aes(data2()$x,data2()$y))
  })

}

shinyApp(ui, server)

enter image description here

Upvotes: 1

Related Questions