瀏覽代碼

连接桩样式

CzRger 4 月之前
父節點
當前提交
2f63aa81a9

+ 1 - 1
src/stores/modules/workflow.ts

@@ -30,7 +30,7 @@ export const useWorkflowStore = defineStore('workflow', {
       const dom = document.getElementById(portId)
       const node = this.graph.getCellById(nodeId)
       if (dom && node) {
-        node.portProp(portId, ['args', 'dy'], dom.offsetTop + 17)
+        node.portProp(portId, ['args', 'dy'], dom.offsetTop + 4)
       }
     },
     getInVars(node) {

+ 37 - 27
src/views/workflow/chart/index.vue

@@ -106,7 +106,7 @@
 import {createVNode, getCurrentInstance, nextTick, onMounted, reactive, ref, render, watch} from "vue";
 import {Graph, Path, Shape} from '@antv/x6'
 import {getNodeDefault, lineActiveStyle, lineStyle} from "@/views/workflow/config";
-import nodeAdd from './node-add.vue'
+import nodePort from './node-port.vue'
 import {register} from "@antv/x6-vue-shape";
 import WorkflowNode from "./node-index.vue";
 import {handleEdge, handleNode} from "@/views/workflow/handle";
@@ -127,8 +127,8 @@ Graph.registerPortLayout('start', (portsPositionArgs, elemBBox) => {
   return portsPositionArgs.map((_, index) => {
     return {
       position: {
-        x: 3,
-        y: 25 + 7,
+        x: 0,
+        y: 25,
       },
     }
   })
@@ -143,8 +143,8 @@ Graph.registerPortLayout('end', (portsPositionArgs, elemBBox) => {
   return portsPositionArgs.map((_, index) => {
     return {
       position: {
-        x: elemBBox.width + 11,
-        y: 25 + 7,
+        x: elemBBox.width,
+        y: 25,
       },
     }
   })
@@ -162,7 +162,7 @@ Graph.registerPortLayout('more', (portsPositionArgs, elemBBox) => {
     })
     return {
       position: {
-        x: elemBBox.width + 11,
+        x: elemBBox.width,
         y: _.dy,
       },
     }
@@ -188,6 +188,26 @@ Graph.registerConnector(
 )
 Graph.registerNodeTool('contextmenu', ContextMenuTool, true)
 Graph.registerEdgeTool('contextmenu', ContextMenuTool, true)
+Graph.registerHighlighter('port-highlight', {
+  highlight(cellView, magnet) {
+    const dom = magnet.getElementsByClassName('node-port')[0]
+    dom?.classList.add('highlight')
+  },
+  unhighlight(cellView, magnet) {
+    const dom = magnet.getElementsByClassName('node-port')[0]
+    dom?.classList.remove('highlight')
+  },
+}, true)
+Graph.registerHighlighter('port-select', {
+  highlight(cellView, magnet) {
+    const dom = magnet.getElementsByClassName('node-port')[0]
+    dom?.classList.add('select')
+  },
+  unhighlight(cellView, magnet) {
+    const dom = magnet.getElementsByClassName('node-port')[0]
+    dom?.classList.remove('select')
+  },
+}, true)
 const WorkflowStore = useWorkflowStore()
 const emits = defineEmits([])
 const props = defineProps({
@@ -239,29 +259,11 @@ const initChart = () => {
     highlighting: {
       // 连接桩可以被连接时在连接桩外围围渲染一个包围框
       magnetAvailable: {
-        name: 'stroke',
-        args: {
-          rx: 100,
-          ry: 100,
-          attrs: {
-            fill: '#fff',
-            stroke: 'rgba(var(--czr-main-color-rgb), 0.5)',
-            'stroke-width': 3,
-          },
-        },
+        name: 'port-highlight',
       },
       // 连接桩吸附连线时在连接桩外围围渲染一个包围框
       magnetAdsorbed: {
-        name: 'stroke',
-        args: {
-          rx: 100,
-          ry: 100,
-          attrs: {
-            fill: '#fff',
-            stroke: 'rgba(var(--czr-main-color-rgb), 1)',
-            'stroke-width': 3,
-          },
-        },
+        name: 'port-select',
       },
     },
     connecting: {
@@ -319,7 +321,7 @@ const initChart = () => {
       const selectors = args.contentSelectors
       const container = selectors && selectors.foContent
       if (container) {
-        render(createVNode(nodeAdd, {
+        render(createVNode(nodePort, {
           port: args.port,
           node: args.node,
           graph: state.graph,
@@ -565,4 +567,12 @@ defineExpose({
     }
   }
 }
+:deep(.port-start-high) {
+  background-color: red;
+  width: 10px;
+  height: 10px;
+  .port-start {
+    background-color: red !important;
+  }
+}
 </style>

+ 1 - 1
src/views/workflow/chart/node-index.vue

@@ -64,7 +64,7 @@ onMounted(() => {
   position: absolute;
   width: 240px;
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-  border-width: 4px;
+  border-width: 2px;
   border-color: transparent;
   &.active {
     border-color: rgba(var(--czr-main-color-rgb), 0.5);

+ 75 - 16
src/views/workflow/chart/node-add.vue

@@ -1,6 +1,6 @@
 <template>
   <template v-if="port?.group === 'start'">
-    <div class="port">
+    <div class="node-port">
       <div/>
     </div>
   </template>
@@ -13,16 +13,25 @@
         minWidth: 0,
       }">
       <template #reference>
-        <div class="port">
-          <ElTooltip
-            placement="top"
-            effect="light"
-            content="<div><b>点击</b>添加节点</div><div><b>拖拽</b>连接节点</div>"
-            raw-content
-          >
+        <template v-if="state.active">
+          <div class="node-port-operation">
+            <ElTooltip
+              placement="top"
+              effect="light"
+              content="<div><b>点击</b>添加节点</div><div><b>拖拽</b>连接节点</div>"
+              raw-content
+            >
+              <div>
+                <SvgIcon name="czr_add" color="#ffffff" size="12"/>
+              </div>
+            </ElTooltip>
+          </div>
+        </template>
+        <template v-else>
+          <div class="node-port-operation-normal">
             <div/>
-          </ElTooltip>
-        </div>
+          </div>
+        </template>
       </template>
       <div class="node-add">
         <div class="node-add-item __hover" @click="onAddNode(NodeType.Test)">{{ NodeTypeObj[NodeType.Test].title }}</div>
@@ -34,11 +43,12 @@
 </template>
 
 <script setup lang="ts">
-import {getCurrentInstance, inject, reactive, ref} from "vue";
+import {getCurrentInstance, inject, onMounted, reactive, ref, watch} from "vue";
 import { ElPopover, ElTooltip } from 'element-plus';
 import {getNodeDefault} from "@/views/workflow/config";
 import {GraphHistoryStep, NodeType, NodeTypeObj} from "@/views/workflow/types";
 import {handleEdge, handleNode} from "@/views/workflow/handle";
+import SvgIcon from "@/components/SvgIcon/index.vue";
 
 const emits = defineEmits([])
 const props = defineProps({
@@ -47,7 +57,9 @@ const props = defineProps({
   graph: <any>{},
 })
 const {proxy}: any = getCurrentInstance()
-const state: any = reactive({})
+const state: any = reactive({
+  active: false
+})
 const onAddNode = (type) => {
   const node = getNodeDefault(type)
   const sons = props.graph.getSuccessors(props.node, {breadthFirst: true, deep: false, distance: 1}).filter(v => v.data.workflowData.edgeSource === props.port.id)
@@ -94,22 +106,69 @@ const onAddNode = (type) => {
     props.graph.stopBatch(GraphHistoryStep.NodeAdd)
   }, 100)
 }
+onMounted(() => {
+  props.node.on('change:attrs', () => {
+    state.active = props.node.getAttrByPath('hover') || props.node.getAttrByPath('select')
+  })
+})
 </script>
 
 <style lang="scss" scoped>
 @use "@/views/workflow/instance/component/style";
 
-.port {
+.node-port {
   width: 100%;
   height: 100%;
+  position: relative;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
   >div {
+    background-color: var(--czr-main-color);
     width: 100%;
     height: 100%;
-    border: style.$borderStyle;
-    background-color: #ffffff;
-    border-radius: 50%;
+    position: absolute;
+  }
+  &.highlight {
+    >div {
+      background-color: var(--czr-main-color);
+      width: calc(100% + 1px);
+      height: calc(100% + 4px);
+      opacity: 0.5;
+    }
+  }
+  &.select {
+    >div {
+      opacity: 1;
+    }
   }
 }
+
+.node-port-operation-normal {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  >div {
+    background-color: var(--czr-main-color);
+    width: 2px;
+    height: 10px;
+    margin-left: 1px;
+  }
+}
+
+.node-port-operation {
+  background-color: #286bfb;
+  width: 100%;
+  height: 100%;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
 .node-add {
   min-width: 100px;
   padding: 6px 10px;

+ 0 - 12
src/views/workflow/config.ts

@@ -16,18 +16,6 @@ export const lineActiveStyle = {
   targetMarker: null
 }
 
-export const portStyle = {
-  attrs: {
-    fo: {
-      width: 12,
-      height: 12,
-      x: -9,
-      y: -9,
-      magnet: true,
-    },
-  },
-}
-
 export const nodeDefault = {
   [NodeType.Test]: () => (<NodeStruct>{
     x: 0,

+ 36 - 5
src/views/workflow/handle.ts

@@ -1,6 +1,5 @@
 import {Markup} from "@antv/x6";
-import {merge} from "lodash";
-import {lineStyle, portStyle} from "@/views/workflow/config";
+import {lineStyle} from "@/views/workflow/config";
 import { v4 } from "uuid";
 import {useWorkflowStore} from "@/stores";
 import {GraphHistoryStep, NodeType} from "@/views/workflow/types";
@@ -29,9 +28,41 @@ export const handleNode = (no) => {
     portMarkup: [Markup.getForeignObjectMarkup()],
     ports: {
       groups: {
-        start: merge(JSON.parse(JSON.stringify(portStyle)), {position: {name: 'start'}}),
-        end: merge(JSON.parse(JSON.stringify(portStyle)), {position: {name: 'end'}}),
-        more: merge(JSON.parse(JSON.stringify(portStyle)), {position: {name: 'more'}}),
+        start: {
+          position: {name: 'start'},
+          attrs: {
+            fo: {
+              magnet: true,
+              width: 2,
+              height: 10,
+              x: -2,
+              y: -2,
+            }
+          }
+        },
+        end: {
+          position: {name: 'end'},
+          attrs: {
+            fo: {
+              magnet: true,
+              width: 16,
+              height: 16,
+              x: -4,
+              y: -6,
+            }
+          }
+        },
+        more: {
+          position: {name: 'more'},
+          attrs: {
+            fo: {
+              magnet: true,
+              width: 16,
+              height: 16,
+              x: -4,
+            }
+          }
+        },
       },
       items: []
     },