(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

基础信息-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

<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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/272148.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

海云安亮相2023北京国际金融安全论坛,助力金融企业数字化转型降本增效

近日&#xff0c;2023北京国际金融安全论坛暨金融科技标准认证生态大会在北京金融安全产业园成功举办。深圳海云安网络安全技术有限公司&#xff08;以下简称“海云安”&#xff09;受邀参展亮相此次大会。海云安作为国内领先的金融科技服务商&#xff0c;展示了开发安全系列产…

数据结构:图文详解 树与二叉树(树与二叉树的概念和性质,存储,遍历)

目录 一.树的概念 二.树中重要的概念 三.二叉树的概念 满二叉树 完全二叉树 四.二叉树的性质 五.二叉树的存储 六.二叉树的遍历 前序遍历 中序遍历 后序遍历 一.树的概念 树是一种非线性数据结构&#xff0c;它由节点和边组成。树的每个节点可以有零个或多个子节点…

输入两个时间,判断时间是否为非工作日,并且是日期否为同一天。是的话返回true,否返回false

工作遇到这么一个逻辑&#xff0c;前端回传两个时间&#xff08;必须是两个那一种&#xff09;。然后&#xff0c;我后端需要判断这两个时间是否为同一天&#xff0c;并且这个时间是否为非工作日&#xff0c;是的话返回true&#xff0c;反之返回false 代码&#xff1a; packa…

2023/12/26 work

1. 定义自己的命名空间myspace&#xff0c;并在myspace中定义一个字符串&#xff0c;实现求字符串大小的函数。 #include <iostream>using namespace std;namespace mynamespace {string name;unsigned int strlen(string name){return name.size();} }using namespace…

面试题之二HTTP和RPC的区别?

面试题之二 HTTP和RPC的区别&#xff1f; Ask范围&#xff1a;分布式和微服务 难度指数&#xff1a;4星 考察频率&#xff1a;70-80% 开发年限&#xff1a;3年左右 从三个方面来回答该问题&#xff1a; 一.功能特性 1)HTTP是属于应用层的协议&#xff1a;超文本传输协议…

手机蓝牙在物联网超市中的应用

超市一站式购物已进入城市的千家万户。然而人们在选购时却采用直接翻阅商品的方式&#xff0c;既不方便又不卫生甚至大大缩短食品类商品保质期&#xff0c;也给超市商品管理造成很大难度。物联网(The Internet of things)基于射频识别(RFID)、红外感应等技术&#xff0c;把物品…

【PostGIS】在Java中操作postgis——使用springboot+Maven+mybatis框架

前言&#xff1a; PostgreSQL15对应PostGIS安装教程及空间数据可视化 空间数据库-常用空间函数 完成PostGIS的安装与配置后&#xff0c;让我们来写一个Java操作postgis数据库的demo吧~ 使用工具&#xff1a; NavicatIDEA 一、PostGIS数据库准备 在Navicat中新建一个postgr…

云渲染UE4像素流送搭建(winows、ubuntu单实例与多实例像素流送)

windows/ubuntu20.4下UE4.27.2像素流送 像素流送技术可以将服务器端打包的虚幻引擎应用程序在客户端的浏览器上运行&#xff0c;用户可以通过浏览器操作虚幻引擎应用程序&#xff0c;客户端无需下载虚幻引擎&#xff0c;本文实现两台机器通过物理介质网线实现虚幻引擎应用程序…

Golang 协程配合管道

请完成goroutine和channel协同工作的案例&#xff0c;具体要求&#xff1a; &#xff08;1&#xff09;开启一个writeData协程&#xff0c;向管道mtChan中写入50个整数. &#xff08;2&#xff09;开启一个readData协程&#xff0c;从管道intChan中读取writeData写入的数据。 &…

系列十(实战)、发送 接收批量消息(Java操作RocketMQ)

一、发送 & 接收批量消息 1.1、概述 批量消息是指RocketMQ可以把一组消息集合一次性发送&#xff0c;这一组消息会被当做一个消息供消费者消费。 1.2、Demo05MQTestApp /*** Author : 一叶浮萍归大海* Date: 2023/12/25 11:48* Description: 发送 & 接收批量消息*/ …

智能优化算法应用:基于袋獾算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于袋獾算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于袋獾算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.袋獾算法4.实验参数设定5.算法结果6.参考文献7.MA…

python CodeFormer 图像(人脸面部)修复源码

介绍 github地址&#xff1a;https://github.com/sczhou/CodeFormer [NeurIPS 2022] Towards Robust Blind Face Restoration with Codebook Lookup Transformer 效果&#xff1a; 测试环境&#xff1a; anconda3python3.8 torch1.9.0cu111 pyqt5 部分代码&#xff1a; i…

记一次应急响应练习(windows)

记一次应急响应练习&#xff08;windows&#xff09; windows&#xff1a; 1.请提交攻击者攻击成功的第一时间&#xff0c;格式&#xff1a;YY:MM:DD hh:mm:ss 答&#xff1a;2023/04/29:22:44:32 思路&#xff1a; 看见桌面的小皮面板&#xff0c;进入小皮的安装目录。发现…

nodejs进阶

文章目录 写在前面一、dependencies、devDependencies和peerDependencies区别&#xff1a;二、需要牢记的npm命令2.1 npm init2.2 npm config list2.3 npm配置镜像源 三、npm install 的原理四、package-lock.json的作用五、npm run 的原理六、npx6.1 npx是什么6.2 npx的优势6.…

一个卖美妆的 一个月招了数十万代理!月销售额破亿 你敢相信吗?

商业模式永不过时 大家好&#xff0c;我是吴军&#xff0c;一家软件公司的产品经理 今天我们来聊一下这个纪炫商城 其实&#xff0c;说这个纪炫商城之前&#xff0c;我想跟各位企业家老板聊几句实在话 作为公司两百多号技术的&#xff0c;一个拥有五年软件开发经验的产品经理…

深入探讨Java反射:解析机制与应用场景

当谈及Java编程语言的强大功能时&#xff0c;反射&#xff08;Reflection&#xff09;是一个不可忽视的特性。反射允许程序在运行时检查和操作其自身的结构&#xff0c;这为开发者提供了一种动态获取信息和执行操作的途径。在本篇博客中&#xff0c;我们将深入探讨Java反射的原…

分支限界法求解01背包(优先队列)【java】

实验内容&#xff1a;运用分支限界法解决0-1背包问题 实验目的&#xff1a;分支限界法按广度优先策略遍历问题的解空间树&#xff0c;在遍历过程中,对已经处理的每一个结点根据限界函数估算目标函数的可能取值&#xff0c;从中选取使目标函数取得极值的结点优先进行广度忧先搜…

day42 1226

作业1&#xff1a; #include <iostream>using namespace std;namespace myspace {string str; }int length(string str) {//char *p &str.at(0);const char *p str.data();int count 0;while (*p ! 0) {p;count;}return count; } int main() {getline(cin,myspac…

元素隐式具有 “any“ 类型,因为类型为 “string“ 的表达式不能用于索引类型 “typeof

报错展示 解决办法 Object.keys(directives).forEach(k > {app.directive(k, directives[k as keyof typeof directives]) })