的添加、配置、箭头与自定义改造全指南)
X6 教程边Edge的添加、配置、箭头与自定义改造全指南【免费下载链接】X6 JavaScript diagramming library that uses SVG and HTML for rendering.项目地址: https://gitcode.com/GitHub_Trending/x6/X6导读在 X6 中边Edge是连接两个节点、表达实体间关系的核心模型广泛应用于流程图、ER 图、DAG、组织结构图等图编辑场景。本教程基于官方基础教程 edge.zh.md 展开系统讲解边的添加方式、source/target 终端的四种写法、vertices 路径点、router 路由与 connector 连接器的分工协作、labels 标签与 defaultLabel 默认标签、内置与自定义箭头Marker以及通过prop/attr两个 API 在渲染后动态修改边。读完本文你将掌握 X6 中边的完整配置体系并能结合源码理解路由与连接器各自的职责边界。添加边从零创建一条连接节点和边拥有共同的基类 Cell边除了继承自Cell的属性外还支持以下专属选项属性名类型默认值描述sourceTerminalData-源节点或起始点。targetTerminalData-目标节点或目标点。verticesPoint.PointLike[]-路径点。routerRouterData-路由。connectorConnectorData-连接器。labelsLabel[]-标签。defaultLabelLabel内置默认标签默认标签见 labels 和 defaultLabel最简单的添加方式是在创建Graph后调用graph.addEdge传入shape: edge以及 source/targetgraph.addEdge({ shape: edge, source: node1, target: node2, })从源码看graph.addEdge最终会经由 Edge.create 从边注册表Edge.registry按shape名称解析构造函数并实例化随后通过store持久化配置。shape: edge对应 X6 内置的默认边Shape.Edge其默认markup与attrs定义在 src/shape/edge.ts 中包含line可见的 path 元素与wrap透明的、用于响应交互的 path 元素两个选择器。配置边逐项拆解核心选项source / target指定边的两端source 和 target 即边的源与目标“终端Terminal”支持四种灵活写法graph.addEdge({ source: rect1, // 直接传入节点实例 target: rect2, }) graph.addEdge({ source: rect1, // 传入节点 ID target: rect2, }) graph.addEdge({ source: { cell: rect1, port: out-port-1 }, // 节点实例 连接桩 ID target: { cell: rect2, port: in-port-1 }, // 节点 ID 连接桩 ID }) graph.addEdge({ source: rect1, // 源节点 ID target: { x: 100, y: 120 }, // 直接指定坐标点 })上述四种写法的归一化逻辑可以在 Edge.preprocess 中看到当传入Cell实例时取cell.id存入{ cell: id }当传入Point或数组[x, y]时转换为{ x, y }点对象当传入对象时保留cell/port结构。此外X6 还支持sourceCell/sourcePort/sourcePoint与targetCell/targetPort/targetPoint这类扁平化写法它们会在preprocess中被合并为标准的 terminal 数据结构。连接桩Port的引入让边可以精确地“贴”在节点的某个出/入口上这也是 ER 图、流程图中端口模型的基础。连接桩的配置方式可参考 port 相关文档。vertices路径点vertices路径点描述边从起始点出发、依次经过这些点、最终到达终止点的中间轨迹graph.addEdge({ source: rect1, target: rect2, vertices: [ { x: 100, y: 200 }, { x: 300, y: 120 }, ], })边模型的底层将vertices与 source/target 点共同构造成折线Polyline相关实现见 Edge.getPolyline它依次拼接“源点 → 各路径点 → 目标点”并基于该折线计算包围盒getBBox与中点连接点getConnectionPoint。在渲染层路径点还会经历路由与连接器的二次加工见下文。源码中还提供了setVertices、insertVertex、appendVertex、getVertexAt、removeVertexAt等方法src/model/edge.ts用于动态增删路径点。对应可交互示例位于 site/src/tutorial/basic/edge/vertices/index.tsx。router路由路由router会对vertices做进一步处理在必要时额外插入点并返回处理后的点序列。以最常用的orth正交路由为例经过它处理后边的每一段连线都变成水平或垂直方向呈现出“横平竖直”的折线效果非常适合流程图与 ER 图。graph.addEdge({ source: rect1, target: rect2, vertices: [ { x: 100, y: 200 }, { x: 300, y: 120 }, ], // 如果没有 args 参数可以简写为 router: orth router: { name: orth, args: {}, }, })X6 默认提供以下 6 种路由normalorthoneSidemanhattanmetroer路由的注册机制在 src/registry/router/index.ts 中定义所有内置路由normal、oneside、orth、metro、manhattan、er、loop统一从 main.ts 导出并注册到routerRegistry。以 orth.ts 为例它先取源/目标的包围盒与锚点将锚点并入包围盒再按“方位角bearingN/S/E/W”逐段推导正交折线遇到源/目标节点互相包含insideNode等特殊情况时还会走专门的处理分支最终保证每一段线段都严格水平或垂直。manhattan路由则是orth的增强版在 manhattan/index.ts 中通过合并defaults配置后调用核心router实现能够绕开障碍物节点规划路径适合需要自动避障的场景。另外我们也可以注册自定义路由详情请参考 自定义路由。对应可交互示例见 site/src/tutorial/basic/edge/router/index.tsx。connector连接器连接器connector负责把路由router返回的点序列加工成真正用于渲染的 SVGpathData即path d...中的路径数据参见 MDN 对 pathData 的说明。例如rounded连接器会把折线的拐角处理成圆弧倒角让边更柔和graph.addEdge({ source: rect1, target: rect2, vertices: [ { x: 100, y: 200 }, { x: 300, y: 120 }, ], router: orth, // 如果没有 args 参数可以简写为 connector: rounded connector: { name: rounded, args: {}, }, })X6 默认提供以下 4 种连接器normalroundedsmoothjumpover连接器与路由的职责可以这样理解路由解决“走哪条路”点的序列连接器解决“怎么画”把这些点连成怎样的 path。这一点在源码中得到清晰印证——路由定义签名是(vertices, options, edgeView) PointLike[]src/registry/router/index.ts即输入点、输出点而连接器定义签名是(sourcePoint, targetPoint, routePoints, options, edgeView) Path | stringsrc/registry/connector/index.ts即输入起止点与路由点输出 SVG Path。以 rounded.ts 为例它从options.radius默认 10计算每个拐角处的圆弧起点/终点与控制点拼接M、L、C路径段最终返回序列化后的路径字符串。另外我们也可以注册自定义连接器详情请参考 自定义连接器。对应可交互示例见 site/src/tutorial/basic/edge/connector/index.tsx。labels标签labels用于设置标签的文本、位置、样式等通过数组形式支持多标签。labels中指定的每一项都会与defaultLabel进行 lodash merge 合并后使用const edge graph.addEdge({ source: rect1, target: rect2, labels: [ { attrs: { label: { text: edge, }, }, }, ], }) // 或通过 labels 设置多个标签只设置文本时可简化为此写法 const edge graph.addEdge({ source: rect1, target: rect2, labels: [edge], }) // 或通过 label 设置单个标签 const edge graph.addEdge({ source: rect1, target: rect2, label: edge, })从源码看parseStringLabel会把字符串标签转换为{ attrs: { label: { text } } }结构src/model/edge.tsgetDefaultLabel返回当前边构造器或实例store中的默认标签副本src/model/edge.ts。除了文本Label 还可以承载rect、path等复杂图形形成带背景框、图标的富标签详细能力见 labels API 文档。对应可交互示例见 site/src/tutorial/basic/edge/labels/index.tsx。defaultLabel默认标签defaultLabel是默认标签用于简化标签配置labels中的每一项都会与它 merge。内置Shape.Edge的默认标签定义在 Edge.defaultLabelmarkup 由body圆角 rect白色背景与labeltext 元素黑色 14px 居中文字组成position.distance默认为 0.5即默认显示在边的中点。使用箭头sourceMarker 与 targetMarkerX6 定义了sourceMarker和targetMarker两个特殊属性为边定制起始箭头与终止箭头。对于Shape.Edge可以通过line选择器指定graph.addEdge({ shape: edge, source: [100, 100], target: [500, 500], attrs: { line: { sourceMarker: block, // 实心箭头 targetMarker: { name: ellipse, // 椭圆 rx: 10, // 椭圆箭头的 x 半径 ry: 6, // 椭圆箭头的 y 半径 }, }, }, })内置箭头X6 提供了以下 9 种内置箭头使用时只需指定箭头名和可选参数blockclassicdiamondcrossasyncpathcirclecirclePlusellipse这些内置箭头的实现统一注册在markerRegistry中src/registry/marker/index.ts工厂函数签名(options) MarkerResult返回带tagName与属性集的 SVG 标记结构各预设从 main.ts 导出classic、diamond、path、cross、async、circle、ellipse 等。对应可交互示例见 site/src/tutorial/basic/edge/native-marker/index.tsx其中一次性展示了 block、classic、diamond、circle、circlePlus、ellipse、cross、async 共 8 种箭头在边上的实际效果。提示X6 中边默认自带classic箭头如果想去掉可以将targetMarker设置为null。默认值可以在 src/shape/edge.ts 中看到line的 attrs 里targetMarker: classic。自定义箭头我们也可以通过tagName指定的 SVG 元素来渲染箭头例如使用path元素。自定义箭头默认继承边的填充色fill与边框色stroke也可以显式覆盖graph.addEdge({ shape: edge, source: [100, 100], target: [500, 500], attrs: { line: { sourceMarker: { tagName: path, d: M 20 -10 0 0 20 10 Z, }, targetMarker: { tagName: path, fill: yellow, // 使用自定义填充色 stroke: green, // 使用自定义边框色 strokeWidth: 2, d: M 20 -10 0 0 20 10 Z, }, }, }, })提示起始箭头与终止箭头使用了相同的d属性因为 X6 会自动计算箭头方向。简单来说定义箭头时只需要定义一个“向左指向坐标原点”的箭头即可X6 会依据边的走向自动旋转对齐。相关归一化逻辑位于 src/registry/marker/util.ts 的normalize函数中。更多箭头的案例与定制技巧请参考 marker API 文档。对应可交互示例见 site/src/tutorial/basic/edge/custom-marker/index.tsx。定制边markup 与 attrs和节点一样我们可以通过markup和attrs定制边的形状与样式也可以注册自定义边以达到复用效果。X6 默认边Shape.Edge中定义了两个选择器line代表可见的 path 元素描边样式wrap代表透明的 path 元素用于响应交互扩大点击热区。对应的默认定义在 src/shape/edge.tswrap使用stroke: transparent、strokeWidth: 10、cursor: pointerline使用stroke: #333、strokeWidth: 2并开启pointerEvents: none避免遮挡 wrap 的交互二者通过groupSelector: lines分组组级 attrs 统一设置connection: true与strokeLinejoin: round其中connection表示该 path 由边的连接数据自动生成。在创建边时可以像下面这样定义样式完整可运行示例见 site/src/tutorial/basic/edge/registry/index.tsxgraph.addEdge({ source: [100, 100], target: [400, 100], attrs: { line: { stroke: #ff0000, // 自定义边的颜色 strokeWidth: 4, strokeDasharray: 5 5, // 虚线样式 targetMarker: block, }, }, })边同样支持Edge.define注册自定义边类型并复用相关机制见 Edge.define 与 Edge.registry注册时默认继承自edge可指定inherit、constructorName、overwrite等配置。修改边prop 与 attr在渲染完成之后我们还可以通过 API 修改边的所有属性常用到下面两个方法edge.prop(path, value)详细使用见 节点和边的属性propertiesedge.attr(path, value)详细使用见 元素属性attrs。下面看一个Shape.Edge默认prop的完整结构const edge graph.addEdge({ source: [200, 140], target: [500, 140], label: edge, }) console.log(edge.prop()) // 输出结果 { shape: edge, attrs: { lines: { connection: true, strokeLinejoin: round }, wrap: { strokeWidth: 10 }, line: { stroke: #333, strokeWidth: 2, targetMarker: classic } }, id: 9d5e4f54-1ed3-429e-8d8c-a1526cff2cd8, source: { x: 200, y: 140 }, target: { x: 500, y: 140 }, labels: [{ attrs: { label: { text: edge } } }], zIndex: 1 }可以看到prop返回的是经过处理后的一份新配置其值可以通过方法更新更新后边会立即刷新到最新状态。为了更快捷地修改边的attrsX6 提供了attr方法edge.prop(target, { x: 300, y: 300 }) // 修改终点 edge.attr(line/stroke, #ccc) // 修改边颜色等价于 edge.prop(attrs/line/stroke, #ccc)对应的可交互示例见 site/src/tutorial/basic/edge/prop/index.tsx点击 “prop” 按钮会通过edge.prop(vertices, [[x, y]])随机更新路径点点击 “attr” 按钮会通过edge.attr(line/stroke, color)随机更换边颜色直观展示两条修改路径的实时刷新效果。小结本文围绕 X6 的边模型完成了从“创建”到“改造”的完整闭环graph.addEdge创建边并设置source/target四种终端写法vertices定义中间轨迹router如orth、manhattan负责在点序列上规划正交/避障路径connector如rounded负责将点序列渲染为 SVG pathlabels与defaultLabel负责标签文本与样式sourceMarker/targetMarker提供 9 种内置箭头并支持任意 SVG 元素自定义箭头最后通过prop/attr在运行时动态修改边的任意属性。这些能力共同构成了 X6 中“连线”这一核心交互的基础更深入的 API 细节可继续查阅 edge 模型 API、router 注册表、connector 注册表 与 marker API。【免费下载链接】X6 JavaScript diagramming library that uses SVG and HTML for rendering.项目地址: https://gitcode.com/GitHub_Trending/x6/X6创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考