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

如何在Shiny中实现关联下拉框驱动的动态自适应模型选择器?

Shiny仪表盘动态下拉框实现方案

需求概述

开发包含多下拉框的Shiny仪表盘,实现以下功能:

  • 包含固定下拉框:数据类型(Data Type)、数据单位(Data Unit)、市场(Market)、子市场(Sub Market)
  • 当Market-Sub Market组合对应多个模型时,动态显示**模型选择器(Model Selector)**下拉框
  • 所有下拉框处于同一行,新增下拉框时自动调整尺寸适配布局

修改后的完整代码

library(shiny)
library(shinythemes)
library(data.table)

# 构建模型映射数据
market <- c("MarketA", "MarketB", "MarketC", "MarketA","MarketA")
submarket <- c("SubmarketX", "SubmarketY", "SubmarketZ", "SubmarketX","SubmarketX")
models <- c("modelA1", "modelB1", "modelC1", "modelA2","modelA3")
model_selector <- c("1","1","1","2","3")

mod.selection <- data.table(
  market_name = market,
  submarket_name = submarket,
  model_name = models,
  model_selector = model_selector
)

server <- function(input, output, session) {
  # 动态控制模型选择器的显示与下拉选项
  output$model_selector_ui <- renderUI({
    req(input$select_market, input$select_submarket)
    
    # 获取当前市场-子市场组合对应的模型列表
    model_list <- mod.selection[
      market_name == input$select_market & submarket_name == input$select_submarket,
      unique(model_selector)
    ]
    
    # 如果模型数量大于1,渲染模型选择器下拉框
    if(length(model_list) > 1) {
      selectInput(
        "select_model",
        label = h4("Model Selector"),
        choices = model_list,
        selected = model_list[1]
      )
    } else {
      # 否则返回空内容
      NULL
    }
  })
  
  # 根据选中的市场更新子市场选项
  observeEvent(input$select_market, {
    submarkets <- unique(mod.selection$submarket_name[mod.selection$market_name == input$select_market])
    updateSelectInput(session, "select_submarket", choices = submarkets, selected = submarkets[1])
  })
  
  # 可选:监听模型选择器的变化,获取对应的模型名称
  selected_model <- reactive({
    req(input$select_market, input$select_submarket)
    
    if(!is.null(input$select_model)) {
      mod.selection[
        market_name == input$select_market & submarket_name == input$select_submarket & model_selector == input$select_model,
        model_name
      ]
    } else {
      mod.selection[
        market_name == input$select_market & submarket_name == input$select_submarket,
        model_name
      ]
    }
  })
  
  # 可选:输出选中的模型名称用于测试
  output$selected_model <- renderPrint({
    cat("当前选中模型:", selected_model())
  })
}

ui <- fluidPage(
  theme = shinytheme("cerulean"),
  
  # 使用flex布局实现下拉框自动适配宽度
  tags$style(HTML("
    .flex-row {
      display: flex;
      gap: 15px;
      padding: 10px;
      flex-wrap: wrap;
    }
    .flex-item {
      flex: 1;
      min-width: 200px;
    }
  ")),
  
  div(class = "flex-row",
      # 数据类型下拉框
      div(class = "flex-item",
          selectInput("select1", label = h4("Data Type"),
                      choices = list("Type" = 1),
                      selected = 1),
          verbatimTextOutput("value1")
      ),
      # 数据单位下拉框
      div(class = "flex-item",
          selectInput("select2", label = h4("Data Unit"),
                      choices = list("Unit" = 1),
                      selected = 1),
          verbatimTextOutput("value2")
      ),
      # 市场下拉框
      div(class = "flex-item",
          selectInput("select_market", label = h4("Market"),
                      choices = unique(mod.selection$market_name),
                      selected = unique(mod.selection$market_name)[1]),
          verbatimTextOutput("value3")
      ),
      # 子市场下拉框
      div(class = "flex-item",
          selectInput("select_submarket", label = h4("Sub Market"),
                      choices = NULL),
          verbatimTextOutput("value4")
      ),
      # 动态模型选择器
      div(class = "flex-item",
          uiOutput("model_selector_ui"),
          verbatimTextOutput("value5")
      )
  ),
  
  # 可选:显示选中的模型信息
  verbatimTextOutput("selected_model"),
  
  sidebarLayout(
    sidebarPanel(),
    mainPanel()
  )
)

shinyApp(ui = ui, server = server)

关键实现说明

  1. 动态渲染模型选择器

    • 使用uiOutput("model_selector_ui")在UI中预留动态元素位置
    • 在server端通过renderUI判断当前Market-Sub Market组合的模型数量,大于1时生成下拉框,否则返回空
  2. 自适应布局实现

    • 通过自定义CSS的Flex布局(display: flex)让所有下拉框容器自动平分可用宽度
    • 设置flex: 1让每个下拉框自适应空间,min-width保证在窗口变小时不会过窄,gap控制间距
    • 相比传统的12栅格column布局,Flex布局更灵活,新增下拉框时会自动调整所有元素的宽度
  3. 数据逻辑优化

    • 使用unique()获取去重后的子市场和模型选项,避免重复值
    • 通过req()确保输入值存在后再执行逻辑,避免空值报错
    • 新增selected_model响应式对象,方便后续业务逻辑中获取选中的模型名称

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 21:15:00