(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

相关推荐
杨超越luckly1 小时前
HTML应用指南:利用GET请求获取全国中国建设银行网点位置信息
前端·arcgis·html·数据可视化·门店数据
你们瞎搞3 小时前
arcgis矢量数据转为标准geojson格式
python·arcgis·json·地理空间数据
新中地GIS开发老师14 小时前
Cesium 军事标绘入门:用 Cesium-Plot-JS 快速实现标绘功能
前端·javascript·arcgis·cesium·gis开发·地理信息科学
清欢ysy1 天前
Cannot find module ‘@next/bundle-analyzer‘
开发语言·javascript·arcgis
jerryinwuhan2 天前
arcgis如何将一部分shp地图截取下来并处理成networkx格式
arcgis
细节控菜鸡5 天前
【2025最新】ArcGIS for JS 实现地图卷帘效果
开发语言·javascript·arcgis
细节控菜鸡6 天前
【2025最新】ArcGIS for JS 实现地图卷帘效果,动态修改参数(进阶版)
开发语言·javascript·arcgis
GIS阵地6 天前
CSV转换为QGIS的简单分类符号
arcgis·二次开发·qgis·地理信息系统·pyqgis
角砾岩队长7 天前
基于ArcGIS实现Shapefile转KML并保留标注
arcgis
细节控菜鸡7 天前
【2025最新】ArcGIS for JS二维底图与三维地图的切换
javascript·arcgis