如何在d3.js中制作反向进化树(树结构翻转)?
实现反向进化树的几种方法
方法一:直接反转坐标映射(最快实现)
无需修改数据结构,在绘制节点和连线时直接反转径向半径的计算逻辑:
- 假设原代码中径向布局的总半径为
radius,节点的y值代表到根节点的距离:- 绘制节点时,将原本的
translate(${d.y}, 0)改为translate(${radius - d.y}, 0) - 径向连线生成器的半径参数同步改为
d => radius - d.y
- 绘制节点时,将原本的
示例代码片段:
// 节点位置变换 g.selectAll("circle") .data(root.descendants()) .join("circle") .attr("transform", d => `rotate(${d.x * 180 / Math.PI - 90}) translate(${radius - d.y}, 0)`) .attr("r", 2.5); // 适配反转后的连线生成 const link = d3.linkRadial() .angle(d => d.x) .radius(d => radius - d.y);
方法二:修改层级数据的深度值
通过反转节点的depth属性,让布局工具自动生成反向位置:
- 构建层级数据后,先计算整个树的最大深度:
const root = d3.hierarchy(data); const maxDepth = d3.max(root.descendants(), d => d.depth);
- 遍历所有节点,反转深度值:
root.each(d => { d.depth = maxDepth - d.depth; // 如果用了sum/count计算节点权重,也可同步反转: // d.value = totalValue - d.value; });
- 正常调用
d3.tree()或d3.cluster()布局即可,此时布局逻辑会自动适配反转后的层级结构。
方法三:调整布局的尺寸范围
如果使用了比例尺映射节点深度到半径,直接反转比例尺的范围:
- 原代码可能为(根在外侧、叶子在中心的配置):
const y = d3.scaleLinear() .domain([0, maxDepth]) .range([radius, 0]);
- 修改为根在中心、叶子在外侧的配置:
const y = d3.scaleLinear() .domain([0, maxDepth]) .range([0, radius]);
- 后续节点和连线的
y值均使用y(d.depth)即可。
注意事项
- 若树结构有自定义大小计算(如
root.sum()或root.count()),需同步调整对应的权重映射逻辑,确保大小展示符合反向需求。 - 连线生成器的逻辑必须和节点坐标逻辑保持一致,避免出现连线错位问题。
内容的提问来源于stack exchange,提问作者senior_script
相关产品推荐
相关产品推荐

