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

D3.js径向树图表如何将节点圆形替换为SVG环形图(donut)

实现方案

核心改动思路

你当前的代码是直接在节点位置渲染圆形,只需将单个circle替换为承载环形图的分组容器即可实现需求,具体改动步骤如下:


步骤1:补充节点的百分比数据

先给原始数据的每个节点增加百分比字段,示例:

var data = {
  "name": "AirtelApp",
  "percent": 60, // 新增百分比字段
  "children": [
    { 
      "name": "airteltopicsOne",
      "percent": 75, // 新增
      "children": [
        { "name": "airteltopicsOne1.1", "percent": 90 }, // 新增
        { "name": "airteltopicsOne1.2", "percent": 45 }, // 新增
      ]
    },
    // 其余节点同理补充percent字段
  ]
};

步骤2:定义环形图生成器

在节点渲染逻辑前新增D3环形图相关生成器配置:

// 环形图尺寸和原有圆形尺寸匹配
const donutWidth = 10; // 环形的宽度
const outerRadius = 30.5;
const innerRadius = outerRadius - donutWidth;

// 饼图生成器,仅展示百分比和剩余值两部分
const pie = d3.pie()
  .sort(null)
  .value(d => d);

// 环形路径生成器
const arc = d3.arc()
  .innerRadius(innerRadius)
  .outerRadius(outerRadius);

// 环形图配色:第一部分是已完成占比,第二部分是剩余占比
const color = d3.scaleOrdinal()
  .range(['#4CAF50', '#e0e0e0']);

步骤3:替换原有圆形节点为环形图节点

把你原来直接生成circle的节点逻辑,替换为生成分组容器,在容器内渲染环形图:

// 原来的var node = g.selectAll('.node')...那段整体替换为下面的代码
var node = g
  .selectAll('.node')
  .data(nodes.descendants())
  .join('g') // 替换为g作为节点容器
  .attr('class', 'node')
  .attr(
    'transform',
    (d) => `
      rotate(${(d.x * 180) / Math.PI - 90})
      translate(${d.y},0)
    `
  );

// 每个节点容器内渲染环形图
node.each(function(d) {
  // 生成环形数据:[百分比值, 剩余值]
  const pieData = pie([d.data.percent, 100 - d.data.percent]);
  // 渲染环形路径
  d3.select(this)
    .selectAll('path')
    .data(pieData)
    .join('path')
    .attr('d', arc)
    .attr('fill', (d, i) => color(i));
  // 可选:环形中间显示百分比数值
  d3.select(this)
    .append('text')
    .attr('text-anchor', 'middle')
    .attr('dy', '0.3em')
    .attr('font-size', '10px')
    // 修正文字旋转,保证正显
    .attr('transform', d.x >= Math.PI ? 'rotate(180)' : '')
    .text(`${d.data.percent}%`);
});

步骤4:微调原有文字标签位置

因为节点从圆形变成了环形,原有标签的偏移量可以稍微调大,避免和环形重叠,修改fonts部分的x属性即可:

.attr('x', (d) => (d.x < Math.PI === !d.children ? 36 : -36)) // 把原来的6/-6改成36/-36即可

效果参考

预期效果


注意事项

  • 如果需要不同层级的节点环形大小不同,可以根据d.depth调整outerRadius和innerRadius的数值
  • 环形图的配色可以根据业务需求自行修改color的range值
  • 原有节点的hover交互可以直接绑定在.node类上,无需额外调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 03:18:04