瀏覽代碼

fix: Improve the flowChart component

xiaoxian521 4 年之前
父節點
當前提交
ba41753d77

+ 22 - 0
src/components/FlowChart/index.ts

@@ -0,0 +1,22 @@
+import { App } from "vue"
+import control from "./src/Control.vue"
+import nodePanel from "./src/NodePanel.vue"
+import dataDialog from "./src/DataDialog.vue"
+
+export const Control = Object.assign(control, {
+  install(app: App) {
+    app.component(control.name, control)
+  }
+})
+
+export const NodePanel = Object.assign(nodePanel, {
+  install(app: App) {
+    app.component(nodePanel.name, nodePanel)
+  }
+})
+
+export const DataDialog = Object.assign(dataDialog, {
+  install(app: App) {
+    app.component(dataDialog.name, dataDialog)
+  }
+})

+ 0 - 0
src/components/FlowChart/src/Bpmn.vue


+ 72 - 75
src/components/FlowChart/src/Control.vue

@@ -1,5 +1,6 @@
 <template>
   <div class="control-container">
+    <!-- 功能按钮 -->
     <ul>
       <li
         v-for="(item,key) in titleLists"
@@ -9,117 +10,111 @@
         @mouseenter.prevent="onEnter(key)"
         @mouseleave.prevent="focusIndex = -1"
       >
-        <button ref="controlButton" @click="onControl(item,key)">
+        <button
+          :ref="'controlButton' + key"
+          :disabled="item.disabled"
+          :style="{cursor: item.disabled === false ? 'pointer' : 'not-allowed'}"
+          @click="onControl(item,key)"
+        >
           <span :class="'iconfont ' + item.icon"></span>
           <p>{{ item.text }}</p>
         </button>
       </li>
     </ul>
-    <!-- <el-button size="small" @click="$_zoomIn">放大</el-button>
-      <el-button size="small" @click="$_zoomOut">缩小</el-button>
-      <el-button size="small" @click="$_zoomReset">大小适应</el-button>
-      <el-button size="small" @click="$_translateRest">定位还原</el-button>
-      <el-button size="small" @click="$_reset">还原(大小&定位)</el-button>
-      <el-button size="small" @click="$_undo" :disabled="undoDisable">上一步(ctrl+z)</el-button>
-      <el-button size="small" @click="$_redo" :disabled="redoDisable">下一步(ctrl+y)</el-button>
-      <el-button size="small" @click="$_download">下载图片</el-button>
-      <el-button size="small" @click="$_catData">查看数据</el-button>
-    <el-button v-if="catTurboData" size="small" @click="$_catTurboData">查看turbo数据</el-button>-->
   </div>
 </template>
 
-<script>
-export default {
+<script lang='ts'>
+import { defineComponent ,ref, unref, onMounted } from "vue";
+import { templateRef } from '@vueuse/core'
+
+export default defineComponent({
   name: "Control",
   props: {
     lf: Object || String,
     catTurboData: Boolean,
   },
-  data() {
-    return {
-      undoDisable: true,
-      redoDisable: true,
-      focusIndex: -1,
-      titleLists: [
+  emits: ["catData"],
+  setup(props,{emit}) {
+    const controlButton3 = templateRef<HTMLElement | null>('controlButton3', null)
+    const controlButton4 = templateRef<HTMLElement | null>('controlButton4', null)
+
+    let focusIndex = ref(-1)
+    let titleLists = ref([
         {
           icon: "icon-zoom-out-hs",
           text: "缩小",
+          disabled: false
         },
         {
           icon: "icon-enlarge-hs",
           text: "放大",
+          disabled: false
         },
         {
           icon: "icon-full-screen-hs",
           text: "适应",
+          disabled: false
         },
         {
           icon: "icon-previous-hs",
           text: "上一步",
+          disabled: true
         },
         {
           icon: "icon-next-step-hs",
           text: "下一步",
+          disabled: true
         },
-      ],
-    };
-  },
-  mounted() {
-    this.$props.lf.on("history:change", ({ data: { undoAble, redoAble } }) => {
-      this.$data.undoDisable = !undoAble;
-      this.$data.redoDisable = !redoAble;
-    });
-  },
-  methods: {
-    onControl(item, key) {
-      ["zoom", "zoom", "resetZoom", "undo", "redo"].forEach((v, i) => {
-        let domControl = this.$props.lf;
+        {
+          icon: "icon-download-hs",
+          text: "下载图片",
+          disabled: false
+        },
+        {
+          icon: "icon-watch-hs",
+          text: "查看数据",
+          disabled: false
+        },
+      ])
+
+    const onControl = (item, key) => {
+      ["zoom", "zoom", "resetZoom", "undo", "redo", "getSnapshot"].forEach((v, i) => {
+        let domControl = props.lf
         if (key === 1) {
-          domControl.zoom(true);
+          domControl.zoom(true)
+        }
+        if (key === 6) {
+          emit("catData")
         }
         if (key === i) {
-          domControl[v]();
+          domControl[v]()
         }
-      });
-    },
-    onEnter(key) {
-      this.focusIndex = key;
-    },
-    $_zoomIn() {
-      this.$props.lf.zoom(true);
-    },
-    $_zoomOut() {
-      this.$props.lf.zoom(false);
-    },
-    $_zoomReset() {
-      this.$props.lf.resetZoom();
-    },
-    $_translateRest() {
-      this.$props.lf.resetTranslate();
-    },
-    $_reset() {
-      this.$props.lf.resetZoom();
-      this.$props.lf.resetTranslate();
-    },
-    $_undo() {
-      this.$props.lf.undo();
-    },
-    $_redo() {
-      this.$props.lf.redo();
-    },
-    $_download() {
-      this.$props.lf.getSnapshot();
-    },
-    $_catData() {
-      this.$emit("catData");
-    },
-    $_catTurboData() {
-      this.$emit("catTurboData");
-    },
+      })
+    }
+
+    const onEnter = (key) => {
+      focusIndex.value = key
+    }
+
+    onMounted(()=>{
+      props.lf.on("history:change", ({ data: { undoAble, redoAble } }) => {
+        unref(titleLists)[3].disabled = unref(controlButton3).disabled = !undoAble
+        unref(titleLists)[4].disabled = unref(controlButton4).disabled = !redoAble
+      })
+    })
+
+    return {
+      focusIndex,
+      titleLists,
+      onControl,
+      onEnter
+    };
   },
-};
+});
 </script>
 
+
 <style scoped>
 @import "./assets/iconfont/iconfont.css";
 .control-container {
@@ -127,7 +122,6 @@ export default {
   right: 20px;
   background: hsla(0, 0%, 100%, 0.8);
   box-shadow: 0 1px 4px rgb(0 0 0 / 30%);
-  border-radius: 5px;
 }
 .iconfont {
   font-size: 25px;
@@ -145,7 +139,10 @@ export default {
 .control-container ul li {
   width: 60px;
   text-align: center;
-  cursor: pointer;
-  /* pointer-events: none; */
 }
-</style>
+.control-container ul li button {
+  border: none;
+  background-color: transparent;
+  outline: none;
+}
+</style>

+ 11 - 15
src/components/FlowChart/src/DataDialog.vue

@@ -1,22 +1,18 @@
 <template>
-  <div>
-    <vue-json-pretty :path="'res'" :deep="3" :showLength="true" :data="graphData"></vue-json-pretty>
-  </div>
+  <vue-json-pretty :path="'res'" :deep="3" :showLength="true" :data="graphData"></vue-json-pretty>
 </template>
 
-<script>
-import VueJsonPretty from 'vue-json-pretty'
-import 'vue-json-pretty/lib/styles.css'
-
-export default {
+<script lang='ts'>
+import VueJsonPretty from "vue-json-pretty";
+import "vue-json-pretty/lib/styles.css";
+import { defineComponent } from "vue";
+export default defineComponent({
+  name: "DataDialog",
   props: {
     graphData: Object
   },
   components: {
-    VueJsonPretty,
-  },
-};
-</script>
-
-<style scoped>
-</style>
+    VueJsonPretty
+  }
+});
+</script>

+ 38 - 27
src/components/FlowChart/src/NodePanel.vue

@@ -1,6 +1,12 @@
 <template>
+  <!-- 左侧bpmn元素选择器 -->
   <div class="node-panel">
-    <div class="node-item" v-for="item in nodeList" :key="item.text" @mousedown="$_dragNode(item)">
+    <div
+      class="node-item"
+      v-for="item in nodeList"
+      :key="item.text"
+      @mousedown="nodeDragNode(item)"
+    >
       <div class="node-item-icon" :class="item.class">
         <div v-if="item.type === 'user' || item.type === 'time'" class="shape"></div>
       </div>
@@ -9,40 +15,45 @@
   </div>
 </template>
 
-<script>
-export default {
-  name: 'NodePanel',
+<script lang='ts'>
+import { defineComponent, ref, unref } from "vue";
+export default defineComponent({
+  name: "NodePanel",
   props: {
     lf: Object,
-    nodeList: Array,
+    nodeList: Array
   },
-  data() {
-    return {
-      node: {
-        type: 'rect',
-        property: {
-          a: 'efrwe',
-          b: 'wewe'
-        }
-      },
-      properties: {
-        a: 'efrwe',
-        b: 'wewe'
+  setup(props) {
+    let node = ref({
+      type: "rect",
+      property: {
+        a: "efrwe",
+        b: "wewe"
       }
-    }
-  },
-  methods: {
-    $_dragNode(item) {
-      this.$props.lf.dnd.startDrag({
+    });
+    let properties = ref({
+      a: "efrwe",
+      b: "wewe"
+    });
+
+    const nodeDragNode = item => {
+      props.lf.dnd.startDrag({
         type: item.type,
-        properties: this.$data.properties
-      })
-    }
+        properties: unref(properties)
+      });
+    };
+
+    return {
+      node,
+      properties,
+      nodeDragNode
+    };
   }
-}
+});
 </script>
 
-<style>
+
+<style scoped>
 .node-panel {
   position: absolute;
   top: 100px;

+ 0 - 60
src/views/components/flow-chart/index.vue

@@ -1,60 +0,0 @@
-<template>
-  <div id="container"></div>
-</template>
-
-<script lang='ts'>
-import LogicFlow from "@logicflow/core";
-import "@logicflow/core/dist/style/index.css";
-import { onMounted } from "vue";
-
-const data = {
-  // 节点
-  nodes: [
-    {
-      id: 50,
-      type: "rect",
-      x: 100,
-      y: 150,
-      text: "你好",
-    },
-    {
-      id: 21,
-      type: "circle",
-      x: 300,
-      y: 150,
-    },
-  ],
-  // 边
-  edges: [
-    {
-      type: "polyline",
-      sourceNodeId: 50,
-      targetNodeId: 21,
-    },
-  ],
-};
-export default {
-  setup() {
-    onMounted(() => {
-      const lf = new LogicFlow({
-        container: document.querySelector("#container"),
-        stopScrollGraph: true,
-        stopZoomGraph: true,
-        width: 500,
-        height: 500,
-        grid: {
-          type: "dot",
-          size: 20,
-        },
-      });
-
-      lf.render(data);
-    });
-
-    return {};
-  },
-};
-</script>
-
-<style scoped>
-</style>

+ 52 - 58
src/views/flow-chart/index.vue

@@ -6,8 +6,7 @@
       v-if="lf"
       :lf="lf"
       :catTurboData="false"
-      @catData="$_catData"
-      @catTurboData="$_catTurboData"
+      @catData="catData"
     ></Control>
     <!-- 节点面板 -->
     <NodePanel :lf="lf" :nodeList="nodeList"></NodePanel>
@@ -19,28 +18,25 @@
     </el-dialog>
   </div>
 </template>
-<script>
+
+<script lang='ts'>
+import { ref, unref, onMounted, nextTick } from "vue"
 import LogicFlow from '@logicflow/core'
 import { Snapshot, BpmnElement } from '@logicflow/extension'
 import '@logicflow/core/dist/style/index.css'
 import '@logicflow/extension/lib/style/index.css'
-import NodePanel from '/@/components/FlowChart/src/NodePanel.vue'
-import Control from '/@/components/FlowChart/src/Control.vue'
-import DataDialog from '/@/components/FlowChart/src/DataDialog.vue'
-import { toTurboData, toLogicflowData } from '/@/components/FlowChart/src/adpterForTurbo.ts'
-import { BpmnNode } from '/@/components/FlowChart/src/config.ts'
-import demoData from './dataTurbo.json'
+import { Control, NodePanel, DataDialog } from '/@/components/FlowChart'
 
+import { toTurboData, toLogicflowData } from '/@/components/FlowChart/src/adpterForTurbo'
+import { BpmnNode } from '/@/components/FlowChart/src/config'
+import demoData from './dataTurbo.json'
 export default {
-  name: 'LF',
   components: { NodePanel, Control, DataDialog },
-  data() {
-    return {
-      lf: null,
-      dialogVisible: false,
-      graphData: null,
-      dataVisible: false,
-      config: {
+  setup() {
+    let lf = ref(null) 
+    let graphData =ref(null)
+    let dataVisible = ref(false)
+    let config = ref({
         grid: true,
         background: {
           color: '#f7f9ff'
@@ -48,51 +44,54 @@ export default {
         keyboard: {
           enabled: true
         },
-      },
-      nodeList: BpmnNode,
-    }
-  },
-  mounted() {
-    this.$_initLf()
-  },
-  methods: {
-    $_initLf() {
+      })
+    let nodeList= BpmnNode
+
+    function initLf() {
       // 画布配置
       LogicFlow.use(Snapshot)
       // 使用bpmn插件,引入bpmn元素,这些元素可以在turbo中转换后使用
       LogicFlow.use(BpmnElement)
-      const lf = new LogicFlow({ ...this.config, container: document.querySelector('#LF-Turbo') })
-      this.lf = lf
+      const domLf = new LogicFlow({ ...unref(config), container: document.querySelector('#LF-Turbo') })
+      lf.value = domLf
       // 设置边类型bpmn:sequenceFlow为默认类型
-      lf.setDefaultEdgeType('bpmn:sequenceFlow')
-      this.$_render()
-    },
-    $_render() {
+      unref(lf).setDefaultEdgeType('bpmn:sequenceFlow')
+      onRender()
+    }
+
+    function onRender() {
       // Turbo数据转换为LogicFlow内部识别的数据结构
       const lFData = toLogicflowData(demoData)
-      this.lf.render(lFData)
-    },
-    closeDialog() {
-      this.$data.dialogVisible = false
-    },
-    $_catData() {
-      this.$data.graphData = this.$data.lf.getGraphData()
-      this.$data.dataVisible = true
-    },
-    $_catTurboData() {
-      debugger
-      const graphData = this.$data.lf.getGraphData()
-      // 数据转化为Turbo识别的数据结构
-      this.$data.graphData = toTurboData(graphData)
-      this.$data.dataVisible = true
-    },
-    goto() {
-      this.$router.push('/')
+      lf.value.render(lFData)
     }
-  }
-}
+
+    function catData() {
+      graphData.value = unref(lf).getGraphData()
+      dataVisible.value = true
+    }
+
+    onMounted(()=>{
+      initLf()
+    })
+
+    return {
+      lf,
+      graphData,
+      dataVisible,
+      config,
+      nodeList,
+      catData
+    };
+  },
+};
 </script>
-<style>
+
+<style scoped>
+#LF-Turbo {
+  width: 100vw;
+  height: 85%;
+  outline: none;
+}
 .logic-flow-view {
   height: 100%;
   position: relative;
@@ -107,11 +106,6 @@ export default {
   right: 20px;
   z-index: 2;
 }
-#LF-Turbo {
-  width: 100vw;
-  height: 85%;
-  outline: none;
-}
 .time-plus {
   cursor: pointer;
 }