- 数据可视化
- 前端
- 图表库
【免费下载链接】G6
♾ A Graph Visualization Framework in JavaScript.
生态树(Dendrogram)布局是 G6 图可视化框架中面向层次聚类数据的经典树形布局,其核心特点是所有子节点处于同一层级、忽略节点尺寸(每个节点按 1px 处理),非常适合表达分类体系、算法族谱、基因谱系等层次结构。读完本文,你将掌握该布局的全部配置项(方向、间距、辐射模式)、它与treeToGraphData数据转换的配合方式,以及如何结合源码理解其底层实现。
布局概述:什么是生态树布局
生态树布局适用于层次聚类数据的可视化。与 紧凑盒(CompactBox)布局 等其他树形布局相比,它的显著特征有三个:
- 所有子节点布局在同一层级:同一父节点的直接子节点全部对齐到同一水平(或垂直)线上,视觉上呈现"等高"的层状结构;
- 不考虑节点大小:布局计算时不读取节点的宽高,避免节点尺寸差异导致层级错位;
- 每个节点被当成 1px 处理:参与布局计算的节点统一按 1 个像素点看待,因此整体结构紧凑、规则,尤其适合节点数量较多的树。
这一特性决定了它在节点大小差异大、需要按尺寸展示的场景下(此时更适合 MapNodeSize 等变换 配合其他布局)需要谨慎选用,而在追求整齐层级的分类树场景中则非常合适。
快速上手:最小配置示例
在 G6 中通过Graph构造参数里的layout字段即可启用生态树布局,type固定为dendrogram:
const graph = new Graph({ container: 'container', data, // 由 treeToGraphData 转换后的图数据 layout: { type: 'dendrogram', direction: 'LR', // 布局方向,默认 LR nodeSep: 30, // 同一层级节点间距(px) rankSep: 250, // 不同层级间距(px) radial: false, // 是否启用辐射状布局 }, }); graph.render();这是官方文档给出的最小配置骨架,其中direction、nodeSep、rankSep、radial四个参数共同决定了整棵树的形态,下文逐一详解。
配置项详解(Options)
配置项总表
| 属性 | 描述 | 类型 | 默认值 | 必选 |
|---|---|---|---|---|
| type | 布局类型 | dendrogram | - | ✓ |
| direction | 布局方向,可选值见下文 | LR|RL|TB|BT|H|V | LR | |
| nodeSep | 节点间距,即同一层级节点之间的距离,单位像素 | number | 20 | |
| rankSep | 层级间距,即不同层级之间的距离,单位像素 | number | 200 | |
| radial | 是否启用辐射状布局,说明见下文 | boolean | false |
说明:
nodeSep与rankSep均以像素为单位。从源码结构看,dendrogram布局的实现来自@antv/hierarchy包(见 packages/g6/src/layouts/index.ts 的export { compactBox, dendrogram, indented, mindmap } from '@antv/hierarchy'),这两个参数控制的是布局计算坐标系中的间距值,实际渲染时还需结合视口缩放(zoom)综合感知。
direction:六种布局方向
树布局的方向选项共 6 种,决定了根节点位置与树展开方向:
TB:根节点在上,向下逐层布局。适合自上而下的组织结构图、决策树;BT:根节点在下,向上逐层布局。适合自下而上表达"汇聚"关系的树;LR:根节点在左,向右逐层布局。横向空间利用率高,标签阅读方向自然,是默认方向;RL:根节点在右,向左逐层布局,与LR镜像对称;H:根节点在中间,左右水平对称布局,左右两侧子树镜像展开;V:根节点在中间,上下垂直对称布局,上下两侧子树镜像展开。
方向选择直接决定了与之匹配的边类型与标签摆放策略:横向方向(LR/RL)通常搭配cubic-horizontal边,纵向方向(TB/BT)搭配cubic-vertical边,详见下文实战示例。
radial:辐射状布局模式
radial用于启用辐射状(放射状)布局模式。启用后,节点不再沿直线方向展开,而是以根节点为中心,按层级呈同心圆环分布:层数越深的节点离根节点越远,同层节点分布在同一圆环上。
使用建议(文档原话):
若
radial设置为true,建议将direction设置为'LR'或'RL'以获得最佳效果。
原因在于辐射模式下,节点沿根节点四周的角度铺开,LR/RL这类单侧展开方向能保证子树的扇区划分连续不重叠,视觉最均衡。辐射形态与 case-radial-dendrogram.ts 这类"径向树"场景天然契合,也可配合 PlaceRadialLabels 变换 优化标签排布。
源码级原理:dendrogram 在 G6 中的实现链路
内置注册与导出
从源码可以确认生态树布局是 G6 的内置布局之一,无需手动注册即可使用:
- 导出实现:
dendrogram布局函数由@antv/hierarchy提供并统一导出,见 packages/g6/src/layouts/index.ts; - 注册到内置扩展表:在 packages/g6/src/registry/build-in.ts 的
layout分类下注册了dendrogram: dendrogram as any,同表还包括compact-box、mindmap、indented等树形布局; - 加载内置扩展:
registerBuiltInExtensions()会遍历该表并逐一register('layout', type, extension)(见 packages/g6/src/registry/build-in.ts),因此new Graph({ layout: { type: 'dendrogram' } })开箱即用。
通用布局选项(BaseLayoutOptions)
dendrogram作为布局家族成员,同样继承 G6 的通用布局配置(见 packages/g6/src/layouts/types.ts),在实战中这些选项与树形布局配合密切:
preLayout: boolean:是否在初始化元素之前预计算布局。开启后元素首次渲染即处于最终位置,避免"先乱后正"的跳动,测试示例中普遍设置为true;nodeFilter / comboFilter:过滤参与布局的节点/combo;width / height:布局区域尺寸,默认取画布宽高;enableWorker: boolean:是否在 Web Worker 中运行布局,适用于大规模树;animation: boolean:是否启用布局动画过渡。
注意:
preLayout不适用于流水线(pipeline)布局,且isLayoutInvisibleNodes(不可见节点是否参与布局)仅在preLayout为true时生效,这是源码中明确标注的约束。
完整实战:数据准备与可运行示例
树形数据转换 treeToGraphData
G6 的图数据结构(nodes+edges)与树形数据结构(children嵌套)不同,使用生态树布局前需要先将树形数据转换为图数据。G6 提供了内置工具函数treeToGraphData:
import { Graph, treeToGraphData } from '@antv/g6'; // data 为嵌套 children 的树形 JSON,如仓库测试数据集 // packages/g6/__tests__/dataset/algorithm-category.json const data = treeToGraphData(treeData); const graph = new Graph({ container: 'container', autoFit: 'view', data, layout: { type: 'dendrogram', /* ... */ }, });仓库中的官方示例均使用algorithm-category.json数据集,该文件位于 packages/g6/tests/dataset/algorithm-category.json,结构为多级嵌套的算法分类树,非常适合演示生态树效果。
示例一:LR 横向生态树
对应官方示例 basic.js 与测试用例 layout-dendrogram-basic.ts:
const graph = new Graph({ container: 'container', autoFit: 'view', data: treeToGraphData(data), node: { style: { labelText: (d) => d.id, // 非叶子节点标签放左侧,叶子节点放右侧,贴合 LR 展开方向 labelPlacement: (d) => (d.children?.length ? 'left' : 'right'), labelBackground: true, // 锚点放在左右两侧,供边连接 ports: [{ placement: 'right' }, { placement: 'left' }], }, }, edge: { type: 'cubic-horizontal', // 横向三次贝塞尔边,与 LR 方向匹配 }, layout: { type: 'dendrogram', direction: 'LR', // H / V / LR / RL / TB / BT nodeSep: 36, rankSep: 250, preLayout: true, }, behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element', 'collapse-expand'], }); graph.render();示例二:TB 纵向生态树
对应官方示例 vertical.js 与测试用例 layout-dendrogram-tb.ts。纵向布局时锚点应改放上下两侧,边改为cubic-vertical;为避免叶子节点标签过长挤压布局,可对叶子标签做 90° 旋转:
const graph = new Graph({ container: 'container', autoFit: 'view', data: treeToGraphData(data), node: { style: (d) => { const isLeafNode = !d.children?.length; const style = { labelText: d.id, labelPlacement: 'right', labelOffsetX: 2, labelBackground: true, ports: [{ placement: 'top' }, { placement: 'bottom' }], }; if (isLeafNode) { Object.assign(style, { labelTransform: [['rotate', 90], ['translate', 18]], labelBaseline: 'center', labelTextAlign: 'left', }); } return style; }, }, edge: { type: 'cubic-vertical', }, layout: { type: 'dendrogram', direction: 'TB', // H / V / LR / RL / TB / BT nodeSep: 50, rankSep: 120, preLayout: true, }, behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element', 'collapse-expand'], }); graph.render();示例三:radial 辐射状生态树
对应官方示例 radial.js 与测试用例 layout-dendrogram-radial.ts。辐射模式无需指定direction即可工作(默认LR),只需开启radial:
const graph = new Graph({ container: 'container', autoFit: 'view', data: treeToGraphData(data), node: { style: { labelText: (d) => d.id, labelBackground: true, }, }, layout: { type: 'dendrogram', radial: true, // 以根节点为中心辐射状分布 nodeSep: 40, rankSep: 140, }, behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'], }); graph.render();单元测试验证
仓库在 packages/g6/tests/unit/layouts/dendrogram.spec.ts 中为生态树布局编写了快照测试:basic用例渲染 LR 方向布局、tb用例渲染 TB 方向布局,均通过toMatchSnapshot与渲染快照比对,保证了文档所描述的方向与形态行为的正确性。
搭配建议与最佳实践
- 边类型与方向匹配:横向方向(
LR/RL)搭配cubic-horizontal边,纵向方向(TB/BT)搭配cubic-vertical边,视觉上折线最平滑;这是官方示例与测试用例的统一做法。 - 锚点(ports)跟随方向:节点 style 中通过
ports声明边的连接点,横向布局配置left/right,纵向布局配置top/bottom,保证边从正确方向伸出。 - 标签策略:
LR布局下将非叶子节点标签放左侧、叶子放右侧可避免与子树的边重叠;纵向布局中叶子标签旋转 90° 可显著节省纵向空间。 - 开启
preLayout: true:让布局在元素初始化前完成,首帧即稳定,官方示例均如此配置;大规模树可进一步考虑enableWorker: true将计算移入 Web Worker。 - 配合折叠展开行为:
collapse-expand行为(见 packages/g6/src/behaviors/collapse-expand.ts)在生态树中可直接用于展开/收起子树,适合交互式探索大层级树。 - 注意节点尺寸约束:生态树"节点按 1px 处理"的机制意味着它不感知节点大小差异。若你的节点尺寸差异大且需要据此排布,应改用其他布局或配合尺寸映射变换。
生态树布局是 G6 布局体系中形态最规整、最易读的树形方案之一。理解direction与radial两个核心开关,再辅以边类型、标签与锚点的方向化配置,即可快速构建出专业级的分类树、谱系树与径向树可视化应用。
- 数据可视化
- 前端
- 图表库
【免费下载链接】G6
♾ A Graph Visualization Framework in JavaScript.
相关推荐
G6 生态树(Dendrogram)布局实战指南:方向、间距与径向模式配置详解
G6 生态树(Dendrogram)布局实战指南:方向、间距与径向模式配置详解 导读 本文围绕 G6(AntV 图可视化框架)内置的 dendrogram 生态
数据可视化前端图表库G6 生态树 Dendrogram 布局:配置详解与源码级实践指南
G6 生态树 Dendrogram 布局:配置详解与源码级实践指南 导读 生态树(Dendrogram)是 AntV G6 中用于层次聚类数据可视化的树形布局,
数据可视化前端图表库G6 生态树布局(Dendrogram)实战指南:配置详解与源码级原理
G6 生态树布局(Dendrogram)实战指南:配置详解与源码级原理 生态树(Dendrogram)是 G6 内置的树图布局之一,专为层次聚类数据的可视化设计
数据可视化前端图表库
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考