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

如何在Shiny Dashboard中用线条/箭头连接Box实现树状图

问题描述

我希望通过Box组件复现下方的树状图效果,请问能否为这些Box添加类似图中的连接线或箭头,实现组件间的关联展示?

树状图示例

当前代码
library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(title = "Connected Boxes"),
  dashboardSidebar(),
  dashboardBody(
    fluidRow(
      column(12,
             fluidRow(
               column(2,),
               column(5,),
               column(1,),
               column(4,
                      box(
                        title = "No ADC received",
                        width = 12,
                        height = 80,
                      ))
               
             ),
             fluidRow(
               column(2,),
               column(5,
                      box(
                        title = "Trodelvy",
                        width = 12,
                        height = 80,
                        style = "background-color: red; border-color: #red;",
                      )
               ),
               column(5,)
               
             ),
             fluidRow(
               column(2,),
               column(5,),
               column(1,
               ),
               column(4,
                      box(
                        title = "EV",
                        width = 12,
                        height = 80,
                        style = "background-color: lightblue; border-color: #lightblue;",
                        
                      ))
               
             ),
             fluidRow(
               column(2,
                      box(
                        title = "Bladder",
                        width = 12,
                        height = 80,
                      )
               ),
               column(5,),
               column(5,)
               
             ),
             fluidRow(
               column(2,),
               column(5,),
               column(1,),
               column(4,
                      box(
                        title = "No ADC received",
                        width = 12,
                        height = 80,
                      ))
               
             ),
             fluidRow(
               column(2,),
               column(5,
                      box(
                        title = "EV",
                        width = 12,
                        height = 80,
                        style = "background-color: lightblue; border-color: #lightblue;",
                        
                      )
               ),
               column(5,)
               
             ),
             fluidRow(
               column(2,),
               column(5,),
               column(1,
                      textOutput("arrow2") 
               ),
               column(4,
                      box(
                        title = "Trodelvy",
                        width = 12,
                        height = 80,
                        style = "background-color: red; border-color: #red;",
                      ))
               
             )
      )
    )
    
  )
)

server <- function(input, output) {}

shinyApp(ui, server)
可行解决方案

要给Shiny的Box组件添加连接线或箭头,有三种实用方案可选:

方案1:CSS伪元素绘制(适合固定简单布局)

给目标Box添加自定义ID,通过CSS的::before/::after伪元素结合绝对定位,直接绘制线条和箭头。这种方式无需额外依赖,适合布局固定的场景。

示例修改代码:

ui <- dashboardPage(
  dashboardHeader(title = "Connected Boxes"),
  dashboardSidebar(),
  dashboardBody(
    tags$style(HTML("
      /* 给需要定位的Box设置相对定位 */
      .connected-box {
        position: relative;
      }
      /* 绘制Bladder到EV的连接线+箭头 */
      #bladder-box::after {
        content: '';
        position: absolute;
        top: 50%;
        right: -180px;
        width: 180px;
        height: 2px;
        background-color: #333;
        transform: translateY(-50%);
      }
      #bladder-box::before {
        content: '';
        position: absolute;
        top: 50%;
        right: -10px;
        transform: translateY(-50%);
        border: solid #333;
        border-width: 0 2px 2px 0;
        padding: 3px;
        transform: rotate(-45deg);
      }
      /* 可添加更多连接规则 */
    ")),
    fluidRow(
      column(2,
             box(
               title = "Bladder",
               width = 12,
               height = 80,
               id = "bladder-box",
               class = "connected-box"
             )
      ),
      # 其他Box添加对应id和connected-box类,比如EV的box设置id="ev-box"
      # ... 剩余原有代码
    )
  )
)

方案2:专业可视化包(适合复杂/交互式树状图)

如果布局复杂或需要交互式效果,推荐用visNetwork或DiagrammeR这类专业绘图包,将Box逻辑转换为节点-边关系,自动生成带连接的树状图。

示例(使用visNetwork):

library(shiny)
library(shinydashboard)
library(visNetwork)

ui <- dashboardPage(
  dashboardHeader(title = "Connected Boxes"),
  dashboardSidebar(),
  dashboardBody(
    fluidRow(
      column(12,
             visNetworkOutput("tree_plot", height = "600px")
      )
    )
  )
)

server <- function(input, output) {
  output$tree_plot <- renderVisNetwork({
    # 定义节点(对应原Box的内容和样式)
    nodes <- data.frame(
      id = 1:7,
      label = c("Bladder", "EV", "Trodelvy", "No ADC received", "No ADC received", "EV", "Trodelvy"),
      color = c("white", "lightblue", "red", "white", "white", "lightblue", "red")
    )
    # 定义边(对应Box间的连接关系)
    edges <- data.frame(
      from = c(1,1,2,2,3,3),
      to = c(2,3,4,6,5,7),
      arrows = "to"
    )
    # 生成可视化
    visNetwork(nodes, edges) %>%
      visLayout(hierarchical = list(direction = "UD", sortMethod = "directed")) %>%
      visNodes(shape = "box", height = 80, width = 200)
  })
}

shinyApp(ui, server)

方案3:SVG自定义绘制(适合高度自定义场景)

在页面中添加SVG容器,通过JS或Shiny的服务器端计算Box的位置坐标,动态绘制连接线。这种方式能实现最精准的自定义,但需要一定的前端知识。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:52:15