|
|
@@ -0,0 +1,134 @@
|
|
|
+<template>
|
|
|
+ <div ref="canvas" class="w-full h-full">
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+import { ref, onMounted } from 'vue'
|
|
|
+import { Graph } from '@antv/x6'
|
|
|
+
|
|
|
+defineOptions({
|
|
|
+ name: 'workflow'
|
|
|
+})
|
|
|
+
|
|
|
+const canvas = ref<HTMLDivElement>()
|
|
|
+
|
|
|
+const data = {
|
|
|
+ nodes: [
|
|
|
+ {
|
|
|
+ id: 'node1',
|
|
|
+ shape: 'rect',
|
|
|
+ x: 40,
|
|
|
+ y: 40,
|
|
|
+ width: 100,
|
|
|
+ height: 40,
|
|
|
+ label: 'hello',
|
|
|
+ attrs: {
|
|
|
+ // body 是选择器名称,选中的是 rect 元素
|
|
|
+ body: {
|
|
|
+ stroke: '#8f8f8f',
|
|
|
+ strokeWidth: 1,
|
|
|
+ fill: '#fff',
|
|
|
+ rx: 6,
|
|
|
+ ry: 6
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'node2',
|
|
|
+ shape: 'rect',
|
|
|
+ x: 160,
|
|
|
+ y: 180,
|
|
|
+ width: 100,
|
|
|
+ height: 40,
|
|
|
+ label: 'world',
|
|
|
+ attrs: {
|
|
|
+ body: {
|
|
|
+ stroke: '#8f8f8f',
|
|
|
+ strokeWidth: 1,
|
|
|
+ fill: '#fff',
|
|
|
+ rx: 6,
|
|
|
+ ry: 6
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ edges: [
|
|
|
+ {
|
|
|
+ shape: 'edge',
|
|
|
+ source: 'node1',
|
|
|
+ target: 'node2',
|
|
|
+ label: 'x6',
|
|
|
+ attrs: {
|
|
|
+ // line 是选择器名称,选中的边的 path 元素
|
|
|
+ line: {
|
|
|
+ stroke: '#8f8f8f',
|
|
|
+ strokeWidth: 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 初始化工作流
|
|
|
+ */
|
|
|
+const initWorkflow = () => {
|
|
|
+ console.log('initWorkflow')
|
|
|
+ const graph = new Graph({
|
|
|
+ container: canvas.value,
|
|
|
+ width: canvas.value?.clientWidth,
|
|
|
+ height: canvas.value?.clientHeight,
|
|
|
+ autoResize: true,
|
|
|
+ panning: false,
|
|
|
+ // 鼠标滚轮缩放
|
|
|
+ mousewheel: {
|
|
|
+ enabled: true,
|
|
|
+ zoomAtMousePosition: true,
|
|
|
+ modifiers: 'ctrl',
|
|
|
+ minScale: 0.2,
|
|
|
+ maxScale: 2
|
|
|
+ },
|
|
|
+ background: {
|
|
|
+ color: '#eee'
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ size: 20,
|
|
|
+ type: 'dot',
|
|
|
+ visible: true,
|
|
|
+ args: { background: true }
|
|
|
+ },
|
|
|
+ // 节点交互
|
|
|
+ interacting: {
|
|
|
+ edgeLabelMovable: false,
|
|
|
+ edgeMovable: true,
|
|
|
+ nodeMovable: (view) => {
|
|
|
+ // 节点上锁状态无法移动
|
|
|
+ const data = view.cell.getData<{ lock: boolean }>()
|
|
|
+ return !data?.lock
|
|
|
+ },
|
|
|
+ arrowheadMovable: true,
|
|
|
+ vertexMovable: true,
|
|
|
+ vertexAddable: true,
|
|
|
+ vertexDeletable: true,
|
|
|
+ useEdgeTools: true,
|
|
|
+ magnetConnectable: true,
|
|
|
+ stopDelegateOnDragging: true,
|
|
|
+ toolsAddable: true
|
|
|
+ },
|
|
|
+ // 连线配置
|
|
|
+ connecting: {
|
|
|
+ snap: true,
|
|
|
+ allowLoop: true,
|
|
|
+ allowPort: false,
|
|
|
+ allowNode: false,
|
|
|
+ allowMulti: false
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ graph.fromJSON(data) // 渲染元素
|
|
|
+ graph.centerContent() // 居中显示
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(initWorkflow)
|
|
|
+</script>
|