带有动态文本的ShinyApp出现在多个UI元素的任何更改中

时间:2017-01-05 13:21:14

标签: r reactive-programming observable shiny

我有兴趣开发一个以下列方式行事的Shiny App:

  1. 在对用户界面元素数量进行任何更改后更新图表。 这是通过actionButton / isolate构造完成的。
  2. 显示警告文字,提示用户点击 更新 按钮。的 突出。
  3. 按下 更新 按钮后删除警告文字。的 突出。
  4. 实施例

    方法

    • 通过提供的一个示例绘制,以下示例提供了对修改直方图的两个功能的访问。
    • 直方图在 更新 按钮点击后更新。
    • 与UI交互后,observeEvent构造应更新警告消息,然后传递给renderText
    • 如果没有与UI的交互,renderText可以返回空字符串。
    • actionButton应将警告消息字符串值还原为空c("")可以使用insertUI / renderUI的替代方法。

    代码

    app.R

    library(shiny)
    
    ui <- fluidPage(titlePanel("Reactive UI"),
                    sidebarLayout(
                        sidebarPanel(
                            # Reactive text should appear upon any change here
                            sliderInput(
                                "bins",
                                "Number of bins:",
                                min = 1,
                                max = 50,
                                value = 30
                            ),
                            checkboxInput(
                                inputId = "chckBxLg",
                                label = "Log scale",
                                value = FALSE
                            )
                            ,
                            actionButton("btnUpdate", "Update")
                        ),
                        mainPanel(textOutput("msgTxt"),
                                  plotOutput("distPlot"))
                    ))
    
    # Define server logic required to draw a histogram
    server <- function(input, output) {
        # Create placeholder object for msg
        msgUpdateText <- c("")
    
        # Insert update message text upon change to UI elements
        observeEvent(eventExpr = {
            input$bins
            input$chckBxLg
        },
        handlerExpr = {
            # This message should only show after interaction with the UI
            isolate(msgUpdateText <<-
                        c("You have clicked something, update the chart"))
        })
    
        # Render text
        output$msgTxt <- renderText(msgUpdateText)
    
        output$distPlot <- renderPlot({
            input$btnUpdate
            isolate({
                x    <- faithful[, 2]
                if (input$chckBxLg) {
                    x <- log(x)
                }
                bins <-
                    seq(min(x), max(x), length.out = input$bins + 1)
    
                # Also delete the text message
                msgUpdateText <<- c("")
            })
    
            hist(x,
                 breaks = bins,
                 col = 'darkgray',
                 border = 'white')
        })
    }
    
    shinyApp(ui = ui, server = server)
    

    问题

    消息:

      

    您点击了某些内容,更新了图表

    只应在用户与用户界面互动后显示 {{后 消失 按下1}} ,而信息永久可见。

    App preview

    旁注

    提供的解决方案应该可以跨多个UI元素进行扩展。提供的 not-working,示例尝试捕获对两个UI元素的更改:

    actionButton

    我正在努力使代码能够容纳大量元素

    observeEvent(eventExpr = {
        input$bins      # Element 1
        input$chckBxLg  # Element 2
    },
    handlerExpr = {
        # This message should only show after interaction with the UI
        isolate(msgUpdateText <<-
                    c("You have clicked something, update the chart"))
    })
    

1 个答案:

答案 0 :(得分:2)

我想我已经设法达到了预期的效果。我已将必要的逻辑带入3 observeEvent次调用。第一个观察到任何输入变化并将变量设置为TRUE。第二个观察updatebutton并将变量设置为FALSE。第三个观察输入和更新按钮并根据变量呈现警告消息(如果它打印出来TRUE,否则它是空的)。

我发现的唯一问题是,它现在开始显示警告信息,但我还没有找到原因。

最终代码:

library(shiny)

ui <- fluidPage(titlePanel("Reactive UI"),
                sidebarLayout(
                  sidebarPanel(
                    # Reactive text should appear upon any change here
                    sliderInput(
                      "bins",
                      "Number of bins:",
                      min = 1,
                      max = 50,
                      value = 30
                    ),
                    checkboxInput(
                      inputId = "chckBxLg",
                      label = "Log scale",
                      value = FALSE
                    )
                    ,
                    actionButton("btnUpdate", "Update")
                  ),
                  mainPanel(uiOutput("msgui"),
                            plotOutput("distPlot"))
                ))

# Define server logic required to draw a histogram
server <- function(input, output) {
  # Initialize the value to check if a change happened
  Changebool <<- FALSE

  observeEvent(eventExpr = { #When an input is changed
    input$bins
    input$chckBxLg
  },
  handlerExpr = {  # Change the changebool to TRUE
    Changebool <<- TRUE
  }
  )

  observeEvent(eventExpr = { #When the update button is pressed
    input$btnUpdate
  },
  handlerExpr = {  # Change the changebool to FALSE
    Changebool <<- FALSE
  }
  )

  observeEvent({input$btnUpdate # If any of the inputs change or the update button is pressed
    input$bins
    input$chckBxLg},
               {  # Recreate the message-ui
                 output$msgui <- renderUI({
                   if (Changebool) {  # if a change has happened since last update
                     textOutput("msgTxt")  #Output text
                   } else {  #otherwise
                       #Output nothing
                   } 
                 })
               })

  # Render text
  output$msgTxt <- renderText("You have clicked something, update the chart")

  output$distPlot <- renderPlot({
    input$btnUpdate
    isolate({
      x    <- faithful[, 2]
      if (input$chckBxLg) {
        x <- log(x)
      }
      bins <-
        seq(min(x), max(x), length.out = input$bins + 1)
    })

    hist(x,
         breaks = bins,
         col = 'darkgray',
         border = 'white')
  })
}

shinyApp(ui = ui, server = server)

我必须承认我在这方面来回摆弄相当多,所以如果你发现代码中有任何奇怪的东西可以随意发表评论