antv-x6-vue
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 = 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下面 |
- [x] 形象连贯桩为组件应用
名称 | 形容 |
---|---|
PortGroup | 提供ports/groups/<group_name> 相干的配置,同时也作为Port组件的容器,提供一个默认的group名称 |
Port | 调用addPort/removePort操作以后连贯桩,比x6官网多提供一个magnet参数(默认状况须要应用attrs/circle/magnet 进行配置)。另外,Port也能够独立应用。 |
应用Port和PortGroup的时候,能够放在一个以port
命名的slot外面(思考到默认的VueShape会将默认的slot认为是用户自定义的节点,这里应用slots.port辨别一下),也能够间接应用默认的slot
<Node id="1" :x="100" :y="100" label="node1"> <PortGroup name="in" position="top" :attrs="{circle: {r: 6, magnet: true, stroke: '#31d0c6'}}"> <Port id="id1" /> <Port id="id2" :magnet="false" /> </PortGroup></Node><Node id="2" :x="200" :y="200" label="node2"> <Port id="id1" /></Node>
- [x] 提供内置的一些组件
名称 | 形容 |
---|---|
Grid | 渲染网格 |
Background | 渲染背景 |
Scroller | 滚动组件 |
Clipboard | 剪贴板,配合Keyboard 组件能够应用ctrl+c /ctrl+x /ctrl+v |
Keyboard | 键盘快捷键 |
MouseWheel | 鼠标滚轮,反对应用滚轮实现画布放大放大 |
Connecting | 配置连线相干参数和帮忙办法 |
- [x] Widgets
名称 | 形容 |
---|---|
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
组件)<x6-node id="44" :x="400" :y="300" label="node4"><x6-port-group name="in" position="top" :attrs="{circle: {r: 6, magnet: true, stroke: '#31d0c6'}}"> <x6-port id="id1" /></x6-port-group></x6-node>
[x] 反对群组性能。UI嵌套的时候主动调用embed和unembed函数解决父子关系
<Node id="9" :x="500" :y="200" label="node9" :width="300" :height="200"><Node id="99" :x="550" :y="220" label="node99" :width="200" :height="150"> <Node id="999" :x="580" :y="240" label="node999"></Node></Node></Node>
[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<template> <Graph> <Node id="1" :x="100" :y="100" /> <Node id="2" :x="200" :y="200" /> <Edge id="e1" source="1" target="2" /> <VueShape primer="rect" id="3" :x="200" :y="300" :width="160" :attrs="{rect: {fill: '#ddd', stroke: '#333'}, label: {text: 'VueShape'}}"> <div>这里是一个vue的组件</div> <img style="width: 30px;height:30px;" src="https://v3.cn.vuejs.org/logo.png" /> </VueShape> <CustomNode v-if="visible" primer="circle" id="4" :x="400" :y="y" :attrs="{circle: {fill: '#ddd', stroke: '#333'}, label: {text: 'CustomNode'}}" @added="added" @click="click" @cell:change:position="changed" > <span>Hello</span> </CustomNode> <Edge id="e2" source="1" target="3" /> <Background /> <Grid :visible="showGrid" /> <Snapline /> <Selection /> <Clipboard /> </Graph></template>