Loading...
节点小工具是一些渲染在节点上的一些小组件,这些小工具通常都附带一些交互功能,如删除按钮,点击按钮时删除对应的节点。我们可以根据下面的一些场景来添加或删除小工具。
// 创建节点时添加小工具graph.addNode({...,tools: [{name: 'button-remove',args: { x: 10, y: 10 },},],})// 创建节点后添加小工具node.addTools([{name: 'button-remove',args: { x: 10, y: 10 },},])// 删除工具graph.on("node:mouseleave", ({ node }) => {if (node.hasTool("button-remove")) {node.removeTool("button-remove");}});
在 X6 中默认提供了以下几个用于节点的小工具:
在指定位置处渲染一个按钮,支持自定义按钮的点击交互。配置如下:
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
x | number | string | 0 | 相对于节点的左上角 X 轴的坐标,小数和百分比表示相对位置。 |
y | number | string | 0 | 相对于节点的左上角 Y 轴的坐标,小数和百分比表示相对位置。 |
offset | number | { x: number, y: number } | 0 | 在 x 和 y 基础上的偏移量。 |
rotate | boolean | - | 是否跟随节点旋转。 |
useCellGeometry | boolean | true | 是否使用几何计算的方式来计算元素包围盒,开启后会有性能上的提升,如果出现计算准度问题,请将它设置为 false 。 |
markup | Markup.JSONMarkup | - | 渲染按钮的 Markup 定义。 |
onClick | (args: {e: Dom.MouseDownEvent, cell: Cell, view: CellView }) => void | - | 点击按钮的回调函数。 |
// 鼠标 Hover 时添加按钮graph.on('node:mouseenter', ({ node }) => {node.addTools({name: 'button',args: {markup: ...,x: 0,y: 0,offset: { x: 18, y: 18 },onClick({ view }) { ... },},})})// 鼠标移开时删除按钮graph.on('node:mouseleave', ({ node }) => {node.removeTools() // 删除所有的工具})
在指定的位置处,渲染一个删除按钮,点击时删除对应的节点。它是上面 button
工具的一个特例,所以支持 button
的所有配置。
const source = graph.addNode({...,// 添加一个始终显示的删除按钮tools: [{name: 'button-remove',args: {x: '100%',y: 0,offset: { x: -10, y: 10 },},},],})
根据节点的包围盒渲染一个包围节点的矩形。注意,该工具仅仅渲染一个矩形,不带任何交互。配置如下:
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
tagName | string | rect | 使用何种图形渲染。 |
rotate | boolean | - | 图形是否跟随节点旋转。 |
padding | SideOptions | 10 | 边距。 |
attrs | KeyValue | object | 图形属性。 |
useCellGeometry | boolean | true | 是否使用几何计算的方式来计算元素包围盒,开启后会有性能上的提升,如果出现计算准度问题,请将它设置为 false 。 |
其中 attrs
的默认值(默认样式)为:
{fill: 'none',stroke: '#333','stroke-width': 0.5,'stroke-dasharray': '5, 5','pointer-events': 'none',}
SideOptions
的类型定义如下:
type SideOptions =| number| {vertical?: numberhorizontal?: numberleft?: numbertop?: numberright?: numberbottom?: number}
工具使用方式如下:
const source = graph.addNode({...,tools: [{name: 'boundary',args: {padding: 5,attrs: {fill: '#7c68fc',stroke: '#333','stroke-width': 1,'fill-opacity': 0.2,},},},],})
提供节点上文本编辑功能。配置如下:
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
x | number | string | - | 相对于节点的左上角 X 轴的坐标,小数和百分比表示相对位置 |
y | number | string | - | 相对于节点的左上角 Y 轴的坐标,小数和百分比表示相对位置 |
attrs/fontSize | string | 14 | 编辑文本字体大小 |
attrs/color | string | #000 | 编辑文本字体颜色 |
attrs/fontFamily | string | Arial, helvetica, sans-serif | 编辑文本的字体 |
attrs/backgroundColor | string | #fff | 编辑区域的背景色 |
getText | string | (this: CellView, args: {cell: Cell}) => string | - | 获取原文本方法,在自定义 markup 场景需要自定义 getText 方法 |
setText | string | (this: CellView, args: {cell: Cell, value: string}) => void | - | 设置新文本,在自定义 markup 场景需要自定义 setText 方法 |
需要注意的是,2.8.0 版本后不需要在双击事件中去动态添加工具,也就不需要传入事件参数。
// 2.8.0 版本之前使用方式graph.on('node:dblclick', ({ node, e }) => {node.addTools({name: 'node-editor',args: {event: e,},})})// 2.8.0 版本之后使用方式node.addTools({name: 'node-editor',})
还需要注意的是,如果在节点中自定义了 markup
,往往需要自定义 getText
和 setText
方法来正确获取和设置编辑文本,这两个配置都支持函数和字符串两种形式,函数比较好理解,字符串其实就是要获取或者设置的文本的属性路径,一般情况下建议使用字符串形式,这样图数据可以完全序列化(因为函数无法序列化),否则可能会出现渲染画布后文本编辑功能异常,比如:
node.addTools({name: 'node-editor',args: {getText: 'a/b',setText: 'c/d',},})
上面配置表示:
node.attr('a/b')
node.attr('c/d', value)
继承 ToolItem
实现一个工具类,难度较高,要求对 ToolItem 类都有所了解,可以参考上述内置工具的源码,这里不展开叙述。
Graph.registerNodeTool('button', Button)
继承已经注册的工具,在继承基础上修改配置。我们在 ToolItem
基类上提供了一个静态方法 define
来快速实现继承并修改配置。
const MyButton = Button.define<Button.Options>({name: 'my-btn',markup: ...,onClick({ view }) { ... },})Graph.registerNodeTool('my-btn', MyButton, true)
同时,我们为 Graph.registerNodeTool
方法提供了一种快速继承并指定默认选项的实现:
Graph.registerNodeTool('my-btn', {inherit:'button', // 基类名称,使用已经注册的工具名称。markup: ...,onClick: ...,})