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

D3.js cluster布局节点矩形重叠,如何设置固定间距避免覆盖?

D3.js 流程图节点重叠问题修复方案

问题现象

使用D3.js绘制层级流程图时,第三层级的节点矩形出现重叠覆盖的情况,预期实现同级节点间保留固定边距、无重叠的效果。

根因分析

你当前使用的d3.cluster布局采用.size([width, height])配置时,会强制将整棵树的所有节点压缩到指定的宽高范围内,布局仅按节点数量平均分配水平空间,没有考虑你绘制的矩形本身的宽度和节点间需要预留的边距,因此某层级节点数量较多时就会出现坐标重合、矩形重叠的问题。

修复方案

修改核心配置和坐标计算逻辑即可解决:

  1. 将cluster布局的配置从.size()改为.nodeSize(),显式指定每个节点的水平占用总宽度(包含矩形本身宽度+预留边距)、垂直层级间距,保证同级节点不会互相挤压
  2. 布局计算完成后对整个容器做水平偏移,让整棵树在SVG画布中居中显示
  3. 节点坐标统一使用布局计算生成的d.x、d.y,避免手动计算层级高度出现偏差

修复后完整代码

const data = {
    "children": [
        {
            "name": "boss1",
            "children": [
                {"name": "mister_a","colname": "level3"},
                {"name": "mister_b","colname": "level3"},
                {"name": "mister_c","colname": "level3"},
                {"name": "mister_d","colname": "level3"}
            ],
            "colname": "level2"
        },
        {
            "name": "boss2",
            "children": [
                {"name": "mister_e","colname": "level3"},
                {"name": "mister_f","colname": "level3"}
            ],
            "colname": "level2"
        }
    ],
    "name": "CEO"
}

const svg = d3.select(this.$refs.svg)
const container = d3.select('svg g')

const width = this.$refs.svg.clientWidth,
      height = this.$refs.svg.clientHeight,
      marginTop = 25, 
      curveDegree = 50, 
      entityHeight = 300,
      nodeWidth = 100, // 节点矩形宽度,可按需调整
      nodeHorizontalGap = 20 // 同级节点间水平边距,可按需调整

// 核心修改:改用nodeSize配置,参数为[单个节点水平占用总宽度, 层级垂直间距]
const cluster = d3.cluster().nodeSize([nodeWidth + nodeHorizontalGap, entityHeight]);

const root = d3.hierarchy(data, function (d) {
    return d.children;
});
cluster(root);

// 容器水平偏移,让整棵树在画布中居中
const treeCenterOffsetX = width / 2 - root.x;
container.attr('transform', `translate(${treeCenterOffsetX}, 0)`);

// 绘制节点连线
container.selectAll('path')
    .data(root.descendants().slice(1))
    .join('path')
    .attr("d", function (d) {
        let curve = d.y - curveDegree
        return "M" + d.parent.x + "," + (d.parent.y + marginTop)
            + "C " + d.parent.x + "," + curve
            + " " + d.x + "," + curve
            + " " + d.x + "," + (d.y + marginTop);
    })
    .style("fill", 'none')
    .attr("stroke", '#ccc')

// 绘制节点矩形
container.selectAll("g")
    .data(root.descendants())
    .join("g")
    .append("rect")
    .attr("class", "shadow")
    .style("fill", '#fff')
    .style("stroke", '#000')
    .attr("width", nodeWidth)
    .attr("height", 30)
    .attr("transform", function (d) {
        return `translate(${d.x - nodeWidth / 2},${d.y + marginTop - 15})`
    })

你可以根据实际业务需求调整nodeHorizontalGap控制同级节点间距,修改entityHeight调整不同层级间的垂直距离。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:48:01