在 Shiny 中渲染图形时出现延迟

Delay while rendering graphics in Shiny

我有一个 ShinyApp,当我在 shinydashboard 中省略并激活侧边栏时,我试图使图表不会受到渲染延迟的影响。我的图形包含在 shiny::box 中,当图形改变大小时,这种延迟总是发生。这是我的可复制应用程序:

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)

问题:

图形 1 优于另一个。这不可能发生。

如何解决这个问题?

如果您检查浏览器中的元素并切换边栏 on/off,您会看到 div 中包含图像的 div 随着 window 的变化而自动调整大小,但是图像没有。这是因为图像的宽度是固定的,基于从 R 输出的图像的大小。例如,您会看到 div 的宽度为:100%;,而 img 的宽度为 515。

您看到的延迟来自 Shiny 在切换侧边栏时重新绘制图表,这就是延迟的原因。要调整图像大小,只需将相同的 css 规则添加到实际图像本身,如下所示:

img {
    width: 100%;
}

这将在切换边栏时自动调整图像大小。请注意,shiny 仍然会重新绘制图表。

要包含 CSS 样式,您可以将其放在流畅的页面中,如下所示:

          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")
                   
            ) 
          )

完整应用:

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)

输出: