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

如何在RShiny中用ggiraph实现带Tooltip的交互式ggraph树图

解决RShiny中ggiraph+ggraph交互式树图问题及Plotly替代方案

一、用ggiraph实现交互式ggraph树图

你遇到的核心问题是误用了ggraph的原生图层,只要替换为ggiraph提供的交互式图层,就能直接添加tooltip和data_id功能。具体来说,用geom_point_interactive替代geom_node_point,用geom_text_interactive替代geom_node_text,同时绑定ggraph布局自动生成的x、y坐标即可。

修改后的完整代码:

# Packages ----------------------------------------------------
library(shiny)
library(ggraph)
library(igraph)
library(ggiraph)

edges <- data.frame(c("Start", "Start"), c("P1", "P2"))
colnames(edges) <- c("from", "to")

vert <- data.frame(c("Start", "P1", "P2"), c(1, 2, 3), c("this is start", "node P1 info", "node P2 info"))
colnames(vert) <- c("name", "Value", "Info")

# Ui ---------------------------------------------------------
ui <- fluidPage(
  girafeOutput(outputId = "tree_plot_out")
)

# Server -----------------------------------------------------
server <- function(input, output, session) {
  #create Tree plot
  tree_plot <- reactive({
    g <- graph_from_data_frame(edges, vertices = vert) 
    
    ggraph(g) +
      geom_edge_link() +
      # 交互式节点点图层:绑定tooltip和data_id
      geom_point_interactive(
        aes(x = x, y = y, col = Value, 
            tooltip = Info, data_id = name)
      ) +
      # 交互式节点文本图层:自定义hover信息
      geom_text_interactive(
        aes(x = x, y = y - 0.1, label = Info, 
            tooltip = paste("节点:", name, "\n值:", Value), data_id = name),
        size = 5
      )
  })

  # 输出交互式图,可自定义hover样式和选择模式
  output$tree_plot_out <- renderGirafe({
    girafe(ggobj = tree_plot(), 
           options = list(opts_hover(css = "fill:red;"),
                          opts_selection(type = "single")))
  })

}

shinyApp(ui = ui, server = server)

关键细节:

  • geom_point_interactive和geom_text_interactive完全兼容ggraph的布局,自动读取布局生成的x、y坐标
  • 在aes中直接绑定顶点数据作为tooltip内容,data_id可用于后续获取用户选中的节点(通过input$tree_plot_out_selected)
  • girafe的options参数可自定义hover高亮样式、选择模式等交互行为

二、Plotly替代方案

Plotly可以绘制带边的网络图,只是需要手动处理节点坐标和边的连接逻辑,以下是适配你的需求的完整示例:

# Packages ----------------------------------------------------
library(shiny)
library(plotly)
library(igraph)

edges <- data.frame(c("Start", "Start"), c("P1", "P2"))
colnames(edges) <- c("from", "to")

vert <- data.frame(c("Start", "P1", "P2"), c(1, 2, 3), c("this is start", "node P1 info", "node P2 info"))
colnames(vert) <- c("name", "Value", "Info")

# Ui ---------------------------------------------------------
ui <- fluidPage(
  plotlyOutput(outputId = "tree_plot_out")
)

# Server -----------------------------------------------------
server <- function(input, output, session) {
  output$tree_plot_out <- renderPlotly({
    g <- graph_from_data_frame(edges, vertices = vert)
    # 获取树图布局坐标,和ggraph逻辑一致
    layout <- layout_as_tree(g, root = V(g)["Start"])
    vert$x <- layout[,1]
    vert$y <- layout[,2]
    
    # 整理边的坐标数据:匹配起点和终点的位置
    edge_coords <- merge(edges, vert[,c("name","x","y")], by.x = "from", by.y = "name") %>%
      merge(vert[,c("name","x","y")], by.x = "to", by.y = "name", suffixes = c("_from", "_to"))
    
    # 绘制节点(带hover信息和点击标识)
    p <- plot_ly(vert, x = ~x, y = ~y, type = "scatter", mode = "markers+text",
                 text = ~Info, textposition = "bottom center",
                 marker = list(color = ~Value, size = 15),
                 hoverinfo = "text",
                 text = ~paste("节点:", name, "\n值:", Value, "\n信息:", Info),
                 customdata = ~name) %>%
      # 添加边的线条
      add_trace(data = edge_coords, x = ~x_from, y = ~y_from, 
                xend = ~x_to, yend = ~y_to,
                type = "scatter", mode = "lines",
                line = list(color = "#888"),
                hoverinfo = "none", showlegend = FALSE) %>%
      # 隐藏坐标轴,适配树图样式
      layout(xaxis = list(visible = FALSE), yaxis = list(visible = FALSE),
             showlegend = FALSE)
    
    # 注册点击事件,用于后续交互
    event_register(p, "plotly_click")
  })
  
  # 监听节点点击事件示例
  observeEvent(event_data("plotly_click"), {
    clicked_node <- event_data("plotly_click")$customdata
    print(paste("点击了节点:", clicked_node))
  })
}

shinyApp(ui = ui, server = server)

关键细节:

  • 用layout_as_tree获取和ggraph一致的树布局坐标
  • 手动处理边的坐标匹配,通过add_trace添加线条作为边
  • 节点的hover信息直接在text参数中定义,点击事件通过event_register和event_data监听

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 03:16:13