如何将yEd生成的GraphML文件导入R并保留图形属性?
解决yWorks yEd GraphML文件导入R并保留样式的问题
我之前也碰到过类似的情况——igraph的read_graph对yWorks这类工具生成的自定义GraphML支持确实有限。yEd会加入大量自己的命名空间属性(比如y:、demostyle:前缀的内容),而igraph只认标准GraphML里带attr.type的属性,那些自定义样式相关的属性就直接被忽略了,这就是你看到警告的原因。要保留形状、颜色这些样式,我们得手动解析XML文件,把需要的信息提取出来再传给visNetwork。
下面是具体的操作步骤:
1. 加载所需工具包
我们需要用xml2解析XML结构,用visNetwork实现可视化:
library(xml2) library(visNetwork) library(dplyr) # 用于数据整理
2. 读取并解析GraphML文件
先把文件读成XML对象,同时定义好yWorks用到的自定义命名空间:
# 读取GraphML文件 graphml <- read_xml("data/graphml_example.graphml") # 提取文件中的命名空间,方便后续节点定位 ns <- xml_ns(graphml)
3. 提取节点信息(标签、形状、颜色)
首先先提取SharedData里的颜色映射表,再逐个节点提取ID、标签、形状和对应的颜色:
# 提取SharedData中的颜色映射关系 color_map <- xml_find_all(graphml, ".//y:SharedData/yjs:Color", ns) color_df <- data.frame( key = xml_attr(color_map, "x:Key"), color = xml_attr(color_map, "value"), stringsAsFactors = FALSE ) # 提取所有节点 nodes <- xml_find_all(graphml, ".//graph/node", ns) # 整理成visNetwork需要的节点数据框 node_df <- lapply(nodes, function(node) { node_id <- xml_attr(node, "id") # 提取节点显示标签 label <- xml_find_first(node, ".//y:Label.Text", ns) %>% xml_text() # 提取yEd里的形状类型,映射为visNetwork支持的形状 shape_type <- xml_find_first(node, ".//demostyle:FlowchartNodeStyle", ns) %>% xml_attr("type") vis_shape <- case_when( shape_type == "terminator" ~ "ellipse", shape_type == "document" ~ "rectangle", shape_type == "start1" ~ "circle", TRUE ~ "rectangle" # 兜底默认形状 ) # 解析颜色引用,匹配对应的颜色值 color_ref <- xml_find_first(node, ".//y:GradientStop[@color]", ns) %>% xml_attr("color") color_key <- gsub("\\{y:GraphMLReference (.*)\\}", "\\1", color_ref) node_color <- color_df$color[color_df$key == color_key] data.frame( id = node_id, label = label, shape = vis_shape, color = node_color, stringsAsFactors = FALSE ) }) %>% bind_rows()
4. 提取边信息
提取边的源节点、目标节点,以及对应的样式:
# 提取所有边 edges <- xml_find_all(graphml, ".//graph/edge", ns) # 整理成visNetwork需要的边数据框 edge_df <- lapply(edges, function(edge) { data.frame( from = xml_attr(edge, "source"), to = xml_attr(edge, "target"), arrows = "to", # 匹配yEd里的目标端箭头设置 color = "#000000", # 从yEd的Stroke属性提取的黑色边 width = 2, # 匹配yEd里的边厚度 stringsAsFactors = FALSE ) }) %>% bind_rows()
5. 用visNetwork生成可视化
现在把整理好的节点和边传入visNetwork,就能得到保留原样式的图了:
visNetwork(node_df, edge_df) %>% visNodes( font = list(size = 16, face = "Calibri", weight = "bold", color = "#FFFFFF") ) %>% # 匹配yEd里的字体设置 visOptions(highlightNearest = TRUE) # 可选:添加节点高亮交互
补充说明
- 如果你需要保留节点的原始位置,可以从
y:RectD的X、Y属性提取坐标,加入到node_df的x和y列,visNetwork会自动使用这些位置布局。 - 如果你的图里有更多yEd流程图形状,只需要补充
vis_shape的映射规则即可。
你之前用igraph导入的代码出现警告,就是因为这些自定义样式属性被忽略了:
library(igraph) example <- igraph::read_graph("data/graphml_example.graphml", format = "graphml")警告信息:
1: In read.graph.graphml(file, ...) : At foreign-graphml.c:651 :Ignoring because of a missing or unknown 'attr.type' attribute ...
内容的提问来源于stack exchange,提问作者user5580950
相关产品推荐
相关产品推荐

