本文主要是介绍antv/x6_2.0学习使用(三、内置节点和自定义节点),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
内置节点和自定义节点
一、节点渲染方式
X6 是基于 SVG 的渲染引擎,可以使用不同的 SVG 元素渲染节点和边,非常适合节点内容比较简单的场景。面对复杂的节点, SVG 中有一个特殊的 foreignObject 元素,在该元素中可以内嵌任何 XHTML 元素,可以借助该元素来渲染 HTML、React/Vue/Angular 组件到需要位置,这会给项目开发带来非常大的便利。
- 在选择渲染方式时推荐:
- 如果节点内容比较简单,而且需求比较固定,使用 SVG 节点
- 其他场景,都推荐使用当前项目所使用的框架来渲染节点
注意:
- React/Vue/Angular/HTML 渲染方式也存在一些限制,因为浏览器的兼容性问题,有时会出现一些异常的渲染行为。主要表现形式为节点内容展示不全或者节点内容闪烁。可以通过一些方法规避,比如在节点内部元素的 css 样式中不要使用 position:absolute、position:relative、tranform、opacity。
- 使用 React/Vue/Angular 渲染时,x6 的版本要和 x6-react-shape/x6-vue-shape/x6-angular-shape 的版本匹配,也就是两个包需要用同一个大版本。比如如果 X6 使用的是 2.x 版本,那么 x6-react-shape/x6-vue-shape/x6-angular-shape 也需要使用 2.x 版本。
- x6-react-shape 从 2.0.8 版本以后只支持 react18,如果项目是低于 react18 的版本,就要把 x6-react-shape 的版本锁定在 2.0.8。
- 节点和边都有共同的基类 Cell,除了从 Cell 继承属性外,还支持以下选项。
属性名 | 类型 | 默认值 | 描述 |
---|---|---|---|
x | number | 0 | 节点位置 x 坐标,单位为 px |
y | number | 0 | 节点位置 y 坐标,单位为 px |
width | number | 1 | 节点宽度,单位为 px |
height | number | 1 | 节点高度,单位为 px |
angle | number | 0 | 节点旋转角度 |
graph.addNode({shape: 'rect',x: 100,y: 40,width: 100,height: 40,
})
二、内置节点
使用 shape 指定节点的图形,shape 的默认值为 rect。X6 内置节点与 shape 名称对应关系如下表
shape 名称 | 描述 |
---|---|
rect | 矩形 |
circle | 圆形 |
ellipse | 椭圆 |
polygon | 多边形 |
polyline | 折线 |
path | 路径 |
image | 图片 |
html | HTML 节点,使用 foreignObject 渲染 HTML 片段。 |
// rect
graph.addNode({shape: "rect",x: 40,y: 40,width: 80,height: 40,label: "rect",
});// circle
graph.addNode({shape: "circle",x: 180,y: 40,width: 40,height: 40,label: "circle",
});// ellipse
graph.addNode({shape: "ellipse",x: 280,y: 40,width: 80,height: 40,label: "ellipse",
});// path
graph.addNode({shape: "path",x: 420,y: 40,width: 40,height: 40,// https://www.svgrepo.com/svg/13653/likepath: "M24.85,10.126c2.018-4.783,6.628-8.125,11.99-8.125c7.223,0,12.425,6.179,13.079,13.543c0,0,0.353,1.828-0.424,5.119c-1.058,4.482-3.545,8.464-6.898,11.503L24.85,48L7.402,32.165c-3.353-3.038-5.84-7.021-6.898-11.503c-0.777-3.291-0.424-5.119-0.424-5.119C0.734,8.179,5.936,2,13.159,2C18.522,2,22.832,5.343,24.85,10.126z",label: "path",
});// polygon
graph.addNode({shape: "polygon",x: 60,y: 150,width: 40,height: 40,points: "100,10 40,198 190,78 10,78 160,198",label: "polygon",attrs: {body: {fill: "#fff",stroke: "#8f8f8f",strokeWidth: 1,},label: {refX: 0.5,refY: "100%",refY2: 4,textAnchor: "middle",textVerticalAnchor: "top",},},
});// polyline
graph.addNode({shape: "polyline",x: 180,y: 150,width: 40,height: 40,label: "polyline",attrs: {body: {refPoints: "0,0 0,10 10,10 10,0",},label: {refX: 0.5,refY: "100%",refY2: 4,textAnchor: "middle",textVerticalAnchor: "top",},},
});// image
graph.addNode({shape: "image",x: 290,y: 150,width: 60,height: 40,imageUrl:"https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg",label: "image",attrs: {label: {refX: 0.5,refY: "100%",refY2: 4,textAnchor: "middle",textVerticalAnchor: "top",},}
});
以下是效果图
三、定制节点
实际上是从基础节点派生(继承)出我们自己的节点,并覆盖基类的某些选项和方法。
可以通过 markup 和 attrs 来定制节点的形状和样式,markup 可以类比 HTML,attrs 类比 CSS。具体可以仔细阅读 markup 和 attrs 文档。
以 Rect 为例:
- 继承
import { Node } from '@antv/x6'class Rect extends Node {......
}
-
配置
调用继承的静态方法 config(options) 来配置节点选项的默认值、自定义选项和自定义属性,最常用选项的是通过 markup 来指定节点默认的 SVG/HTML 结构,通过 attrs 来指定节点的默认属性样式
名称 类型 是否必选 默认值 说明 propHooks Function 否 undefined 自定义选项钩子 attrHooks Object 否 undefined 自定义属性钩子 …others Object 节点选项
Rect.config({width: 100,height: 40,markup: [ // 定义了节点由 <rect> 和 <text> 两个 SVG 元素构成,并分别指定了 body 和 label 两个选择器,接着就可以在 attrs 中通过这两个选择器来指定节点的默认样式。{tagName: 'rect',selector: 'body',},{tagName: 'text',selector: 'label',},],attrs: {body: {fill: '#ffffff',stroke: '#333333',strokeWidth: 2,},label: {fontSize: 14,fill: '#333333',refX: '50%',refY: '50%',textAnchor: 'middle',textVerticalAnchor: 'middle',},},// 通过钩子将自定义选项 label 应用到 'attrs/text/text' 属性上propHooks(metadata) {const { label, ...others } = metadataif (label) {ObjectExt.setByPath(others, 'attrs/text/text', label)}return others},
})
-
注册
调用 Graph 的静态方法 registerNode 来注册节点,注册以后就可以像使用内置节点那样来使用节点。
Graph.registerNode(name: string, cls: typeof Node, overwrite?: boolean)
参数名 | 类型 | 是否必选 | 默认值 | 说明 |
---|---|---|---|---|
name | String | 是 | 注册的节点名 | |
cls | typeof Node | 是 | 节点类,直接或间接继承 Node 的类 | |
overwrite | Boolean | 否 | false | 重名时是否覆盖,默认为 false 不覆盖(重名时报错) |
例如,注册名为 ‘rect’ 的节点。
Graph.registerNode('rect', Rect)
注册以后,可以像下面这样来使用。
graph.addNode({shape: 'rect',x: 30,y: 40,
})
- 便捷方法:
同时实现定义和注册节点。
Graph.registerNode(name: string, options: Object, overwrite?: boolean)
参数名 | 类型 | 是否必选 | 默认值 | 说明 |
---|---|---|---|---|
name | String | 是 | 注册的节点名 | |
options | Object | 是 | 选项 | |
overwrite | Boolean | 否 | false | 重名时是否覆盖,默认为 false 不覆盖(重名时报错) |
通过 options.inherit 来指定继承的基类,默认值为 Node 类,支持字符串或节点类,当 options.inherit 为字符串时将自动从已注册的节点中找到对应的节点作为基类,options 的其他选项与 define 方法一致。当 options.constructorName 类名缺省时,第一个参数 name 的大驼峰形式(CamelCase)也将作为自定义节点的类名。
const ports = {groups: {top: {position: "top",attrs: {circle: {r: 4,magnet: true,stroke: "#5F95FF",strokeWidth: 1,fill: "#fff",style: {visibility: "hidden",},},},},right: {position: "right",attrs: {circle: {r: 4,magnet: true,stroke: "#5F95FF",strokeWidth: 1,fill: "#fff",style: {visibility: "hidden",},},},},bottom: {position: "bottom",attrs: {circle: {r: 4,magnet: true,stroke: "#5F95FF",strokeWidth: 1,fill: "#fff",style: {visibility: "hidden",},},},},left: {position: "left",attrs: {circle: {r: 4,magnet: true,stroke: "#5F95FF",strokeWidth: 1,fill: "#fff",style: {visibility: "hidden",},},},},},items: [{group: "top",},{group: "right",},{group: "bottom",},{group: "left",},],
};Graph.registerNode("custom-rect",{inherit: "rect",width: 66,height: 36,attrs: {body: {strokeWidth: 1,stroke: "#5F95FF",fill: "#EFF4FF",},text: {fontSize: 12,fill: "#262626",},},ports: { ...ports },},true
);Graph.registerNode("custom-polygon",{inherit: "polygon",width: 66,height: 36,attrs: {body: {strokeWidth: 1,stroke: "#5F95FF",fill: "#EFF4FF",},text: {fontSize: 12,fill: "#262626",},},ports: {...ports,items: [{group: "top",},{group: "bottom",},],},},true
);Graph.registerNode("custom-circle",{inherit: "circle",width: 45,height: 45,attrs: {body: {strokeWidth: 1,stroke: "#5F95FF",fill: "#EFF4FF",},text: {fontSize: 12,fill: "#262626",},},ports: { ...ports },},true
);Graph.registerNode("custom-image",{inherit: "rect",width: 52,height: 52,markup: [{tagName: "rect",selector: "body",},{tagName: "image",},{tagName: "text",selector: "label",},],attrs: {body: {stroke: "#5F95FF",fill: "#5F95FF",},image: {width: 26,height: 26,refX: 13,refY: 16,},label: {refX: 3,refY: 2,textAnchor: "left",textVerticalAnchor: "top",fontSize: 12,fill: "#fff",},},ports: { ...ports },},true
);
除此方法外还可以使用另外一种静态方法 define 来自定义节点,具体可查看自定义节点
四、自定义HTML节点
- 渲染节点
X6 默认内置 HTML
渲染能力
import { Shape } from '@antv/x6'Shape.HTML.register({shape: 'custom-html',width: 160,height: 80,html() {const div = document.createElement('div')div.className = 'custom-html'return div},
})graph.addNode({shape: 'custom-html',x: 60,y: 100,
})
- 节点更新
在注册节点的时候,提供一个 effect,字段,是当前节点的 prop 数组,当 effect 包含的 prop 有变动时,会重新执行 html 方法,返回新的 dom,更新节点内容。
Shape.HTML.register({shape: 'custom-html',width: 160,height: 80,effect: ['data'],html(cell) {const { color } = cell.getData()const div = document.createElement('div')div.className = 'custom-html'div.style.background = colorreturn div},
})
五、 自定义React/Vue/Angular节点
可阅读官方文档 自定义React节点、自定义Vue节点、自定义Angular节点
这篇关于antv/x6_2.0学习使用(三、内置节点和自定义节点)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!