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

Shiny中实现带左侧固定分组块与共用滚动条的宽图可视化

实现Shiny固定左侧分组+分组内共用X轴滚动的布局

这个需求完全可行,用Shiny原生布局结合少量CSS就能简易实现,核心思路是:

  • 左侧固定一个非滚动的侧边栏,用来展示分组和图表名称
  • 将同组的图表放在同一个横向可滚动容器内,实现共用X轴滚动条

以下是修改后的完整代码:

library(shiny)
library(ggplot2)

test_ui <- function(id){
  ns <- NS(id)
  tagList(
    # 自定义CSS样式
    tags$style(HTML("
      /* 左侧固定栏样式 */
      .fixed-sidebar {
        position: fixed;
        width: 200px;
        height: 100vh;
        background-color: #f8f9fa;
        padding: 20px;
        border-right: 1px solid #dee2e6;
      }
      /* 右侧内容区,避开左侧固定栏 */
      .content-area {
        margin-left: 220px;
        padding: 20px;
      }
      /* 分组滚动容器 */
      .scroll-group {
        overflow-x: auto;
        margin-bottom: 30px;
      }
      /* 分组标题样式 */
      .group-title {
        font-size: 1.2em;
        font-weight: bold;
        margin-bottom: 10px;
      }
      /* 图表名称样式 */
      .plot-name {
        margin: 8px 0;
        color: #495057;
      }
    ")),
    # 整体布局
    fluidRow(
      # 左侧固定侧边栏
      div(class = "fixed-sidebar",
          div(class = "group-title", "分组1(MPG轴)"),
          div(class = "plot-name", "图表1: drat vs mpg"),
          div(class = "plot-name", "图表2: qsec vs mpg"),
          br(),
          div(class = "group-title", "分组2(Disp轴)"),
          div(class = "plot-name", "图表3: drat vs disp"),
          div(class = "plot-name", "图表4: qsec vs disp")
      ),
      # 右侧内容区
      div(class = "content-area",
          # 分组1:共用X轴滚动
          div(class = "scroll-group",
              plotOutput(outputId = ns("plot1"), height=100, width="1500px"),
              plotOutput(outputId = ns("plot2"), height=100, width="1500px")
          ),
          # 分组2:共用X轴滚动
          div(class = "scroll-group",
              plotOutput(outputId = ns("plot3"), height=100, width="1200px"),
              plotOutput(outputId = ns("plot4"), height=100, width="1200px")
          )
      )
    )
  )
}

test_server <- function(id){
  moduleServer(id, function(input, output, session){
    ns <- session$ns
    output$plot1 <- renderPlot({
      ggplot(mtcars, aes(x = mpg, y = drat)) +
        geom_point()
    })
    output$plot2 <- renderPlot({
      ggplot(mtcars, aes(x = mpg, y = qsec)) +
        geom_point()
    })
    output$plot3 <- renderPlot({
      ggplot(mtcars, aes(x = disp, y = drat)) +
        geom_point()
    })
    output$plot4 <- renderPlot({
      ggplot(mtcars, aes(x = disp, y = qsec)) +
        geom_point()
    })
  })
}

demoApp <- function() {
  ui <- fluidPage(
    test_ui("demo")
  )
  server <- function(input, output, session) {
    test_server("demo")
  }
  shinyApp(ui, server)  
}

demoApp()

关键实现细节:

  • 左侧固定栏:通过CSS的position: fixed实现固定定位,height: 100vh确保占满整个视口高度,不会随页面滚动移动
  • 分组滚动容器:每个分组包裹在scroll-group类的div中,overflow-x: auto让容器在图表宽度超出时自动显示横向滚动条,同组内的图表会共用这个滚动条
  • 内容区偏移:右侧内容区设置margin-left避开左侧固定栏,避免内容被遮挡
  • 样式优化:添加了基础的样式区分分组和图表名称,提升可读性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 04:43:21