在 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)
输出:
我有一个 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)
输出: