antv-x6-vue
【vue封装x6为原生组件】github地址: antv-x6-vue
核心思想
- 由于x6主要面向编辑场景,所以对每一个节点有更多的交互逻辑。所以,将x6的Shape抽象成组件,每一个组件负责管理自己的生命周期。
- 针对复杂的自定义图形,利用x6支持渲染vue组件@antv/x6-vue-shape的功能,同时利用slots将节点渲染交给当前组件,将图形相关逻辑交给x6。
import { VueShape as VueShapeContainer } from '@antv/x6-vue-shape';
cell.value = https://www.it610.com/article/new VueShapeContainer({
id, width, height,
primer, useForeignObject,
// 这里将自己的slots中的内容强行放到画布中去
// 这样图结构的交互还有一些操作逻辑交给x6
// 通过vue绘制的组件渲染和组件内部交互逻辑交给用户
component: component
? component
: () => h('div', {key: id, class: 'vue-shape'}, slots.default ? slots.default({props, item: cell}) : null),
...otherOptions,
})
graph.addCell(cell.value)
文章图片
- 提供
useVueShape
,可以很容易的自定义一个vue组件定制出来的节点。
- 提供
useCellEvent
,可以比较方便的给当前节点绑定事件。
const CustomNode = defineComponent({
name: 'CustomNode',
props: [...VueShapeProps, 'otherOptions'],
inject: [contextSymbol],
setup(props, context) {
// 直接传递props给useVueShape,watch的时候不能监听到变化
const cell = useVueShape(() => props, context)
useCellEvent('node:click', (e) => context.emit('click', e), { cell })
return () => null
}
})
- 提供
useTeleport
,优化x6-vue-shape
默认创建多个App导致渲染性能问题。同时避免出现节点数据更新不及时问题。
安装
yarn add antv-x6-vue
Components
- [x] 提供
Graph
容器以及GraphContext.useContext
获取x6
的graph
对象。可以利用这个对象操作画布,绑定事件。
- [x] 包装
Shape
作为vue
组件+使用x6-vue-shape
封装自定义组件,暴露的组件有:
类 |
shape 名称 |
描述 |
Node |
rect |
等同于Shape.Rect |
Edge |
edge |
等同于Shape.Edge |
VueShape |
vue-shape |
使用@antv/x6-vue-shape 渲染的自定义vue 组件的容器,可以将slots.default 内容渲染到节点内。 |
Shape.Rect |
rect |
矩形。 |
Shape.Circle |
circle |
圆形。 |
Shape.Ellipse |
ellipse |
椭圆。 |
Shape.Polygon |
polygon |
多边形。 |
Shape.Polyline |
polyline |
折线。 |
Shape.Path |
path |
路径。 |
Shape.Image |
image |
图片。 |
Shape.HTML |
html |
HTML 节点,使用 foreignObject 渲染 HTML 片段。 |
Shape.TextBlock |
text-block |
文本节点,使用 foreignObject 渲染文本。 |
Shape.BorderedImage |
image-bordered |
带边框的图片。 |
Shape.EmbeddedImage |
image-embedded |
内嵌入矩形的图片。 |
Shape.InscribedImage |
image-inscribed |
内嵌入椭圆的图片。 |
Shape.Cylinder |
cylinder |
圆柱。 |
Shape.Edge |
edge |
边。 |
Shape.DoubleEdge |
double-edge |
双线边。 |
Shape.ShadowEdge |
shadow-edge |
阴影边。 |
另外提供帮助函数
名称 |
描述 |
useCell |
使用这个函数可以通过传递markup之类的参数自定义节点 |
useVueShape |
使用这个函数自定义vue的渲染内容定制更加复杂的节点 |
useCellEvent |
通过这个函数绑定事件到cell上面 |
名称 |
描述 |
PortGroup |
提供ports/groups/ 相关的配置,同时也作为Port组件的容器,提供一个默认的group名称 |
Port |
调用addPort/removePort操作当前连接桩,比x6官方多提供一个magnet参数(默认情况需要使用attrs/circle/magnet 进行配置)。另外,Port也可以独立使用。 |
使用Port和PortGroup的时候,可以放在一个以port
命名的slot里面(考虑到默认的VueShape会将默认的slot认为是用户自定义的节点,这里使用slots.port区分一下),也可以直接使用默认的slot
名称 |
描述 |
Grid |
渲染网格 |
Background |
渲染背景 |
Scroller |
滚动组件 |
Clipboard |
剪贴板,配合Keyboard 组件可以使用ctrl+c /ctrl+x /ctrl+v |
Keyboard |
键盘快捷键 |
MouseWheel |
鼠标滚轮,支持使用滚轮实现画布放大缩小 |
Connecting |
配置连线相关参数和帮助方法 |
名称 |
描述 |
Snapline |
对齐线 |
Selection |
点选/框选 |
MiniMap |
小地图 |
Stencil |
内置的带分组和搜索功能的拖拽组件,还提供StencilGroup 以实现分组功能 |
Contextmenu |
右键菜单 |
TeleportContainer |
一个默认和useVueShape绑定到同一个view的容器,使用这个组件的时候,可以不用手动调用useTeleport,也不用专门指定view |
TODO
- [ ] Stencil支持默认分组(不使用
StencilGroup
的情况)
- [ ] Dnd也作为组件实现
- [x] ContextMenu:实现一个默认的menu,同时暴露一个useContextMenu方便用户定制
- [x] 实现Connecting,也作为组件使用
- [x] 提供PluginInstallFunction,支持全局注册组件(组件有
x6-
或者X6
前缀,例如X6Node
,x6-node
都会对应前面提到的Node
组件)
- [x] 支持群组功能。UI嵌套的时候自动调用embed和unembed函数处理父子关系
- [x] 使用Teleport渲染
默认的x6-vue-shape
把每一个节点渲染成一个vue的app导致渲染性能问题
通过vue3提供的Teleport功能,让当前App的子组件渲染到foreignobject内部。解决性能问题的同时,也能更好的处理VueShape组件内部数据及时更新的问题
DEMO
import { defineComponent, reactive } from 'vue'
import Graph, { Node, Edge, Grid, Background } from 'antv-x6-vue'export default defineComponent({
setup(props) {
// ...
const state = reactive({
showGrid: true,
y: 10,
visible: true,
})
const methods = {
added(e) {
console.log('added', e)
},
click(e) {
console.log('click', e)
},
changed(e) {
console.log('changed', e)
},
}
return { ...toRefs(state), ...methods }
},
})// template
这里是一个vue的组件
文章图片
Hello
文章图片
推荐阅读