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

R语言中使用foreignObject实现Sankeynetwork文本居中对齐

直接修改onRender里的JS逻辑即可,问题根源是之前写死了foreignObject的宽高和定位,没有和节点的实际坐标、尺寸匹配,同时插入的标签内容没加居中样式。调整后完整可运行代码如下:

library(networkD3)
library(htmlwidgets)
library(data.table)

set.seed(1999)
links <- data.table(
  src = rep(0:4, times=c(1,1,2,3,5)),
  target = sample(1:11, 12, TRUE),
  value = sample(100, 12)
)[src < target, ]  # 避免自环
nodes <- data.table(name=LETTERS[1:12])

## 给标签加统计值
txt <- links[, .(total = sum(value)), by=c('target')]
nodes[txt$target+1L, name := paste0(name, '<br>(', txt$total, ')')]

## 绘制桑基图
sn <- sankeyNetwork(Links=links, Nodes=nodes, Source='src', Target='target',
              Value='value', NodeID='name', fontSize=16, nodeWidth=50, width=600, height=300)

onRender(sn,
'
function(el,x) {
  // 移除默认文本标签
  d3.selectAll(".node text").remove()
  d3.selectAll(".node")
    .append("foreignObject")
    // 匹配节点实际位置、尺寸,避免偏移
    .attr("x", function(d) { return d.x; })
    .attr("y", function(d) { return d.y; })
    .attr("width", function(d) { return d.dx; })
    .attr("height", function(d) { return d.dy; })
    // 插入带居中样式的标签内容
    .html(function(d) { 
      return `<div style="width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; font-size: 16px; line-height: 1.2;">
        ${d.name}
      </div>` 
    })
}
'
)

核心调整点:

  • 去掉了之前写死的width=100、height=50固定值,直接读取每个节点自身的左上角坐标(d.x/d.y)和自适应尺寸(d.dx为节点宽度、d.dy为节点高度)设置foreignObject属性,让标签容器和节点框完全重合。
  • 在foreignObject内部嵌套占满全容器的div,用flex布局实现容器内内容的水平、垂直双向居中,同时给div加text-align: center属性,保证两行文本自身也保持居中对齐,字号、行高和初始设置的fontSize参数匹配即可。

运行后标签会完全贴合节点框实现双向居中,内部两行文字也会保持居中对齐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 09:54:22