有没有一种方法可以显示在Shiny中构建的地块,而不是等待所有地块? [英] Is there a way to display plots as they build in Shiny instead of waiting for all of them?

查看:103
本文介绍了有没有一种方法可以显示在Shiny中构建的地块,而不是等待所有地块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含许多情节的Shiny Dashboard,所有情节都需要花费几秒钟来构建.一旦构建了最后一个,它们都会显示出来.相反,我希望每个图在完成时立即显示.我了解R是单线程的,但是似乎必须要有一种将执行返回到显示代码"或类似的方法.

I have a Shiny Dashboard with many plots, all of which take multiple seconds to build. Once the last one builds, they all display. I would like instead for each plot to display as soon as it completes. I understand R is single-threaded, but it seems as though there must be a way to "return execution to the display code" or something like that.

此代码演示了该问题:

library(shiny)

ui <- fluidPage(
  title = "Page loading test"
  , h1("Page loading test")
  , plotOutput("plot1")
  , plotOutput("plot2")
  , plotOutput("plot3")
  , plotOutput("plot4")
)

server <- function(input, output) {
   output$plot1 <- renderPlot({
     Sys.sleep(10)
     plot(rnorm(50))
   })

   output$plot2 <- renderPlot({
     Sys.sleep(10)
     plot(rnorm(50))
   })

   output$plot3 <- renderPlot({
     Sys.sleep(10)
     plot(rnorm(50))
   })

   output$plot4 <- renderPlot({
     Sys.sleep(10)
     plot(rnorm(50))
   })
}

shinyApp(ui = ui, server = server)

睡眠只是为了模拟执行缓慢.

页面显示需要40秒钟.我希望页面花10s来显示plot1,然后再花10s来显示plot2,依此类推.是否可以在每个plot函数的底部调用像UpdatePage()这样的调用?

It takes 40s for the page to display. I would like the page to take 10s to display plot1, then an additional 10s to display plot2, etc. Is there a call like UpdatePage() that can be called at the bottom of each plot function?

在我的页面上,我正在加载正在运行的动画,以便用户知道正在发生的活动,这使得它们在一次加载时更加明显.

On my page, I have loading animations running so the user is aware activity is occurring, which makes it even more obvious when they load at once.

我当然可以拥有一个简单的页面,但是那样就不会成为仪表盘了. :)

I could, of course, have a simpler page, but then it wouldn't be a dashboard. :)

推荐答案

您可以使用reactiveTimer()定期刷新页面.

You can use reactiveTimer() to refresh your page regularly.

您可以将图保存在图的list中,以便在每次刷新时立即打印它们.

And you can save your plots in a list of plots to print them immediately at each refresh.

我不得不重新排列renderPlot函数的顺序,因此step迭代器一次只能渲染一个图

I had to reorder the renderPlot functions so the step iterator only renders one plot at a time

我还选择不立即开始第一个渲染以绘制正在加载"图.

Also I chose not to start the first render right away to plot "Loading" plots.

library(shiny)

ui <- fluidPage( 
  title = "Page loading test"
  , h1("Page loading test")
  , plotOutput("plot1")
  , plotOutput("plot2")
  , plotOutput("plot3")
  , plotOutput("plot4")
)

# Loading plot
plot(-1:1, -1:1, type = "n", xlab = "", ylab = "")
text(0,0, "Loading",cex = 5)
loading <- recordPlot()

plotlist <- vector("list",4) 
step <- 0 # which plot should be rendered next

server <- function(input, output, session) {
  autoInvalidate <- reactiveTimer(10, session)
  output$plot4 <- renderPlot({autoInvalidate();
    if(step>4){plotlist[[4]]}
    else if(step==4){step <<- step+1
    print("rendering step 4")
    Sys.sleep(10)
    plotlist[[4]] <<- {plot(rnorm(50));recordPlot()}} else loading
  })
  output$plot3 <- renderPlot({autoInvalidate();
    if(step>3){plotlist[[3]]}
    else if(step==3){step <<- step+1
    print("rendering step 3")
    Sys.sleep(10)
    plotlist[[3]] <<- {plot(rnorm(50));recordPlot()}} else loading
  })
  output$plot2 <- renderPlot({autoInvalidate();
    if(step>2){plotlist[[2]]}
    else if(step==2){step <<- step+1
    print("rendering step 2")
    Sys.sleep(10)
    plotlist[[2]] <<- {plot(rnorm(50));recordPlot()}} else loading
  })
  output$plot1 <- renderPlot({autoInvalidate();
    if(step>1){plotlist[[1]]}
    else if(step==1){step <<- step+1
    print("rendering step 1")
    Sys.sleep(10)
    plotlist[[1]] <<- {plot(rnorm(50));recordPlot()}} else {step <<-1;loading}
  })
}
shinyApp(ui = ui, server = server)

这篇关于有没有一种方法可以显示在Shiny中构建的地块,而不是等待所有地块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆