Home > Net >  Delay while rendering graphics in Shiny
Delay while rendering graphics in Shiny

Time:12-30

I have a ShinyApp and am trying to make the charts not suffer from rendering delay when I omit and activate the sidebar in shinydashboard. My graphics are enclosed in a shiny::box and this delay always occurs when the graphic changes size. This is my reproducible app:

library(shiny)
library(shinydashboard)

header <- dashboardHeader(title = "Dashboard", titleWidth = 300)

sidebar <- dashboardSidebar(width = 300, 
                        
                            sidebarMenu(id = "tabs",
                                    
                                        menuItem(text = "Plot", tabName = "plot", icon = icon("chart-pie")) 
                                    
                                        )
                            )

body <- dashboardBody(

  tabItem(tabName = "plot",

  fluidPage(

    column(width = 12, 
       
           box(plotOutput(outputId = "plot1", click = "plot_click"), width = 6, title = 
"Gráfico 1"), 
       
           box(plotOutput(outputId = "plot2", click = "plot_click", width = "75%"), width = 6, title = "Gráfico 2")
       
           ) 
    )
  )

)

ui <- dashboardPage(header, sidebar, body, skin = "blue")

server <- function(input, output) {

  output$plot1 <- renderPlot({

    plot(x = data.frame(x = replicate(n = 1, expr = runif(n = 1, min = 1, max = 7))), 
         xlab = "A", ylab = "B")

  })

  output$plot2 <- renderPlot({

    plot(x = data.frame(x = replicate(n = 1, expr = runif(n = 1, min = 1, max = 7))), 
         xlab = "A", ylab = "B")

  })

}

shinyApp(ui, server)

Problem:

enter image description here

The graph 1 advances over another. This could not happen.

How to fix this?

CodePudding user response:

If you inspect element in the browser and toggle the sidebar on/off, you will see that the div that the image is contained in autoresizes as the window changes, but the image does not. This is because the width of the image is fixed, based on the size of the image output from R. For example, you will see that the div has width: 100%;, where as the img has width 515.

The delay you see comes from Shiny replotting the graph when the sidebar is toggled, that's why there's a delay. To get the image to resize, simply add the same css rule to the actual image itself, like so:

img {
    width: 100%;
}

This will automatically resize the image when the sidebar is toggled. Notice that shiny still replots the graph.

To include the CSS style, you can put it in the fluid page, like so:

          fluidPage(
            
            tags$head(
              tags$style(HTML("
      img {
          max-width: 100%;
          }"))
            ),
            
            column(width = 12,
                   box(plotOutput(outputId = "plot1", click = "plot_click"), width = 6, title = "Gráfico 1"), 
                   
                   box(plotOutput(outputId = "plot2", click = "plot_click", width = "75%"), width = 6, title = "Gráfico 2")
                   
            ) 
          )

Full app:

library(shiny)
library(shinydashboard)

header <- dashboardHeader(title = "Dashboard", titleWidth = 300)

sidebar <- dashboardSidebar(width = 300, 
                            sidebarMenu(id = "tabs",
                                        menuItem(text = "Plot", tabName = "plot", icon = icon("chart-pie"))
                                        )
                            )

body <- dashboardBody(
  tabItem(tabName = "plot",
          fluidPage(
            
            tags$head(
              tags$style(HTML("
      img {
          max-width: 100%;
          }"))
            ),
            
            column(width = 12,
                   box(plotOutput(outputId = "plot1", click = "plot_click"), width = 6, title = "Gráfico 1"), 
                   
                   box(plotOutput(outputId = "plot2", click = "plot_click", width = "75%"), width = 6, title = "Gráfico 2")
                   
            ) 
          )
  )
  
)

ui <- dashboardPage(header, sidebar, body, skin = "blue")

server <- function(input, output) {
  
  output$plot1 <- renderPlot({
    
    plot(x = data.frame(x = replicate(n = 1, expr = runif(n = 1, min = 1, max = 7))), 
         xlab = "A", ylab = "B")
    
  })
  
  output$plot2 <- renderPlot({
    
    plot(x = data.frame(x = replicate(n = 1, expr = runif(n = 1, min = 1, max = 7))), 
         xlab = "A", ylab = "B")
    
  })
  
}

shinyApp(ui, server)

Output:gif of app

  • Related