我的 Shiny 应用程序的主要目标是通过(交互式)ggplots 显示大量数据。如果数据足够,显示绘图所需的时间可能长达约 10 秒,我想显示一个进度条以提供反馈。
我尝试了 withProgress 和 winProgressBar,但都没有反射(reflect) ggplots 出现所需的时间:两个进度条在实际绘图显示之前就消失了。
所以我的问题是:如何实现(任何类型的)进度条来反射(reflect) ggplots 出现在屏幕上所需的时间?
library(shiny)
library(ggplot2)
library(dplyr)
ui = fluidPage(
mainPanel(
uiOutput("plots")
)
)
server = function(input, output) {
#list of things I want to plot, which will be split over column wt
plotlist = sort(unique(mtcars$wt))[1:4]
observe({
pb = winProgressBar( #test 1: winProgressBar
title = 'observe', #test 1: winProgressBar
label = 'plotting' #test 1: winProgressBar
) #test 1: winProgressBar
message({ #test 1: winProgressBar
withProgress(message = 'ggplotting', value = 0, { #test 2: withProgress
for (i in plotlist) local({
nm <- i
temp.data <- filter(mtcars, wt == plotlist[nm])
plotAname <- paste0("plotA", nm)
output[[plotAname]] <- renderPlot(ggplot(temp.data, aes(x = mpg, y= cyl)) + geom_point())
plotBname <- paste0("plotB", nm)
output[[plotBname]] <- renderPlot(ggplot(temp.data, aes(x = mpg, y= drat)) + geom_point())
plotCname <- paste0("plotC", nm)
output[[plotCname]] <- renderPlot(ggplot(temp.data, aes(x = mpg, y= disp)) + geom_point())
plotDname <- paste0("plotD", nm)
output[[plotDname]] <- renderPlot(ggplot(temp.data, aes(x = mpg, y= hp)) + geom_point())
setWinProgressBar(pb, value = nm/10) #test 1: winProgressBar
incProgress(1/(length(plotlist))) #test 2: withProgress
}) #end of for()
}) #end of withProgress #test 2: withProgress
close(pb) #test 1: winProgressBar
}) #end of message #test 1: winProgressBar
}) #end of observe
output$plots <- renderUI({
withProgress(message = 'rendering', value = 0, { #test 3: withProgress
plot_output_list <- lapply(plotlist, function(i) {
incProgress(1/(length(plotlist))) #test 3: withProgress
#encompass everything in a div because lapply can only returns a single result per loop cycle.
div(style = "padding: 0px; margin: 0px;",
div(style = "position:relative; margin-bottom: -5px; padding: 0px;",
plotOutput(paste0("plotA", i))
),
div(style = "position:relative; margin-bottom: -5px; padding: 0px;",
plotOutput(paste0("plotB", i))
),
div(style = "position:relative; margin-bottom: -5px; padding: 0px;",
plotOutput(paste0("plotC", i))
),
plotOutput(paste0("plotD", i))
)
}) #end of lapply
}) #end of withProgress #test 3: withProgress
}) #end of output$plots
}
shinyApp(ui = ui, server = server)
此示例大约需要 4 秒才能显示其绘图。大约 1 秒后,所有三个测试进度条均已完成。
感谢您抽出宝贵时间来了解此内容!如果我可以提供任何说明,请告诉我。
最佳答案
它实际上并不是您想要生成的进度条。但是您可以在横幅中显示加载消息,这就是为什么我认为它在这里可能有用。只需将以下代码片段复制到应用程序的 ui 部分并根据需要调整颜色即可。
info_loading <- "Shiny is busy. Please wait."
your_color01 <- # define a color for the text
your_color02 <- # define a color for the background of the banner
tags$head(tags$style(type="text/css",
paste0("
#loadmessage {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
padding: 5px 0px 5px 0px;
text-align: center;
font-weight: bold;
font-size: 100%;
color: ", your_color01,";
background-color: ", your_color02,";
z-index: 105;
}
"))),
conditionalPanel(condition="$('html').hasClass('shiny-busy')",
tags$div(info_loading,id="loadmessage"))
根据需要随时调整参数(例如顶部位置)。 您还可以看到:shiny loading bar for htmlwidgets
关于r - 添加进度条以指示 Shiny 中的 ggplotting 进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53188175/