vue项目中如何使用mxgraph进行可视化操作

最近公司需要使用mxgraph,来进行流程图的开发,由于我是第一次接触这个库,所以踩到的坑还是挺多,最坑爹的网上关于这个库的资料实在是太少了,它的文档还是英文文档。所以开发起来还是有点痛苦的。
我们来看下以下部分需求:
vue项目中如何使用mxgraph进行可视化操作_第1张图片
这是PM要我做的流程图,这里我会拿部份的功能和大家分享。包括新建图形,删除节点图形,响应右键菜单事件…由于mxgraph的套路是很固定的,只要你GET到这几个部分再结合文档,就基本没有问题了。

一.创建项目
通过vue-cli创建项目,这里就不多说了…,这是我生成的项目目录。我进行了一个项目目录的修改,大家也可以参考一下。
vue.config.js配置

module.exports = {
  publicPath: './',
  outputDir: 'dist',
  lintOnSave: true,
  chainWebpack: (config) => {
    config.module
      .rule('')
      .test(/mxClient\.js$/)
      .use('exports-loader')
      .loader('exports-loader?mxClient,mxToolbar,mxConnectionHandler,mxEllipse,mxConnectionConstraint,mxWindow,' +
        'mxObjectCodec,mxGraphModel,mxActor,mxPopupMenu,mxShape,mxEventObject,mxGraph,mxPopupMenuHandler,mxPrintPreview,' +
        'mxEventSource,mxRectangle,mxVertexHandler,mxMouseEvent,mxGraphView,mxCodecRegistry,mxImage,mxGeometry,' +
        'mxRubberband,mxConstraintHandler,mxKeyHandler,mxDragSource,mxGraphModel,mxEvent,mxUtils,mxEvent,mxCodec,mxCell,' +
        'mxConstants,mxPoint,mxGraphHandler,mxCylinder,mxCellRenderer,mxEvent,mxUndoManager')
      .end()
  }
}

package.json

{
  "name": "workinteresting",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-vue": "^2.0.2",
    "core-js": "^2.6.5",
    "eslint-plugin-flow-vars": "^0.5.0",
    "eslint-plugin-html": "^6.0.0",
    "node-sass": "^4.12.0",
    "popper.js": "^1.16.0",
    "sass-loader": "^7.3.1",
    "vue": "^2.6.10",
    "vue-router": "^3.0.3",
    "vuex": "^3.0.1",
    "mxgraph": "^3.9.12"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.11.0",
    "@vue/cli-plugin-eslint": "^3.11.0",
    "@vue/cli-service": "^3.11.0",
    "@vue/eslint-config-standard": "^4.0.0",
    "babel-eslint": "^10.0.3",
    "babel-preset-env": "^1.7.0",
    "babel-preset-stage-0": "^6.24.1",
    "eslint": "^5.16.0",
    "eslint-friendly-formatter": "^4.0.1",
    "eslint-loader": "^3.0.2",
    "eslint-plugin-vue": "^5.0.0",
    "node-sass": "^4.9.0",
    "sass-loader": "^7.1.0",
    "vue-template-compiler": "^2.6.10",
    "exports-loader": "^0.7.0",
    "script-loader": "^0.7.2"
  }
}

二.数据驱动生成图形
在项目开发的过程中,我使用了mxGraph踩了很多的坑,其中的一个大坑就是图形回显的问题,一开始我是采用官方推荐的xml形式,大致上就是前台生成一堆的xml,然后后台返回。这里的问题是什么呢?就是后台的小伙伴就会很繁琐,毕竟他们要从一大堆没有规律的xml抽取字段,然后写进数据库。所以,我就把数据格式修改为json格式,我个人认为这是使用mxGraph最为重要的一个东西。

首先我们就先约定好数据格式

graphData: [
        { type: "start", to: [], value: "hello", options: { x: 50, y: 120, width: 120, height: 60, style: "" } },
        { type: "end", to: [], value: "world", options: { x: 350, y: 120, width: 120, height: 60, style: "" } }
      ]

每一项的to作为一个数组,关联于它下面的一个节点,在Graph中:

createData () {
      this.parent = this.graph.getDefaultParent();
      this.graph.getModel().beginUpdate();
      console.log(this.graphData);
      try {
        for (let i = 0; i < this.graphData.length; i++) {
          let baseOptions = this.graphData[i].options;
          let type = this.graphData[i].type || "";
          let value = this.graphData[i].value || "";
          let id = this.graphData[i].id || null;
          let { x, y, width, height, style } = baseOptions;
          let verter = this.graph.insertVertex(this.parent, id, value, x, y, width, height, style || "");
          verter.type = type || "";
          this.graphData[i].id = this.graphData[i].id ? this.graphData[i].id : verter.id;
          this.graphData[i].to = this.graphData[i].to.length > 0 ? this.graphData[i].to : [];
        }
        let isHaveTo = this.graphData.some((v) => v.to.length > 0);
        const cells = this.graph.getChildVertices(this.graph.getDefaultParent()); // 所有的图形
        if (isHaveTo) {
          for (let i = 0; i < this.graphData.length; i++) {
            let arr = this.graphData[i].to;
            let source = this.findCell(this.graphData[i].id);
            if (arr instanceof Array && arr.length > 0) {
              for (let i = 0; i < arr.length; i++) {
                let target = this.findCell(arr[i]);
                if (!source || !target) {
                  return;
                }
                this.graph.insertEdge(this.parent, null, "", source, target);
              }
            }
          }
        }
        // console.log(cells);
        this.$emit("initCell", cells);
      } finally {
        this.graph.getModel().endUpdate();
      }
    },

那么,如果一切顺利的话,则会出现以下的画面:
vue项目中如何使用mxgraph进行可视化操作_第2张图片
这种做法,有些麻烦的是,图形的宽度,大小,位置等的改变都需要实时反馈到graphData中一项,所幸的是在mxgraph这个库中,提供了这些api,下次我则会集中写这些api的功能和作用,包括复制,粘贴,全选,右键等等功能。

三.组件链接
组件的github链接mxGraph组件
这个组件库是我平时工作时候,碰到一些有意思的组件,我都会记录下来,也欢迎各位朋友star。

你可能感兴趣的:(vue,mxGraph)