尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

G6 Dagre 层次化布局实战指南:配置项全解析与源码原理

G6 Dagre 层次化布局实战指南:配置项全解析与源码原理 数据可视化前端图表库【免费下载链接】G6♾ A Graph Visualization Framework in JavaScript.项目地址https://gitcode.com/gh_mirrors/g6/G6点击查看免费下载Dagre 是 G6 内置的层次化布局方案专为有向无环图DAG设计能自动计算节点层级、方向与间距同时支持水平LR/RL与垂直TB/BT两种排布方向。本文以 G6 官方文档《Dagre 布局》为核心结合仓库内布局适配器源码、内置扩展注册表与官方测试用例完整讲解type: dagre的每一项配置、三种分层算法的取舍以及 G6 如何把布局结果转换为可渲染的节点坐标与边控制点。读完本文你将能够为流程图、依赖关系图、任务调度图配置出方向正确、层次清晰、间距可控的 Dagre 布局并理解dagre与antv-dagre两种布局类型的差异。Dagre 布局概述Dagre 是一种层次化布局hierarchical layout它的核心工作方式是把图中的节点按照拓扑关系划分到不同的层rank中再在同一层内排布节点、跨层连接边从而自动处理节点之间的方向和间距。它适用于**有向无环图DAG**场景这也是其名称 dag reDirect Acyclic Graph renderer的由来。在 G6 中dagre布局并非由 G6 自身实现而是内置注册的DagreLayout它来自布局引擎库antv/layout。从 内置扩展注册表 可以看到layout: { antv-dagre: AntVDagreLayout, ... dagre: DagreLayout, ... }同时布局类型导出 也确认了DagreLayout与AntVDagreLayout均直接来自antv/layout。因此dagre布局的完整算法能力与dagre.js保持一致dagre.js是 G6 之外独立维护的开源布局库本文不展开外部链接仅说明其能力边界而 G6 通过适配层完成数据格式的转换与结果回填。快速上手最小配置在 G6 中启用 Dagre 布局只需在Graph配置的layout字段中指定type: dagre其余参数均可省略const graph new Graph({ layout: { type: dagre, rankdir: TB, // 布局方向默认 TB从上到下 align: UL, // 节点对齐方式默认 UL左上对齐 nodesep: 50, // 节点间距px默认 50 ranksep: 50, // 层间距px }, });仓库中的官方示例 站点 Dagre 示例 给出了一个完整的可运行版本数据包含 6 个矩形节点和 5 条有向边布局只配置了type: dagre节点样式通过回调(d) [d.data.width, d.data.height]从数据中读取尺寸边使用polyline类型并配合orth正交路由const graph new Graph({ autoFit: center, data, node: { type: rect, style: { size: (d) [d.data.width, d.data.height], radius: 10, iconText: (d) d.data.label, iconFontSize: 14, }, }, edge: { type: polyline, style: { router: { type: orth }, }, }, layout: { type: dagre, }, }); graph.render();对应的测试用例位于 dagre.spec.ts其中it(dagre.js, ...)直接渲染该数据并做 SVG 快照断言可用于验证默认配置下的真实布局效果。配置项全解析以下配置项表完整覆盖 G6 文档中dagre布局的全部配置标注了类型、默认值与必选性。除type外所有配置均为可选。属性描述类型默认值必选type布局类型dagre-✓rankdir布局方向可选值TB|BT|LR|RLTBalign节点对齐方式可选值UL|UR|DL|DRULnodesep节点间距px。rankdir 为TB/BT时是节点水平间距rankdir 为LR/RL时是节点竖直方向间距number50ranksep层间距px。rankdir 为TB/BT时是竖直方向相邻层间距rankdir 为LR/RL时是水平方向相邻层间距number100见下文说明ranker为每个节点分配等级的算法network-simplex|tight-tree|longest-pathnetwork-simplexdirected是否按有向图处理booleantruecompound是否支持嵌套结构booleantruemultigraph是否允许多重边booleantruenodeSizeG6 自定义属性统一指定或为每个节点指定节点大小返回单个 number 表示宽高相同返回数组形如[width, height]number | number[] | () (number | number[])[0, 0]edgeMinLen边跨越的最小层数number | (edge) number1edgeWeight边权重用于影响优化优先级number | (edge) numberedgeLabelSize边标签尺寸用于预留布局空间number[] | (edge) number[]edgeLabelPos边标签位置string | (edge) stringedgeLabelOffset标签与边的偏移number | (edge) number关于ranksep默认值的说明原文档的配置项表格中标注为100而文档后文ranksep小节中标注为50两处描述存在不一致。建议在实际使用中显式配置该参数避免依赖默认值产生歧义。补充dagre布局不需要单独配置controlPointsG6 会把布局输出的折线点自动转换为边的style.controlPoints。这一行为在布局适配层有明确实现见下文源码原理一节。rankdir布局方向可选值TB|BT|LR|RL默认TB。TB从上到下Top to Bottom是最常用的流程方向源节点在上、目标节点在下BT从下到上Bottom to Top适合自底向上表达的依赖关系LR从左到右Left to Right适合横向空间宽、纵向空间窄的画布或阅读习惯从左往右的展示RL从右到左Right to Left。rankdir不仅决定视觉方向还影响nodesep与ranksep两个间距参数的语义详见下文。仓库示例 antv-dagre.js 中通过 GUI 面板动态切换rankdir/align并调用graph.setLayout(...)与graph.layout()重新布局是快速观察不同方向效果的可运行参考。align节点对齐方式可选值UL|UR|DL|DR默认UL。UL左上对齐Up LeftUR右上对齐Up RightDL左下对齐Down LeftDR右下对齐Down Right。align控制同一层rank内节点的对齐基准影响层内节点在垂直方向上的相对位置。例如在LR方向下UL表示节点靠上对齐、DL表示节点靠下对齐适合让边更直、让图更紧凑的微调。nodesep节点间距类型 number默认 50单位 px。nodesep控制同一层内相邻节点的间距rankdir 为TB或BT时层是水平方向排布的因此nodesep表示节点之间的水平间距rankdir 为LR或RL时层是垂直方向排布的因此nodesep表示节点之间的竖直方向间距。节点过密导致标签重叠时可增大nodesep。ranksep层间距类型 number单位 px默认值标注存在不一致见上文说明。ranksep控制相邻两层之间的间距rankdir 为TB或BT时表示竖直方向相邻层间距rankdir 为LR或RL时表示水平方向相邻层间距。如果图中跨层边长边较多且需要更清晰的层次感可以适当调大ranksep反之需要压缩整体图幅时可以调小该值。示例 antv-dagre.js 中三组预设配置分别使用了ranksep: 70与ranksep: 40可见不同方向组合下的推荐取值区间。ranker节点分层算法可选值network-simplex|tight-tree|longest-path默认network-simplex。ranker决定如何为每个节点分配层级rank是 Dagre 布局质量的核心开关。三种算法各有取舍longest-path最长路径算法使用 DFS 深度优先搜索递归查找每个节点的最长路径来确定其层级。优点是计算简单、速度快缺点是会产生较多长边一条边跨越多层视觉上边显得绕路。tight-tree紧凑树算法一种优化算法目标是减少长边的数量。它先用longest-path计算初始层级再调整松弛边slack edge的长度从而构建一棵可行树feasible tree。network-simplex网络单形法参考经典论文《A Technique for Drawing Directed Graphs》Graphviz 文档的思想核心是迭代修改节点层级、缩小松弛边在布局质量边更直、层次更紧凑上通常最优也是默认算法代价是计算开销相对更高。选型建议节点数不多几百以内且对布局质量敏感时保持默认network-simplex节点规模大、对布局速度敏感、能接受长边时可切换longest-path。注意本文不引用外部站点深入算法细节可阅读 Dagre 官方 wiki 与上述论文可在仓库外自行检索。directed / compound / multigraph图结构开关directed默认true是否按有向图处理。true时边有方向语义分层结果受边的方向约束false时按无向图处理适合不需要表达方向、只关心连通结构的场景。compound默认true是否支持嵌套结构即 G6 的 combo 子图。true时布局会识别 combo 层级将子节点布局在组合框内。multigraph默认true是否允许多重边两个节点之间存在多条边。true时多重边不会互相覆盖布局会为它们分配不同的路由。需要注意在 G6 中若要布局 combo 嵌套结构官方推荐使用antv-dagre布局配合sortByCombodagre布局对 combo 的原生支持有限。详见下文与 antv-dagre 的对比一节。nodeSize节点尺寸G6 自定义属性类型 number | number[] | () (number | number[])默认[0, 0]。nodeSize是 G6 为dagre布局扩展的自定义属性用于统一指定或按节点分别指定参与布局的节点尺寸让层级计算与间距计算考虑节点的实际大小避免节点尺寸不同导致的边交叉或间距不均返回单个number表示节点的宽度与高度相同返回数组形如[width, height]返回函数接收节点数据d按节点动态返回尺寸。layout: { type: dagre, nodeSize: (d) { // d 是一个节点 if (d.id testId) return 20; // 该节点宽高均为 20 return [10, 20]; // 其他节点宽度 10、高度 20 }, }如果不配置nodeSize默认[0, 0]dagre.js 计算时会把所有节点视为无尺寸的点最终布局可能忽略节点实际大小。结合节点样式回调使用效果最佳例如官方示例中节点样式size: (d) [d.data.width, d.data.height]与布局层的nodeSize协同即可做到布局按真实尺寸排布、渲染也按真实尺寸绘制。边相关的进阶配置以下配置项用于精细控制跨层边的排布质量均可传常量值或按边动态返回的函数edgeMinLen默认1边跨越的最小层数。值越大边的起点-终点越倾向于分居更远的层可用于拉开边两端节点的层次距离。edgeWeight边权重用于影响优化优先级。权重越大的边在network-simplex等优化算法中越被优先处理使重要边更直、更短。edgeLabelSize边标签尺寸形如[width, height]用于在布局阶段为边标签预留空间防止标签遮挡节点或与其他边重叠。edgeLabelPos边标签位置字符串控制标签相对边的放置方位。edgeLabelOffset标签与边的偏移量用于微调标签与边的垂直距离。需要说明的是G6 文档中上述边标签类配置沿袭自dagre.js的通用配置实际使用时建议同时为边元素配置对应的标签样式如labelText、labelBackground才能看到预留空间的效果。controlPoints边控制点类型 boolean默认 false。controlPoints配置项表示是否保留边的控制点。该配置主要作用于antv-dagre布局开启后布局会输出折线路径的控制点供polyline、cubic等边类型渲染弯折效果。而dagreantv/layout的 DagreLayout则无需配置该参数——G6 会自动把布局返回的折线点写入边的style.controlPoints详见下文源码说明。源码原理G6 如何适配并应用 dagre 布局布局适配器layoutAdapterG6 通过适配器模式把antv/layout中的DagreLayout包装为 G6 的BaseLayout子类核心实现在 utils/layout.ts 的layoutAdapter函数中主要做了三件事数据模型转换graphData2LayoutModel把 G6 的GraphDatanodes/edges/combos合并转换为antv/layout需要的模型其中 combo 会被当作普通节点一并送入布局utils/layout.ts选项转换transformOptions为布局补充默认的node与edge映射函数把节点的style.x/style.y/style.z、combo 归属等信息映射为布局可读的字段utils/layout.ts结果回填getLayoutResult遍历布局结果把每个节点的x/y/z以及可选的size写回 G6 的节点style把每条边的points写回边的style.controlPointsutils/layout.ts。controlPoints 的自动转换布局结果转 G6 数据的关键在layoutMapping2GraphDatautils/layout.ts其中有一段针对两种 Dagre 实现的注释非常关键/** * antv-dagre 返回 controlPointsdagre 返回 points * antv-dagre returns controlPoints, dagre returns points */ ...(controlPoints?.length ? { controlPoints: controlPoints.map(parsePoint) } : {}),也就是说antv-dagre布局在controlPoints: true时直接返回controlPoints字段而dagre布局返回的是points折线路径点G6 会取points去掉首尾端点后的中间部分作为controlPoints并统一parsePoint为坐标对象后写入边的style.controlPoints。这正是文档中dagre不需要单独配置controlPoints的源码级解释。内置注册与运行时调度注册dagre与antv-dagre均在内置扩展注册表 build-in.ts 中注册Graph实例化时通过type字符串查表获取布局构造器因此无需手动register。类型约束在 layouts/types.ts 中DagreLayoutOptions被约束为type: dagre的联合类型所有布局还共享BaseLayoutOptions的通用能力layouts/types.ts包括nodeFilter/comboFilter筛选参与布局的节点/combopreLayout是否在初始化元素前先计算布局width/height布局区域尺寸默认取画布尺寸animation迭代布局是否启用过渡动画enableWorker是否在 WebWorker 中执行布局iterations迭代类布局的迭代次数。 这些通用配置同样适用于dagre布局。自定义 Dagre 布局的扩展范式仓库测试用例 layout-custom-dagre.ts 展示了如何基于layoutAdapter包装出带自定义选项的 Dagre 布局自定义类继承BaseLayout在execute中通过layoutAdapter(DagreLayout, this.context)生成适配实例并调用其execute再通过register(ExtensionCategory.LAYOUT, custom-layout, CustomLayout)注册即可在Graph中直接使用type: custom-layout。这为在 dagre 基础上增加私有参数、二次加工坐标等定制需求提供了标准入口。与 antv-dagre 布局的对比G6 同时内置了dagre与antv-dagre两种 Dagre 系布局二者在注册表与类型定义中并列存在build-in.ts。结合官方示例与源码注释可以整理出以下差异维度dagreantv-dagre实现来源antv/layout的DagreLayout对齐 dagre.jsantv/layout的AntVDagreLayoutantv 增强版controlPoints无需配置自动由points转换需要配置controlPoints: truecombo 嵌套默认compound: true支持嵌套但布局结果不按 combo 分组支持sortByCombo: true按 combo 分组排布官方示例dagre.jsantv-dagre.js、antv-dagre-combo.js当业务数据包含combo组合/分组结构时官方推荐使用antv-dagre并开启sortByCombo。参考 antv-dagre-combo.js 与测试用例 layout-antv-dagre-flow-combo.ts 的完整配置const graph new Graph({ autoFit: center, data, node: { type: rect, style: { size: [60, 30], radius: 8, labelText: (d) d.id } }, edge: { type: cubic-vertical, style: { endArrow: true } }, combo: { type: rect }, layout: { type: antv-dagre, ranksep: 50, nodesep: 5, sortByCombo: true, // 按 combo 分组参与布局 }, behaviors: [drag-element, drag-canvas, zoom-canvas], });此外utils/layout.ts 的isComboLayout判定中antv-dagre在sortByCombo为真时会被识别为 combo 布局走 combo 布局的渲染管线——这是dagre 布局默认不处理 combo、antv-dagre 才能很好地处理 combo的源码依据。布局适用场景Dagre 布局在以下三类场景中最为典型对应 G6 文档中的官方说明流程图节点之间的方向和间距自动处理TB方向天然符合自上而下、逐步推进的流程阅读习惯依赖关系图展示软件包或模块之间的依赖关系BT/LR方向可表达基础依赖在下/在左的层次任务调度图展示任务之间的依赖关系和执行顺序配合edgeMinLen、edgeWeight可突出关键链路上的任务。在这些场景中通常建议dagre布局 polyline边 orth正交路由以获得规整的横平竖直连线效果见 dagre.js 的组合方式若存在 combo 分组则切换为antv-dagresortByCombo。在仓库中继续深入官方示例可直接运行调试Dagre.js 布局示例Antv-dagre 流程图示例含 GUI 切方向Antv-dagre 带 Combo 流程图示例测试用例快照断言可验证布局输出dagre 布局单元测试自定义 dagre 布局测试dagre 布局 demo 数据源码布局适配与注册布局适配器 layoutAdapter / layoutMapping2GraphData内置布局注册表布局类型定义含通用 BaseLayoutOptions布局导出DagreLayout / AntVDagreLayoutDagre 布局在 G6 中开箱即用理解rankdir/align/ranker/nodeSize这几个核心旋钮配合controlPoints自动转换机制与antv-dagre的 combo 增强即可覆盖绝大多数 DAG 场景的层次化展示需求。赞分享数据可视化前端图表库【免费下载链接】G6♾ A Graph Visualization Framework in JavaScript.项目地址https://gitcode.com/gh_mirrors/g6/G6点击查看免费下载相关推荐G6 AntvDagre 层次布局完整指南从 dagre 增强到流程图实战配置G6 AntvDagre 层次布局完整指南从 dagre 增强到流程图实战配置 导读 本文围绕 G6 内置的 antv dagre 布局展开它是对经典 da数据可视化前端图表库深入解析 G6 蛇形布局Snake Layout原理、配置与实战深入解析 G6 蛇形布局Snake Layout原理、配置与实战 蛇形布局Snake Layout是 G6 中一种面向 长链结构 的专用布局算法它将数据可视化前端图表库G6 鱼骨图布局Fishbone Layout实战指南从配置参数到源码原理G6 鱼骨图布局Fishbone Layout实战指南从配置参数到源码原理 鱼骨图又称 Ishikawa 图、因果图是质量管理与因果分析中最经典的层次数据可视化前端图表库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表