(AntV X6)vue2项目流程图实现

(AntV X6)vue2流程图实现


项目:gitLab/zhengzhouyuan

效果:


一、项目引入X6

npm install @antv/x6 --save

二、引入相关插件

npm install --save @antv/x6-plugin-clipboard @antv/x6-plugin-history @antv/x6-plugin-keyboard @antv/x6-plugin-selection @antv/x6-plugin-snapline @antv/x6-plugin-stencil @antv/x6-plugin-transform insert-css

三、页面

html

c 复制代码
基础信息-6流程建模
<template>
  <div class="processBox">
    <!-- 流程图 -->
    <div id="container" style="min-width: 600px; min-height: 400px">
      <div id="stencil"></div>
      <div id="graph-container"></div>
    </div>
    <div class="saveBtn">
      <el-button type="info" size="mini" @click="graphSave()">保存</el-button>
      <el-button type="danger" size="mini" @click="graphClear()">清空</el-button>
    </div>
  </div>
</template>

js

c 复制代码
<script >
import { mapGetters } from "vuex";
import { Graph, Shape, Addon, DataUri } from "@antv/x6";
import { Stencil } from "@antv/x6-plugin-stencil";
import { Transform } from "@antv/x6-plugin-transform";
import { Selection } from "@antv/x6-plugin-selection";
import { Snapline } from "@antv/x6-plugin-snapline";
import { Keyboard } from "@antv/x6-plugin-keyboard";
import { Clipboard } from "@antv/x6-plugin-clipboard";
import { History } from "@antv/x6-plugin-history";
import insertCss from "insert-css";
import graphTest from "@/assets/json/graphTest";
import {
  companySearch,
  processModelSearch,
  processModelSave,
  treeList,
  equipmentPaging,
} from "@/api/processModel";
import {
  graphOptions,
  ports,
  SETTING_SHAPE_NAME,
  SettingNodeOptions,
  colors,
} from "@/views/basicInformation/ProcessModeling/config";
let graph = null;
let dnd = null;
let selector = null;
export default {
  name: "ProcessLibrary",
  components: {},
  data() {
    return {
      silkData: [],
      tobaccoData: [],
      stemData: [],
      smokeData: [],
      equipmentData: [],
      companyOptions: [],
      companyId: "",
      graphId: "",
      description: "",
      data: {},//渲染数据
      saveData: [],//保存数据
    };
  }, 
  watch: {
    data: {
      deep: true,
      immediate: true,
      handler(oldVal, newVal) {
        if (newVal) {
          graph.fromJSON(this.data);//渲染数据
        }
      },
    },
  },
  mounted() {
    this.getTreeList();
    this.companySearch();
    setTimeout(() => {
      this.initGraph();
    }, 500);
  },
  beforeDestroy() {
    // 画布的销毁以及回收
    graph && graph.dispose();
    graph = null;
    dnd = null;
    selector = null;
  },
  methods: {
    //建模树
    getTreeList() {},  
    //初始化
    initGraph() {
      graph = new Graph({
        container: document.getElementById("graph-container"),
        //画布背景
        background: {
          color: "#F2F7FA",
        },
        grid: true,
        // 滚动
        scroller: {
          enabled: true,
          pageVisible: false, // 是否分页
          pageBreak: false,
          pannable: true, // 是否平移
        },
        //滚轮缩放
        mousewheel: {
          enabled: true,
          zoomAtMousePosition: true,
          //   modifiers: "ctrl",
          //   minScale: 0.5,
          //   maxScale: 3,

          modifiers: ["ctrl", "meta"],
          maxScale: 3,
          minScale: 0.3,
        },
        //连接线
        connecting: {
          router: "manhattan",
          connector: {
            name: "rounded",
            args: {
              radius: 8,
            },
          },
          anchor: "center",
          connectionPoint: "anchor",
          allowBlank: false,
          snap: {
            radius: 20,
          },
          createEdge() {
            return new Shape.Edge({
              attrs: {
                line: {
                  stroke: "#A2B1C3",
                  strokeWidth: 2,
                  targetMarker: {
                    name: "block",
                    width: 12,
                    height: 8,
                  },
                },
              },
              zIndex: 0,
            });
          },
          validateConnection({ targetMagnet }) {
            return !!targetMagnet;
          },
        },
        //连接桩样式
        highlighting: {
          magnetAdsorbed: {
            name: "stroke",
            args: {
              attrs: {
                fill: "#5F95FF",
                stroke: "#5F95FF",
              },
            },
          },
        },
      });
      // 使用插件
      graph
        .use(
          //变换
          new Transform({
            resizing: true, //调整大小
            rotating: true, //旋转角度
          })
        )
        .use(
          //框选
          new Selection({
            rubberband: true,
            showNodeSelectionBox: true,
          })
        )
        .use(new Snapline()) //对齐线
        .use(new Keyboard()) //快捷键
        .use(new Clipboard()) //复制粘贴
        .use(new History()); //撤销

      // 链接桩配置
      const ports = {
        groups: {
          top: {
            position: "top",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          right: {
            position: "right",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          bottom: {
            position: "bottom",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          left: {
            position: "left",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
        },
        items: [
          {
            group: "top",
          },
          {
            group: "right",
          },
          {
            group: "bottom",
          },
          {
            group: "left",
          },
        ],
      };
      //矩形设置
      Graph.registerNode(
        "custom-rect",
        {
          inherit: "rect",
          width: 72,
          height: 36,
          attrs: {
            body: {
              strokeWidth: 1,
              stroke: "#5F95FF",
              fill: "#EFF4FF",
            },
            text: {
              fontSize: 12,
              fill: "#262626",
            },
          },
          ports: { ...ports },
        },
        true
      );
      //设备矩形设置
      Graph.registerNode(
        "dev-rect",
        {
          inherit: "rect",
          width: 230,
          height: 36,
          attrs: {
            body: {
              strokeWidth: 1,
              stroke: "#5F95FF",
              fill: "#EFF4FF",
            },
            text: {
              fontSize: 12,
              fill: "#262626",
            },
          },
          ports: { ...ports },
        },
        true
      );
      //圆形设置
      Graph.registerNode(
        "custom-circle",
        {
          inherit: "circle",
          width: 45,
          height: 45,
          attrs: {
            body: {
              strokeWidth: 1,
              stroke: "#5F95FF",
              fill: "#EFF4FF",
              overflow: "hidden",
              whiteSpace: "nowrap",
              textOverflow: "ellipsis",
            },
            text: {
              fontSize: 12,
              fill: "#262626",
            },
          },
          ports: { ...ports },
        },
        true
      );
      // 初始化左侧
      this.graphNode();
      // 快捷键
      this.initEvent();
    },
    //左侧数据
    graphNode() {
      const stencil = new Stencil({
        title: "组件",
        target: graph,
        search: false,
        collapsable: true,
        stencilGraphWidth: 280,
        stencilGraphHeight: 180,
        //左侧标题
        groups: [
          {
            title: "..工艺",
            name: "group1",
            graphHeight: 140,
          },
          {
            title: "丝1",
            name: "group2",
            graphHeight: 420,
          },
          {
            title: "丝2",
            name: "group3",
            graphHeight: 300,
          },
          {
            title: "丝3",
            name: "group4",
            graphHeight: 150,
          },
          {
            title: "设备区",
            name: "group5",
            graphHeight: 600,
            layoutOptions: {
              columns: 1,
              columnWidth: 230,
            },
          },
        ],
        layoutOptions: {
          columns: 3,
          columnWidth: 80,
          rowHeight: 55,
        },
      });
      document.getElementById("stencil").appendChild(stencil.container);
      // 数据
      const rectNodes1 = this.silkData.map((item) =>
        graph.createNode({
          shape: "custom-rect",
          label: item.name,
          attrs: {
            body: {
              rx: 6,
              ry: 6,
            },
          },
        })
      );
      stencil.load(rectNodes1, "group1");  
      ...
      // 设备区数据
      const imageNodes = this.equipmentData.map((item) =>
        graph.createNode({
          shape: "dev-rect",
          label: item.name,
          attrs: {
            body: {
              rx: 6,
              ry: 6,
            },
          },
        })
      );
      stencil.load(imageNodes, "group5");
    },
    //快捷键与事件
    initEvent() {
      // 点击...
      graph.on("cell:click", (e) => {
        this.menuVisible = false;
        const { node } = e;
        const data = node.getData();
        console.log(data);
      });

      // Edge工具
      graph.on("cell:mouseenter", ({ cell }) => {
        if (cell.isEdge()) {
          cell.addTools([
            {
              name: "button-remove",
              args: {
                x: "30%",
                y: "50%",
              },
            },
          ]);
        }
      });
      graph.on("cell:mouseleave", ({ cell }) => {
        if (cell.isEdge()) {
          cell.removeTool("button-remove");
        }
      });

      // copy cut paste
      graph.bindKey(["meta+c", "ctrl+c"], () => {
        const cells = graph.getSelectedCells();
        if (cells.length) {
          graph.copy(cells);
        }
        return false;
      });
      graph.bindKey(["meta+x", "ctrl+x"], () => {
        const cells = graph.getSelectedCells();
        if (cells.length) {
          graph.cut(cells);
        }
        return false;
      });
      graph.bindKey(["meta+v", "ctrl+v"], () => {
        if (!graph.isClipboardEmpty()) {
          const cells = graph.paste({ offset: 32 });
          graph.cleanSelection();
          graph.select(cells);
        }
        return false;
      });

      //undo redo
      graph.bindKey(["meta+z", "ctrl+z"], () => {
        if (graph.history.canUndo()) {
          graph.history.undo();
        }
        return false;
      });
      graph.bindKey(["meta+shift+z", "ctrl+shift+z"], () => {
        if (graph.history.canRedo()) {
          graph.history.redo();
        }
        return false;
      });

      // select all
      graph.bindKey(["meta+shift+a", "ctrl+shift+a"], () => {
        const nodes = graph.getNodes();
        if (nodes) {
          graph.select(nodes);
        }
      });

      // delete
      graph.bindKey(["backspace", "delete"], () => {
        // 删除选中的元素
        const cells = graph.getSelectedCells();
        if (cells.length) {
          graph.removeCells(cells);
        }
      });

      // zoom
      graph.bindKey(["ctrl+1", "meta+1"], () => {
        const zoom = graph.zoom();
        if (zoom < 1.5) {
          graph.zoom(0.1);
        }
      });
      graph.bindKey(["ctrl+2", "meta+2"], () => {
        const zoom = graph.zoom();
        if (zoom > 0.5) {
          graph.zoom(-0.1);
        }
      });

      // 链接桩控制
      const showPorts = (ports, show) => {
        for (let i = 0, len = ports.length; i < len; i += 1) {
          ports[i].style.visibility = show ? "visible" : "hidden";
        }
      };
      graph.on("node:mouseenter", () => {
        const container = document.getElementById("graph-container");
        const ports = container.querySelectorAll(".x6-port-body");
        showPorts(ports, true);
      });
      graph.on("node:mouseleave", () => {
        const container = document.getElementById("graph-container");
        const ports = container.querySelectorAll(".x6-port-body");
        // if (this.isPortsShow) return
        showPorts(ports, false);
      });
    }, 
    //保存
    graphSave() {
      this.saveData = graph.toJSON();
      const saveDataTrans = JSON.stringify(this.saveData); 
    },
    //清空
    graphClear() {
      graph.clearCells();
    },
  },
};
</script> 

解决参考:

1.文档实例:https://blog.csdn.net/qq_30940855/article/details/132673446

2.代码实例:https://xiaoka2017.gitee.io/easy-flow/#?_blank

3.功能齐全:https://blog.csdn.net/asscas/article/details/132339707

4.事件总结:https://www.jianshu.com/p/5527f7ed2ed9

5.可预览及源代码:https://it.cha138.com/javascript/show-3623284.html

6.官方/自定义树拖拽:https://blog.csdn.net/qq_43156442/article/details/130991471

7.完整流程,初始配置 https://codeantenna.com/a/XiVq3k2WoO

相关推荐
非科班Java出身GISer3 天前
ArcGIS JS 基础教程(48):SceneView watch 状态监听
arcgis·arcgis js基础·arcgis js入门·arcgis js监听状态·arcgis js监听事件·arcgis js 监听飞行·arcgis js 监听功能
斯普信专业组4 天前
Kafka 消费者 poll() 流程与原理详解
kafka·流程图
JudithHuang5 天前
React 嵌套路由与布局
前端·react.js·arcgis·react·react router
Dxy12393102166 天前
JS DES 加密详解
开发语言·javascript·arcgis
非科班Java出身GISer9 天前
ArcGIS JS 基础教程(46):编辑要素属性 FeatureForm
arcgis·arcgis js编辑要素·arcgis js 要素·arcgis js要素属性·arcgis js 编辑属性·arcgis js编辑要素属性
学IT的周星星10 天前
LangGraph:用「流程图」的方式编排 Agent
数据库·人工智能·大模型·llm·流程图·agent
梅如你10 天前
ISPRS | 1990-2020年间中国人工林与天然林的空间分布数据
arcgis·gis·遥感
钛生智能10 天前
OA 流程定制全参数详解(十):画流程图与美化——从“能跑”到“好看”的最后一公里
流程图·办公自动化·oa·协同办公·oa办公系统
limit007513 天前
公开 WMTS / XYZ 瓦片接入 Cesium:6 类常见问题与排查顺序
chrome·低代码·arcgis·web3·旅游
ixiaoyang814 天前
ioDraw v3.7.0 发布:AI 助手完成会话化改造,图表生成一次升级
ai·流程图·甘特图·思维导图·绘图软件·1024程序员节·mermaid