如何将操作按钮引用为闪亮的插入图(insertUI / removeUI)

时间:2019-02-19 08:44:07

标签: r shiny

我问过this question in the RStudio community却没有得到帮助,所以我在这里尝试:

我正在尝试向我的应用程序添加以下功能:当用户插入绘图时,应该出现一个删除按钮,专门删除同时插入的绘图。该应用程序基于insertUI和removeUI。

这将是示例应用程序。

library(shiny)
library(shinydashboard)

# Example data

a<-(letters)
b<-rnorm(length(letters), 4,2)
c<-rnorm(length(letters), 10,15)
d<-c(1:10,20:30,45:49)

data<-data.frame(a,b,c,d)
names(data)<-c("name","v1","v2","v3")

# UI

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    actionButton("add", "Add"),
    radioButtons("add_elements","", c("Element1",   "Element2"))
  ),
  dashboardBody(
    fluidRow( tags$div(id="placeholder")
    )
))

# Server Logic

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

 # Initialize empty vector
  inserted<- c()

  # Observer
  observeEvent(input$add, {
    id_add <- paste0(input$add, input$add_elements)

    insertUI(selector = '#placeholder', where = "afterEnd",
             ui= switch(input$add_elements,
                        'Element1'= plotOutput(id_add),
                        'Element2' = plotOutput(id_add))
    )

    output[[id_add]] <- 
      if (input$add_elements == "Element1") 

        renderPlot({
          plot(data[,1],data[,2])

          }) else if (input$add_elements == "Element2") 

          renderPlot({
            plot(data[,1],data[,4])
            })
    inserted <<- c(id_add,inserted)
    insertUI(
      selector = "#placeholder",
      where = "afterEnd",
      ui = tags$div(actionButton("remove_button", "Remove"))
      )})

  ## Remove Elements ###
  observeEvent(input$remove_button, {
    removeUI(
      selector = paste0('#', inserted[length(inserted)])
    )
    inserted <<- inserted[-length(inserted)]
  })
}

shinyApp(ui = ui, server = server)

插入绘图时,它会获得一个ID,例如1Element1或2Element2。我现在想知道删除按钮如何仅引用具有此确切ID的图?

到目前为止,我已经使用了一个单独的删除按钮,该按钮通过定义存储ID的向量来删除最后插入的绘图。

selector = paste0('#', inserted[length(inserted)])

当用户需要比较多个图时,这不是很有用。我对使用这些选择器的了解有限,绝对不知道如何为每个仅删除相应图的图合并一个删除按钮。任何帮助将不胜感激。

此外,this link可能会有所帮助,因为它显示了相似的功能(我显然无法实现)。

1 个答案:

答案 0 :(得分:2)

在这种情况下,我总是将'list'与'reactiveValues'一起使用,如下所示:

library(shiny)
library(shinydashboard)

# Example data

a<-(letters)
b<-rnorm(length(letters), 4,2)
c<-rnorm(length(letters), 10,15)
d<-c(1:10,20:30,45:49)

data<-data.frame(a,b,c,d)
names(data)<-c("name","v1","v2","v3")

# UI

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    actionButton("add", "Add"),
    radioButtons("add_elements","", c("Element1",   "Element2"))
  ),
  dashboardBody(
    uiOutput("myUI")
  ))

# Server Logic

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

  alld <- reactiveValues()
  alld$ui <- list()

  output$myUI <- renderUI({
    alld$ui
  })

  # Observer
  observeEvent(input$add, {
    id_add <- length(alld$ui)+1

    alld$ui[[id_add]] <-  list(
      plotOutput(paste0("plt",id_add)),
      actionButton(paste0("remove_button", id_add), "Remove")
    )


      if (input$add_elements == "Element1"){
        output[[paste0("plt",id_add)]] <- renderPlot(plot(data[,1],data[,2]))
      } else {
        output[[paste0("plt",id_add)]] <- renderPlot(plot(data[,1],data[,4]))
      }
    })



  ## Remove Elements (for all plots) ###
observe({
  lapply(seq_len(length(alld$ui)), function(i){
    id_add <- i
    observeEvent(input[[paste0("remove_button", id_add)]], {
      alld$ui[[id_add]][1] <- NULL
    })
  })

})


}

shinyApp(ui = ui, server = server)