You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ShinyJS实现Action Button随Plotly钻取状态切换显隐?

问题:Shiny应用中Plotly钻取后返回按钮无法自动隐藏

我搭建了一个带有Plotly钻取图表的简易Shiny应用。希望Action Button仅在Plotly点击事件发生时显示(该功能已实现),但返回主图表时需隐藏此按钮。目前点击图表后按钮会显示,但无法再次隐藏,导致应用仅能单次生效,需要实现其持续可用的效果。

解决方案

问题出在控制按钮显示的observe逻辑上:原代码仅在drills$category存在时执行toggle切换显示状态,但当点击"Return to State"按钮清空drills$category后,没有对应的逻辑来隐藏按钮。我们需要将toggle替换为根据drills$category的状态直接控制显示/隐藏:

  • 将原有的observe块修改为:
observe({
  if(length(drills$category)){
    shinyjs::show("clear")
  } else {
    shinyjs::hide("clear")
  }
})

这样当钻取触发(drills$category有值)时显示按钮,当点击返回按钮清空drills$category后,按钮会自动隐藏,实现持续可用的效果。

修改后的完整代码
library(tidyverse)
library(plotly)
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(shinyjs)


full_data <- tibble(
  State = c("IL", "IL", "IL", "IL", "IL", "IL", "IN", "IN", "IN", "IN", "IN", "IN"),
  City = c("Chicago", "Rockford", "Naperville", "Chicago", "Rockford", "Naperville","Fort Wayne", 
           "Indianapolis", "Bloomington", "Fort Wayne", "Indianapolis", "Bloomington"),
  Year = c("2008", "2008", "2008", "2009", "2009", "2009", "2008", "2008", "2008", "2009", "2009", "2009"),
  GDP = c(200, 300, 350, 400, 450, 250, 600, 400, 300, 800, 520, 375)
)


ui <- fluidPage(useShinyjs(),
                selectInput(inputId = "year",
                            label = "Year",
                            multiple = TRUE,
                            choices = unique(full_data$Year),
                            selected = unique(full_data$Year)),
                selectInput(inputId = "state",
                            label = "State",
                            choices = unique(full_data$State)),
                plotlyOutput("gdp_level", height = 200),
                shinyjs::hidden(actionButton("clear", "Return to State"))
)


server <- function(input, output, session) {
  
  
  drills <- reactiveValues(
    category = NULL,
    sub_category = NULL
  )
  
  
  gdp_reactive <- reactive({
    full_data %>%
      filter(Year %in% input$year) %>%
      filter(State %in% input$state)  
  })
  
  
  gdp_reactive_2 <- reactive({
    full_data %>%
      filter(Year %in% input$year) %>%
      filter(State %in% input$state) %>%
      filter(City %in% drills$category) 
  })
  
  
  
  gdp_data <- reactive({
    
    if (!length(drills$category)) {
      
      return(gdp_reactive())
      
    }
    
    else {
      
      return(gdp_reactive_2())
      
    }
    
  })
  
  
  output$gdp_level <- renderPlotly({
    gdp_data() %>% 
      plot_ly(
        x = ~Year,
        y = ~GDP,
        color = ~City,
        key = ~City,
        source = "gdp_level",
        type = "bar"
      ) %>% 
      layout(barmode = "stack", showlegend = T)
    
  })
  
  
  observeEvent(event_data("plotly_click", source = "gdp_level"), {
    
    x <- event_data("plotly_click", source = "gdp_level")$key
    
    if (!length(x))
      
      return()
    
    if (!length(drills$category)) {
      
      drills$category <- x
      
    }  else {
      
      drills$sub_category <- NULL
      
    }
    
  })
  
  
  # 修改后的按钮显示/隐藏逻辑
  observe({
    if(length(drills$category)){
      shinyjs::show("clear")
    } else {
      shinyjs::hide("clear")
    }
  })
  
  
  observeEvent(input$clear, drills$category <- NULL)
  
}


shinyApp(ui, server)

内容的提问来源于stack exchange,提问作者Harry Kalsted

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 11:40:25