基于fbreitwieser/networkD3分支的Sankey图自定义颜色技术问询
给fbreitwieser/networkD3 add_zoom分支的Sankey图自定义颜色
我太懂你用这个停更旧分支的痛苦了——2016年之后就没更新的add_zoom分支,语法和后来CRAN正式版差得不是一点半点,连颜色设置的逻辑都不一样。下面给你两个靠谱的方法来搞定自定义颜色:
方法1:直接在数据框里指定颜色
这个是最直接的,也是这个旧分支支持的原生方式。你只需要在构建nodes和links数据框的时候,额外加一列color,把你要的颜色值填进去就行:
# 构建带颜色的节点数据框 nodes <- data.frame( name = c("用户", "浏览", "购买", "流失"), color = c("#2E86AB", "#F2D388", "#C98BB9", "#874C62") ) # 构建带颜色的链接数据框,用rgba可以加透明度 links <- data.frame( source = c(0, 0, 1), target = c(1, 3, 2), value = c(50, 30, 20), color = c("rgba(46,134,171,0.6)", "rgba(135,76,98,0.6)", "rgba(242,211,136,0.6)") ) # 调用sankeyGraph,记得加zoom参数开启缩放 sankeyGraph( links = links, nodes = nodes, fontSize = 14, nodeWidth = 35, zoom = TRUE )
这样生成的图里,每个节点和链接都会用上你指定的颜色,完全不需要额外修改。
方法2:用JS注入定制颜色逻辑
如果你想搞点更灵活的(比如让链接颜色自动跟源节点一致),可以借助htmlwidgets的onRender函数,给生成的Sankey图注入自定义D3代码——毕竟这个分支基于D3 v3,语法还是很稳定的:
library(networkD3) library(htmlwidgets) # 先生成基础的Sankey图(不用在数据框加color列) base_sankey <- sankeyGraph( links = links, nodes = nodes, fontSize = 14, nodeWidth = 35, zoom = TRUE ) # 注入自定义JS来设置颜色 custom_sankey <- onRender( base_sankey, ' function(el, x) { // 选中所有节点和链接 var nodes = d3.select(el).selectAll(".node"); var links = d3.select(el).selectAll(".link"); // 给节点设置自定义颜色(这里用了一组渐变色) var nodeColors = ["#2E86AB", "#F2D388", "#C98BB9", "#874C62"]; nodes.style("fill", function(d, i) { return nodeColors[i]; }); // 让链接颜色跟源节点一致,并且加50%透明度 links.style("stroke", function(d) { var sourceColor = d3.select(d.source.node).style("fill"); return sourceColor.replace("rgb", "rgba").replace(")", ",0.5)"); }); } ' ) # 显示定制后的图 custom_sankey
这个方法的好处是不用修改原始数据,适合需要动态调整颜色逻辑的场景。
注意事项
- 这个旧分支的参数是英式拼写!比如设置全局节点颜色的参数是
nodeColour,不是新版的nodeColor,链接颜色是linkColour,别写错了:# 全局统一颜色的写法 sankeyGraph( links = links, nodes = nodes, nodeColour = "#2E86AB", linkColour = "#999", zoom = TRUE ) - 因为分支停更太久,可能和新版R包有兼容性问题,如果遇到奇怪的报错,优先用前两种方法,尽量避免折腾依赖降级。
内容的提问来源于stack exchange,提问作者Matt Summersgill
相关产品推荐
相关产品推荐

