【问题标题】:Update plots in different tabPanels with one action button Shiny使用一个操作按钮更新不同 tabPanel 中的绘图
【发布时间】:2021-04-06 11:57:30
【问题描述】:

在我正在构建的一个更大的应用程序中,我需要使用一个操作按钮更新不同 tabPanel 中的多个绘图。

现在,按下操作按钮后的绘图更新工作。 但是,如果我回到之前的 tabPanel,我想使用 dataNorm 或 dataUnif 中的缓存值来更新绘图的标题。

情况:

  1. 点击前往查看统一历史记录
  2. 更新统一历史标题
  3. 转到 plotNorm tabPanel
  4. 点击去查看正常历史记录
  5. 更新规范历史标题
  6. 返回 plotUnif tabPanel(不要点击 go!)
  7. 尝试更新标题...

任何帮助将不胜感激!! :)

下面是例子:

library(shiny)

ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
            tabsetPanel(id = "tabset",
                        tabPanel("plotUnif",
                                 numericInput("unifCount", "Count", 100),
                                 sliderInput("unifRange", "Range", min = -100, max = 100, value = c(-10, 10)),
                                 textInput(inputId = 'titleUnif', "Change Title"),
                                 plotOutput("plotUnif")
                        ),
                        tabPanel("plotNorm",
                                 numericInput("normCount", "Count", 100),
                                 numericInput("normMean", "Mean", 0),
                                 numericInput("normSd", "Std Dev", 1),
                                 textInput(inputId = 'titleNorm', "Change Title"),
                                 plotOutput("plotNorm")
                        )
            ),
            actionButton("go", "Plot")
        ),
        mainPanel(
            "Bla"
        )
    )
)

server <- function(input, output){
    
    # Record how many times go has been pushed
    v <- reactiveValues(go_rec = 0L)
    
    # Compute new dataUnif only if input$go in new and on that tab (wanted effect: otherwise return cached value)
    dataUnif <- eventReactive(input$go,{
        shiny::req(input$go > v$go_rec, input$tabset == "plotUnif", cancelOutput = T)
        
        v$go_rec <- input$go
        return(runif(input$unifCount, input$unifRange[1], input$unifRange[2]))
    })
    
    # same as dataUnif
    dataNorm <- eventReactive(input$go,{
        shiny::req(input$go > v$go_rec, input$tabset == "plotNorm", cancelOutput = T)
        
        v$go_rec <- input$go
        return(rnorm(input$normCount, input$normMean, input$normSd))
    })
    
    # Disply hist (be able to change title)
    output$plotUnif <- renderPlot({
        shiny::req(dataUnif())
        hist(dataUnif(), main = input$titleUnif)
    })
    
    output$plotNorm <- renderPlot({
        shiny::req(dataNorm())
        hist(dataNorm(), main = input$titleNorm)
    })
}

shinyApp(ui, server)

【问题讨论】:

  • 你应该看看{shiny}提供的update*函数,例如shiny::updateTextInput()
  • 不幸的是,添加标题只是这里的一个示例。在更复杂的应用程序中,dataUnif/dataNorm 和 renderPlot 语句之间会发生各种反应式计算和子集。
  • 好的,但是有很多 update* 函数。很难想象将这些更新放在observe 环境中是行不通的

标签: r shiny


【解决方案1】:

要在不点击actionButton 的情况下刷新标题图,您需要在绘制一次图后取消阻止req。一个解决方案是将它们的状态保存在reactiveValues

  # Record how many times go has been pushed and which plot has been plotted once
  v <- reactiveValues(go_rec = 0L,
                      go_Unif = FALSE, 
                      go_Norm = FALSE)
  
  # Compute new dataUnif only if input$go in new and on that tab or plot already done)
  dataUnif <- eventReactive(input$go,{
    shiny::req(input$go > v$go_rec || v$go_Unif, input$tabset == "plotUnif", cancelOutput = T)
    
    v$go_rec <- input$go
    v$go_Unif <- TRUE
    return(runif(input$unifCount, input$unifRange[1], input$unifRange[2]))
  })
  
  # same as dataUnif
  dataNorm <- eventReactive(input$go,{
    shiny::req(input$go > v$go_rec || v$go_Norm, input$tabset == "plotNorm", cancelOutput = T)
    
    v$go_rec <- input$go
    v$go_Norm <- TRUE
    return(rnorm(input$normCount, input$normMean, input$normSd))
  })

【讨论】:

  • 感谢 HubertL,这确实有效。只是现在即使我确实更改了计数或参数,runif 和 rnorm 仍然可以计算。 (在我的真实场景中,这两个计算代表了非常昂贵的组合)。如果计数或参数没有改变,我想实现一种使用缓存值的方法,同时仍然更新过滤器(或更改示例中的标题)
  • 在每个面板中放置一个操作按钮可能更容易
猜你喜欢
  • 2021-07-16
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2018-12-20
  • 1970-01-01
相关资源
最近更新 更多