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

R Shiny根据单选按钮及if语句切换96孔板着色方案问题排查

96孔板组件行/列着色切换功能失效问题

问题描述

我基于dataTable构建了一个96孔板组件,需要实现对特定单元格、行或列的着色功能,希望通过单选按钮控制是按行还是按列完成着色。

  • 选中水平按钮时期望效果:
    水平模式期望效果
  • 选中垂直按钮时期望效果:
    垂直模式期望效果
  • 实际运行异常效果:
    异常效果示意图

遇到的问题:添加用于切换选中单元格布局(行/列模式切换)的if语句后,孔板的着色完全不显示,推测是遗漏了某些语法细节。

初始完整代码

library(shiny)
library(shinythemes)
library(sortable)
library(colourpicker)
library(glue)
library(png)
library(dplyr)
library(DT)
library(rclipboard)


# 工具函数
plate96 = function(id) {
  div(
    style = "position: relative; height: 500px",
    tags$style(HTML(
      '
        .wells {
            height: 490px;
            width: 750px;
            overflow: hidden;
            min-height: 20px;
            padding: 19px;
            margin-bottom: 20px;
            border: 1px solid #e3e3e3;
            border-radius: 4px;
            -webkit-box-shadow: inset 0 1px 1px rgb(0 0 0 / 5%);
            box-shadow: inset 0 1px 1px rgb(0 0 0 / 5%);
            position: relative;
            transform: translateX(50%);
        }
        
        .wells:after {
            content: "";
            height: 450px;
            width: 690px;
            border: 1px solid;
            position: absolute;
            transform: translate(15px, -100%);
            z-index: -1;
        }
        
        .wells .corner-top {
            position: absolute;
            margin: -20px;
            width: 43px;
            height: 34px;
            transform: rotate(45deg);
            background-color: white;
            z-index: 1;
            left: 30px;
            border-right: 1px solid;
        }
        
        .wells .corner-bot {
            position: absolute;
            margin: -20px;
            width: 40px;
            height: 40px;
            transform: rotate(45deg);
            background-color: white;
            z-index: 1;
            left: 35px;
            bottom: 20px;
            border-top: 1px solid;
        }
        
        .wells .html-widget {
            transform: translateX(20px);
        }
        
        .wells thead tr th {
            font-weight: 100;
        }
        
        .wells table:after {
            content: "";
            border: 1px solid #ccc;
            position: absolute;
            height: 410px;
            width: 635px;
            z-index: -1;
            transform: translate(33px, -99%);
        }

        .wells table.dataTable.no-footer {
            border-spacing: 3px;
            border-bottom: unset;
        }
        
        .wells table.dataTable thead th {
            border-bottom: unset;
        }
        
        
        .wells tbody tr td:not(:first-of-type) {
            border-radius: 50%;
            border: 1px solid black;
            height: 15px;
            width: 15px;
            padding: 15px;
            font-size: 0;
        }
        
        .wells table.dataTable.cell-border tbody tr td:first-of-type {
            border: unset;
            border-right: 1px solid #ccc;
            font-weight: 900;
        }
        '
    )),
    div(
      style = "position: absolute; left: 50%; transform: translateX(-100%);",
      div(
        class = "wells",
        div(class = "corner-top"),
        div(class = "corner-bot"),
        DT::dataTableOutput(id, width = "90%", height= "100%")
      )
    )
  )
}

renderPlate96 = function(id, colors = rep("white", 96), byrow = TRUE) {
  stopifnot(is.character(colors) && length(colors) == 96)
  plate = matrix(1:96, nrow = 8, ncol = 12, byrow = byrow, dimnames = list(LETTERS[1:8], 1:12))
  colnames(plate) = stringr::str_pad(colnames(plate), 2, "left", "0")
  renderDataTable({
    datatable(
      plate,
      options = list(dom = 't', ordering = F),
      selection = list(target = 'cell'),
      class = 'cell-border compact'
    ) %>%
      formatStyle(
        1:12, 
        cursor = 'pointer', 
        backgroundColor = styleEqual(1:96, colors, default = NULL)
      )
  })
}

# app 主体代码
ui = fluidPage(
  plate96("plate"),
  tags$b("选中孔位:"),
  verbatimTextOutput("well_selected"),

  ####水平/垂直方向单选按钮####
  radioButtons("orientation_radio", 
               label = h3("水平/垂直切换"),
               c("水平,按行计数" = "Horizontal", 
                 "垂直,按列计数" = "Vertical")),
  
)



server = function(input, output, session){

  ####孔板颜色输出逻辑####
  output$plate = renderPlate96({
    
    if (input$orientation_radio == "Vertical") {
      return("plate",
        colors = c(
          rep("#eeeeee", 12),
          rep("#27408b", 12),
          rep("#0f8b44", 12),
          rep("#9400d3", 12),
          rep("#0701ff", 12),
          rep("white", 36)
        )
      )
    }
    
    else if (input$orientation_radio == "Horizontal") {
      return("plate",
        colors = c(
          rep("#eeeeee", 8),
          rep("#27408b", 8),
          rep("#0f8b44", 8),
          rep("#9400d3", 8),
          rep("#0701ff", 8),
          rep("white", 56)
        ),
        byrow = FALSE
      )
    }
  })
  
  
  output$well_selected = renderPrint({
    input$plate_cells_selected
  })
}



shinyApp(ui = ui, server = server)

已尝试的无效修改方案

根据建议尝试了两种修改方式,均未解决问题,代码如下:
第一种修改(嵌套调用renderPlate96):

####孔板颜色输出逻辑####
  output$plate = renderPlate96({
    
    if (input$orientation_radio == "Vertical") {
      renderPlate96("plate",
        colors = c(
          rep("#eeeeee", 12),
          rep("#27408b", 12),
          rep("#0f8b44", 12),
          rep("#9400d3", 12),
          rep("#0701ff", 12),
          rep("white", 36)
        )
      )
    }
    
    else if (input$orientation_radio == "Horizontal") {
      renderPlate96("plate",
        colors = c(
          rep("#eeeeee", 8),
          rep("#27408b", 8),
          rep("#0f8b44", 8),
          rep("#9400d3", 8),
          rep("#0701ff", 8),
          rep("white", 56)
        ),
        byrow = FALSE
      )
    }
  })

第二种修改(直接在代码块内写参数):

####孔板颜色输出逻辑####
  output$plate = renderPlate96({
    
    if (input$orientation_radio == "Vertical") {
      "plate"
        colors = c(
          rep("#eeeeee", 12),
          rep("#27408b", 12),
          rep("#0f8b44", 12),
          rep("#9400d3", 12),
          rep("#0701ff", 12),
          rep("white", 36)
        )
      
    }
    
    else if (input$orientation_radio == "Horizontal") {
      "plate"
        colors = c(
          rep("#eeeeee", 8),
          rep("#27408b", 8),
          rep("#0f8b44", 8),
          rep("#9400d3", 8),
          rep("#0701ff", 8),
          rep("white", 56)
        )
        byrow = FALSE
    }
  })

此外还尝试将renderPlate96替换为直接输出plate对象,同样没有效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:06:11