首页 > 解决方案 > 使用一个操作按钮更新不同 tabPanel 中的绘图

问题描述

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

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

情况:

  1. 点击去查看统一历史
  2. 更新 Unif 历史标题
  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)

标签: rshiny

解决方案


要在不单击 的情况下刷新标题图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))
  })

推荐阅读