上文我们介绍了,mxgraph如何在页面不刷新的情况下,通过请求不同文件生成不同的mxgraph图,本文我们将讲述mxgraph手动添加节点和边,并且按照原本数据格式导出数据。

1.准备工作

在这里插入图片描述

  • 准备工作代码
<template>
  <div>
    <div class="Oinput">
      <input type="text" placeholder="请输入对应的城市名称......" />
      <button>生成节点</button>
      <button>保存数据</button>
    </div>
    <div id="graphContainer"></div>
  </div>
</template>

<script>
import mxgraph from "./mxgraph";
const {
  mxGraph,
  mxClient,
  mxCodec,
  mxUtils,
  mxConstants,
  mxPerimeter,
  mxHierarchicalLayout,
  mxCompactTreeLayout,
} = mxgraph;

export default {
  data() {
    return {
      v_graph: "",
      v_parent: "",
    };
  },

  methods: {
    mxGraph() {
      if (!mxClient.isBrowserSupported()) {
        // 判断是否支持mxgraph
        mxUtils.error("Browser is not supported!", 200, false);
      } else {
        // 在容器中创建图表
        let container = document.getElementById("graphContainer");

        var graph = new mxGraph(container);
        var parent = graph.getDefaultParent();
        this.v_graph = graph;
        this.v_parent = parent;

        graph.getModel().beginUpdate();

        var layout = new mxHierarchicalLayout(graph);

        try {
          layout.execute(parent);
        } finally {
          // Updates the display
          graph.getModel().endUpdate();
        }
      }
    },
  },

  mounted() {
    this.mxGraph();
  },
};
</script>
<style>
#graphContainer {
  width: 1000px;
  height: 700px;
  border: 3px solid rgb(194, 185, 185);
  background-image: url("../assets/grid.gif");
  margin: auto;
  box-sizing: border-box;
  padding: 100px 0 0 250px;
}

.Oinput {
  width: 1000px;
  height: 100px;
  margin: auto;
  border: 3px solid rgb(194, 185, 185);
  text-align: center;
  line-height: 100px;
  box-sizing: border-box;
}

input {
  width: 400px;
  height: 40px;
  box-sizing: border-box;
  font-size: 17px;
}

button {
  width: 100px;
  height: 40px;
  box-sizing: border-box;
  margin-right: 20px;
}
</style>

在这里插入图片描述
准备工作完成。

2.需求分析

input中输入城市名,生成节点。在mxgraph中完成城市交通图。

  • 使用v-model获取input输入数据
<input v-model="v_text" type="text" placeholder="请输入对应的城市名称......" />
      <button @click="createNewNode(v_graph,v_parent)">生成节点</button>
      <button>保存数据</button>
  • 生成节点,最后将input赋值为空
/**
     * 生成节点函数
     */
    createNewNode(graph,parent) {
      let text = this.v_text;
      let id = `node${this.v_id ++ }`;
      var node = graph.insertVertex(
        parent,
        id,
        text,
        0,
        0,
        150,
        40,
        "fillColor=#3CAEA3;strokeColor=white;fontStyle=1;fontColor=white;rounded=1;fontSize=15;"
      );

      this.v_text = '';
    },
  • 点击生成节点成功
    在这里插入图片描述

3,生成多个节点连接成为流程图

  • 设置节点可连接,同时避免无效连线
//设置节点可连接
        graph.setConnectable(true);
		graph.setTooltips(true);
		graph.setAllowDanglingEdges(false);
		graph.setMultigraph(false);
  • 双击连接线 即可编辑 label
    在这里插入图片描述

4.节点和连线点击事件

  • 第一步在mxgraph容器内步 禁用鼠标右键
//禁止在mxgraph图中使用鼠标右键
        mxEvent.disableContextMenu(document.getElementById("graphContainer"));
  • 第二步:重写鼠标事件
 graph.popupMenuHandler.factoryMethod = function (menu, cell, evt) {
          // 判断是节点还是边

          if(cell){
            //对于节点而言,它的target以及source均为null
          if(cell.source){
            alert('当前选中是边:' + cell.value)
            //进行其他操作
          }else{
            alert('当前选中是节点:' + cell.value)
            //进行其他操作
          }
          }

          
        }

效果演示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.所有代码

<template>
  <div>
    <div class="Oinput">
      <input v-model="v_text" type="text" placeholder="请输入对应的城市名称......" />
      <button @click="createNewNode(v_graph,v_parent)">生成节点</button>
      <button>保存数据</button>
    </div>
    <div id="graphContainer"></div>
  </div>
</template>

<script>
import mxgraph from "./mxgraph";
const {
  mxGraph,
  mxClient,
  mxCodec,
  mxUtils,
  mxEvent,
  mxConstants,
  mxPerimeter,
  mxHierarchicalLayout,
  mxCompactTreeLayout,
} = mxgraph;

export default {
  data() {
    return {
      v_graph: "",
      v_parent: "",
      v_text: "",
      v_id: 0,
    };
  },

  methods: {
    /**
     * 生成节点函数
     */
    createNewNode(graph, parent) {
      let text = this.v_text;
      let id = `node${this.v_id ++ }`;
      var node = graph.insertVertex(
        parent,
        id,
        text,
        0,
        0,
        150,
        40,
        "fillColor=#3CAEA3;strokeColor=white;fontStyle=1;fontColor=white;rounded=1;fontSize=15;"
      );

      this.v_text = "";
    },

    mxGraph() {
      if (!mxClient.isBrowserSupported()) {
        // 判断是否支持mxgraph
        mxUtils.error("Browser is not supported!", 200, false);
      } else {
        // 在容器中创建图表
        let container = document.getElementById("graphContainer");

        //禁止在mxgraph图中使用鼠标右键
        mxEvent.disableContextMenu(document.getElementById("graphContainer"));
        var graph = new mxGraph(container);
        //设置节点可连接
        graph.setConnectable(true);
        graph.setTooltips(true);
        graph.setAllowDanglingEdges(false);
        graph.setMultigraph(false);
        var parent = graph.getDefaultParent();
        this.v_graph = graph;
        this.v_parent = parent;

        graph.getModel().beginUpdate();

        var layout = new mxHierarchicalLayout(graph);

        try {
          layout.execute(parent);
        } finally {
          // Updates the display
          graph.getModel().endUpdate();
        }

        //鼠标右键事件
        graph.popupMenuHandler.factoryMethod = function (menu, cell, evt) {
          // 判断是节点还是边

          if (cell) {
            //对于节点而言,它的target以及source均为null
            if (cell.source) {
              alert("当前选中是边:" + cell.value);
              //进行其他操作
            } else {
              alert("当前选中是节点:" + cell.value);
              //进行其他操作
            }
          }
        };
      }
    },
  },

  mounted() {
    this.mxGraph();
  },
};
</script>
<style>
#graphContainer {
  width: 1000px;
  height: 700px;
  border: 3px solid rgb(194, 185, 185);
  background-image: url("../assets/grid.gif");
  margin: auto;
  box-sizing: border-box;
}

.Oinput {
  width: 1000px;
  height: 100px;
  margin: auto;
  border: 3px solid rgb(194, 185, 185);
  text-align: center;
  line-height: 100px;
  box-sizing: border-box;
}

input {
  width: 400px;
  height: 40px;
  box-sizing: border-box;
  font-size: 17px;
}

button {
  width: 100px;
  height: 40px;
  box-sizing: border-box;
  margin-right: 20px;
}
</style>

6.按照要求数据格式导出图中数据

  • 要求数据格式
mxgraphData: [
		  {
			nodesList:[
			  [0,'Hello'],
			  [1,'Mxgraph']
			],
			edgesList:[
			  [0,'label',1]
			]
		  }
		],
  • 第一步:获取mxgraph容器内步所有子节点和边
    在这里插入图片描述
  • 获取图中数据
    在这里插入图片描述
DataPush(graph){
      // 获取mxgraph容器内步所有子节点和边
      console.log(graph.getModel().root.children[0].children)
    },
  • 处理数据
/**
     * 按照要求导出数据
     */
    DataPush(graph){
      var newMXgraphData = [
        {
          nodesList:[],
          edgesList:[]
        }
      ]
      // 获取mxgraph容器内步所有子节点和边
      var cellList = graph.getModel().root.children[0].children;
      // 处理数据:
      for(var i = 0 ; i < cellList.length; i++){
          // 区分节点和边
          if(cellList[i].source){
            // 是边
              var arr = [];
              //获取连接起点节点id
              var startId = Number(cellList[i].source.id.slice(4,5))
              var label = cellList[i].value;
              var endId = Number(cellList[i].target.id.slice(4,5))
              arr.push(startId)
              arr.push(label)
              arr.push(endId)
              newMXgraphData[0].edgesList.push(arr);
          }else{
            //是节点
            var arr = [];
            // 保存节点id
            var nodeId = Number(cellList[i].id.slice(4,5));
            var nodeValue = cellList[i].value;
            arr.push(nodeId)
            arr.push(nodeValue)
            newMXgraphData[0].nodesList.push(arr);
          }
      }
      console.log(newMXgraphData);
      return newMXgraphData;
    },

在这里插入图片描述

7.所有代码示例:

<template>
  <div>
    <div class="Oinput">
      <input v-model="v_text" type="text" placeholder="请输入对应的城市名称......" />
      <button @click="createNewNode(v_graph,v_parent)">生成节点</button>
      <button @click="DataPush(v_graph)">保存数据</button>
    </div>
    <div id="graphContainer"></div>
  </div>
</template>

<script>
import mxgraph from "./mxgraph";
const {
  mxGraph,
  mxClient,
  mxCodec,
  mxUtils,
  mxEvent,
  mxConstants,
  mxPerimeter,
  mxHierarchicalLayout,
  mxCompactTreeLayout,
} = mxgraph;

export default {
  data() {
    return {
      v_graph: "",
      v_parent: "",
      v_text: "",
      v_id: 0,
    };
  },

  methods: {
    /**
     * 生成节点函数
     */
    createNewNode(graph, parent) {
      let text = this.v_text;
      let id = `node${this.v_id ++ }`;
      var node = graph.insertVertex(
        parent,
        id,
        text,
        0,
        0,
        150,
        40,
        "fillColor=#3CAEA3;strokeColor=white;fontStyle=1;fontColor=white;rounded=1;fontSize=15;"
      );

      this.v_text = "";
    },

    /**
     * 按照要求导出数据
     */
    DataPush(graph){
      var newMXgraphData = [
        {
          nodesList:[],
          edgesList:[]
        }
      ]
      // 获取mxgraph容器内步所有子节点和边
      var cellList = graph.getModel().root.children[0].children;
      // 处理数据:
      for(var i = 0 ; i < cellList.length; i++){
          // 区分节点和边
          if(cellList[i].source){
            // 是边
              var arr = [];
              //获取连接起点节点id
              var startId = Number(cellList[i].source.id.slice(4,5))
              var label = cellList[i].value;
              var endId = Number(cellList[i].target.id.slice(4,5))
              arr.push(startId)
              arr.push(label)
              arr.push(endId)
              newMXgraphData[0].edgesList.push(arr);
          }else{
            //是节点
            var arr = [];
            // 保存节点id
            var nodeId = Number(cellList[i].id.slice(4,5));
            var nodeValue = cellList[i].value;
            arr.push(nodeId)
            arr.push(nodeValue)
            newMXgraphData[0].nodesList.push(arr);
          }
      }
      console.log(newMXgraphData);
      return newMXgraphData;
    },

    mxGraph() {
      if (!mxClient.isBrowserSupported()) {
        // 判断是否支持mxgraph
        mxUtils.error("Browser is not supported!", 200, false);
      } else {
        // 在容器中创建图表
        let container = document.getElementById("graphContainer");

        //禁止在mxgraph图中使用鼠标右键
        mxEvent.disableContextMenu(document.getElementById("graphContainer"));
        var graph = new mxGraph(container);
        //设置节点可连接
        graph.setConnectable(true);
        graph.setTooltips(true);
        graph.setAllowDanglingEdges(false);
        graph.setMultigraph(false);
        var parent = graph.getDefaultParent();
        this.v_graph = graph;
        this.v_parent = parent;

        graph.getModel().beginUpdate();

        var layout = new mxHierarchicalLayout(graph);

        try {
          layout.execute(parent);
        } finally {
          // Updates the display
          graph.getModel().endUpdate();
        }

        //鼠标右键事件
        graph.popupMenuHandler.factoryMethod = function (menu, cell, evt) {
          // 判断是节点还是边

          if (cell) {
            //对于节点而言,它的target以及source均为null
            if (cell.source) {
              alert("当前选中是边:" + cell.value);
              //进行其他操作
            } else {
              alert("当前选中是节点:" + cell.value);
              //进行其他操作
            }
          }
        };
      }
    },
  },

  mounted() {
    this.mxGraph();
  },
};
</script>
<style>
#graphContainer {
  width: 1000px;
  height: 700px;
  border: 3px solid rgb(194, 185, 185);
  background-image: url("../assets/grid.gif");
  margin: auto;
  box-sizing: border-box;
}

.Oinput {
  width: 1000px;
  height: 100px;
  margin: auto;
  border: 3px solid rgb(194, 185, 185);
  text-align: center;
  line-height: 100px;
  box-sizing: border-box;
}

input {
  width: 400px;
  height: 40px;
  box-sizing: border-box;
  font-size: 17px;
}

button {
  width: 100px;
  height: 40px;
  box-sizing: border-box;
  margin-right: 20px;
}
</style>

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐