如何使用R的networkD3包forceNetwork函数绘制部分有向图
问题原因
networkD3包的forceNetwork函数的arrows参数原生仅支持传入单个逻辑值,不支持按边维度配置的向量输入。你传入逻辑向量时,函数仅会读取第一个元素的值,全局应用到所有边,这是你所有边都显示箭头的核心原因;而linkColour参数原生支持向量输入,因此你的原有逻辑可以正常生效。
解决方法
我们可以通过htmlwidgets包注入自定义JS代码,动态控制每条边的箭头显示状态,步骤如下:
- 原有绘图代码中,将
arrows参数固定设为TRUE(保证箭头标记的基础定义被生成) - 对生成的网络图对象使用
onRender函数,注入JS代码按边的edge_dir值控制箭头是否显示
完整可运行代码示例
library(networkD3) library(htmlwidgets) # 你的原有绘图代码,仅修改arrows参数为TRUE network <- forceNetwork (Links = links_df, Nodes = node_df, Source = "tid1", Target = "tid2", Value = "edge_dir", NodeID = "node_id", Nodesize = "node_size", Group = "node_type", colourScale = JS("d3.scaleOrdinal(d3.schemeCategory20);"), fontSize = 10, linkDistance = 100, radiusCalculation = JS(" Math.sqrt(d.nodesize)+6"), charge = -30, linkColour = ifelse(links_df$edge_dir == 10, "black","red"), opacity = 1, zoom = TRUE, # 这里固定设为TRUE,后续用JS过滤不需要的箭头 arrows = TRUE, opacityNoHover = TRUE, clickAction = NULL) # 注入JS代码按需隐藏箭头 network <- onRender(network, ' function(el, x) { d3.select(el) .selectAll(".link") .style("marker-end", function(d) { // d.value对应你传入的edge_dir字段值 return d.value === 10 ? "url(#arrowhead)" : "none"; }) } ') # 查看效果 network
效果验证
运行修改后的代码后,edge_dir=10的黑色边会保留箭头,edge_dir=5的红色边会自动隐藏箭头,符合你需要的部分有向图效果。
内容的提问来源于stack exchange,提问作者Camilla9347
相关产品推荐
相关产品推荐

