Reputation: 1377
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
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)
Upvotes: 1