2

I have a shiny app with a bunch of tabs with a few plots on each. There is also a sidebar with some controls, and when I change the inputs the plots may take a couple of seconds to refresh. This is absolutely fine (the data needs to be loaded from the database).

What is less fine is that when I switch away from a tab and then return to it later, first couple of seconds I see the old version of the plots, which can be very confusing, especially in cases when delays reach 3-5 seconds (doesn't happen often, but I couldn't find a way to prevent it from happening altogether).

Any suggestions would be greatly appreciated.

Below please some code that hopefully helps illustrate the problem if it's not clear from the description. Switch the tabs, move the slider towards either end to change the graph, and then go back to the original tab -- you should be able to see the image switch from the old version to new which is the behavior I want to get rid of.

library(shiny)

ui <- fluidPage(
   
   titlePanel("Old Faithful Geyser Data"),
   
   sidebarLayout(
      sidebarPanel(
         sliderInput("bins",
                     "Number of bins:",
                     min = 1,
                     max = 5000,
                     value = 3000)
      ),
      
      mainPanel(
        tabsetPanel(
          tabPanel("tab1",
                   plotOutput("distPlot1")
          ),
          tabPanel("tab2",
                   plotOutput("distPlot2")
          )
        )
      )
   )
)

server <- function(input, output) {
   
  output$distPlot1 <- renderPlot({
    x    <- rnorm(input$bins) 
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
    plot(1:input$bins, x)
  })
  
  output$distPlot2 <- renderPlot({
    x    <- rnorm(input$bins)
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
    plot(1:input$bins, x)
  })
}

shinyApp(ui = ui, server = server)
Nikolai
  • 65
  • 5

1 Answers1

2

Here's one idea. tabsetPanel has a id attribute. If set, it defines the name of the element in input that contains the value/title of the selected tab in the tabsetPanel. You could test that to see if the "correct" tab is selected inside each of your renderPlots and return NULL if the correct tab is not selected. I simulated your database delay by putting Sys.sleep(1) in each of the renderPlots in your MWE, and it seems to have the desired effect.

library(shiny)

ui <- fluidPage(
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 5000,
                  value = 3000)
    ),
    mainPanel(
      tabsetPanel(
        id="panels",
        tabPanel("tab1",
                 plotOutput("distPlot1")
        ),
        tabPanel("tab2",
                 plotOutput("distPlot2")
        )
      )
    )
  )
)

server <- function(input, output) {
  output$distPlot1 <- renderPlot({
    if (input$panels != "tab1") return()
    Sys.sleep(1)
    x    <- rnorm(input$bins) 
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
    plot(1:input$bins, x)
  })
  output$distPlot2 <- renderPlot({
    if (input$panels != "tab2") return()
    Sys.sleep(1)
    x    <- rnorm(input$bins)
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    plot(1:input$bins, x)
  })
}

shinyApp(ui = ui, server = server)
Limey
  • 10,234
  • 2
  • 12
  • 32
  • Thanks -- that's a great solution (I tried to upvote it but it didn't work for me -- probably not enough points or something like that). Unfortunately it's not very straightforward to use it in my case, as in my app the tabs are implemented via markdown, not via an explicit call to tabsetPanel (it's a flexdashboard app). I couldn't find how to access currently active page in flexdashboard -- if you happen to have any ideas, they would be greatly appreciated. Best regards, Nikolai – Nikolai Jul 28 '20 at 14:18
  • I've no experience with flesxdashboard alas, but I think maybe either of the two answers to [this question](https://stackoverflow.com/questions/61458456/change-second-tabset-on-click-in-flexdashboard) could be adapted to give you what you need. – Limey Jul 28 '20 at 14:25
  • Thanks , looks promising – Nikolai Jul 28 '20 at 14:37