当前位置:  开发笔记 > 开发工具 > 正文

仅在用户查看输出时计算闪亮

如何解决《仅在用户查看输出时计算闪亮》经验,为你挑选了1个好方法。

我有Shiny的问题,我不知道这是一个错误还是我错过了一些东西.我试图找到一个解决方案,但我似乎无法在网上找到这个问题的参考.

我有一个按下按钮时应该运行的功能,但它只在用户按下按钮后查看输出时才会运行.

这有点奇怪,所以我创建了一个最小的例子.我有两个标签.在第一个中,我选择一个数字(平均值),在第二个选项卡中,我绘制了该值的值.该按钮位于第一个选项卡中,但"create.plot"功能仅在转到tab2时才开始运行.为了清楚起见,我创建了这个'loading.div',它在函数运行时显示出来.

library(shiny)
library(shinyjs)

create.plot <- function(mean)
{
  shinyjs::show('loading.div')
  y <- rep(NA,10)
  for(i in 1:10)
  {
    y[i] <- rnorm(1,mean=mean)
    Sys.sleep(0.5)
  }
  shinyjs::hide('loading.div')

  return(list(y=y, test='Now it runs from tab1'))
}

server <- function(input, output, session) {

  run.function <- eventReactive(input$run,create.plot(input$mean))

  output$plot.y <- renderPlot({
    plot(run.function()[['y']])
  })

  output$test <- renderText({
    run.function()[['test']]
  })
}

ui <- fluidPage(shinyjs::useShinyjs(),
  hidden(div(id='loading.div',h3('Loading..'))),
  tabsetPanel(

  tabPanel('tab1',
    numericInput(inputId = 'mean',label='Mean', value=1),
    actionButton(inputId = 'run', label='Run')
    #,textOutput('test')   ## Uncommenting this line, it works.
    ),

  tabPanel('tab2',
    plotOutput('plot.y'))
  )
)

shinyApp(server=server,ui=ui)

为了确保问题是用户在tab1时没有查看输出,我创建了一个测试字符串.如果取消注释该行,则问题是"修复":该功能在用户点击按钮后直接运行.但是,这只能起作用,因为他正在查看tab1中的输出.

这成为一个严重的问题,因为我有一个闪亮的仪表板,有很多标签.有带输入的选项卡和带输出的选项卡.我希望在单击按钮时运行该功能,但它仅在用户进入"输出"选项卡时运行.

这是一个已知的问题吗?有变通方法吗?



1> Benjamin..:

不可见的反应元素被视为"暂停",并且在取消暂停之前不会更新它们的值.默认情况下,直到它们在屏幕上呈现时才会发生这种情况.

即使不可见,也可以通过更改其挂起状态来设置要更新的元素.您可以使用该outputOptions功能执行此操作.

对于output$test元素,您需要运行

outputOptions(output, "test", suspendWhenHidden = FALSE)

如果您想要更新多个元素,即使不可见,也可以使用

lapply(c("test1", "test2", "test3"),
       function(x) outputOptions(output, x, suspendWhenHidden = FALSE)

但请注意,这意味着所有计算都将立即执行.根据计算的大小,这可能会降低应用程序的性能.例如,如果有一个生成的图并且需要花费一些时间来渲染,并且只有一小部分用户会看到该图,那么在用户请求它以防止放慢速度之前将其保持暂停可能是谨慎的.计算更常用的元素.

EDITS

事实证明"情节不能提前呈现,因为它们没有宽度和高度."(https://github.com/rstudio/shiny/issues/1409).所以我们必须做一些诡计来提前渲染情节:

我们可以选择我们的情节的尺寸,而不是shiny自动适应它.这意味着如果屏幕放大,情节不会增长.

library(shiny)
library(shinyjs)

create.plot <- function(mean)
{
  print("working.....")
  shinyjs::show('loading.div')
  y <- rep(NA,10)
  for(i in 1:10)
  {
    y[i] <- rnorm(1,mean=mean)
    Sys.sleep(0.5)
  }
  shinyjs::hide('loading.div')

  y
}

server <- function(input, output, session) {

  run.function <- eventReactive(input$run,create.plot(input$mean))

  output$plot.y <- renderPlot({
      plot(run.function())
    },
    width = 72 * 5,
    height = 72 * 3
  )

  outputOptions(output, "plot.y", suspendWhenHidden = FALSE)
}

ui <- fluidPage(shinyjs::useShinyjs(),
                hidden(div(id='loading.div',h3('Loading..'))),
                tabsetPanel(

                  tabPanel('tab1',
                           numericInput(inputId = 'mean',label='Mean', value=1),
                           actionButton(inputId = 'run', label='Run')
                  ),

                  tabPanel('tab2',
                           plotOutput('plot.y'))
                )
)

shinyApp(server=server,ui=ui)


起初我以为它可能与`eventReactive`有关,但是进一步的调查把我带到https://github.com/rstudio/shiny/issues/1409,这表明`plotOutput`选择不运行时没有输出要绘制,因为它无法确定大小.如果我们明确设置绘图大小,`outputOptions`将起作用.我将在答案中包含两个如何使用情节来完成这项工作的例子,但实际上,迈克的答案可能是最容易理解的方法.
好吧,只能得到一个工作的例子,所以我将在这一点上放手.就像我说的那样,考虑到"plotOutput"的限制,我认为Mike的答案是你最好的方法.
推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有