一、什么是Mxgraph
mxgraph是一个前端流程图绘制工具。mxGraph支持拖动、复制图元、重新调整大小、重新构造,连接和断开,从外部源的拖放和删除,编辑图元 标签中的位置等。我这里学习mxgraph主要是利用拖拽来生成后台流程。
二、如果使用
1、在vue中引入
在控制台执行命令:npm install mxgraph
2.1 vue html部分
<!-- 定义一个画布容器-->
<div id="graphContainer"></div>
<!-- 定义一个缩略图导航器 -->
<div id="graphOutline"/>
<!-- 定义左侧栏图标 -->
<h4>元素</h4>
<div v-for="item in image" style="display: flex;align-items: center;">
<img class="element-img" :id="item.id" :name="item.name" :src="gtImgUrl(item.icon)" :nodeName="item.nodeName" style="width: 30px;hight: 30px;">
<span style="font-size:20px;">
{{item.name}}
</span>
</div>
</div>
2.2 js部分
2.2.1 创建画布容器并初始化设置
// 创建一个画布容器
mkGraphContainer() {
// 在容器中创建图表
let container = document.getElementById("graphContainer");
this.graph = new mxGraph(container);
// 创建缩略图
this.outline = new mxOutline(this.graph, document.getElementById('graphOutline'));
this.graph.getModel().beginUpdate();
// 定义布局算法
this.layOut = new mxHierarchicalLayout(this.graph);
// 禁止在mxgraph图中使用鼠标右键
mxEvent.disableContextMenu(document.getElementById("graphContainer"));
// 设置节点可连接
this.graph.setConnectable(true);
this.graph.setTooltips(true);
this.graph.setAllowDanglingEdges(false);
this.graph.setMultigraph(false);
this.graph.getView().updateStyle = true;
// 允许调整线条弯曲度
this.graph.setCellsBendable(true);
2.2.2 添加左侧拖拽图标
dragOutImg(sourceEles, graph) {
const dropValidate = function (evt) {
const x = mxEvent.getClientX(evt);
const y = mxEvent.getClientY(evt);
// 获取 x,y 所在的元素
const elt = document.elementFromPoint(x, y);
// 如果鼠标落在graph容器
if (mxUtils.isAncestorNode(graph.container, elt)) {
return graph;
// 鼠标落在其他地方
return null;
// drop成功后新建一个节点
const dropSuccessCb = function (_graph, evt, target, x, y) {
var img = this.element.getAttribute('src');
var name = this.element.getAttribute('name');
var id = this.element.getAttribute('id');
var nodeName = this.element.getAttribute('nodeName');
// 定义节点的样式。
var nodeStyle = {};
// 形状
//nodeStyle[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CYLINDER;
nodeStyle[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_LABEL; // 背景图片只有在长方形形状才会展示
// 周长
nodeStyle[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
// 对齐方式
nodeStyle[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
// 垂直对齐
nodeStyle[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
nodeStyle[mxConstants.STYLE_GRADIENTCOLOR] = '#41B9F5';
// 填充色
nodeStyle[mxConstants.STYLE_FILLCOLOR] = '#8CCDF5';
// 连接线颜色
nodeStyle[mxConstants.STYLE_STROKECOLOR] = '#1B78C8';
nodeStyle[mxConstants.STYLE_FONTCOLOR] = '#000000';
nodeStyle[mxConstants.STYLE_ROUNDED] = true;
// 阴影效果
nodeStyle[mxConstants.STYLE_SHADOW] = true;
// 透明度
nodeStyle[mxConstants.STYLE_OPACITY] = '80';
// 中间字体的大小 例如:鼠标双击输入
nodeStyle[mxConstants.STYLE_FONTSIZE] = '12';
// 字体样式(斜体、下划线、中划线等)
nodeStyle[mxConstants.STYLE_FONTSTYLE] = 0;
// 设置背景图片
//nodeStyle[mxConstants.STYLE_IMAGE]= 'src/assets/mysql.png';
nodeStyle[mxConstants.STYLE_IMAGE] = img;
nodeStyle[mxConstants.STYLE_IMAGE_WIDTH] = '32';
nodeStyle[mxConstants.STYLE_IMAGE_HEIGHT] = '32';
nodeStyle[mxConstants.STYLE_SPACING_TOP] = '2';
nodeStyle[mxConstants.STYLE_SPACING_LEFT] = '50';
nodeStyle[mxConstants.STYLE_SPACING] = '8';
graph.getStylesheet().putCellStyle("nodeStyle", nodeStyle);
//const cell = new mxCell('鼠标双击输入', new mxGeometry(0, 0, 150, 135),'nodeStyle');
const cell = new mxCell(name, new mxGeometry(0, 0, 150, 35),'nodeStyle');
//const cell = new mxCell('鼠标双击输入', new mxGeometry(0, 0, 150, 35),'nodeStyle');
//const cell = new mxCell('鼠标双击', new mxGeometry(0, 0, 150, 35), 'nodeStyle');
cell.vertex = true;
// 自定义数据,将后端需要的数据封装到该节点中。
cell.data = {
name:name,
id:id,
nodeName: nodeName,
fullPath: '',
context: '',
operation: '',
pass: 'true'
// 鼠标落在哪里,节点就停在哪里
const cells = graph.importCells([cell], x, y, target);
if (cells != null && cells.length > 0) {
graph.setSelectionCells(cells);
// 设置连接线条的样式,如果不设置默认是斜线连接。
var edgeStyle = graph.getStylesheet().getDefaultEdgeStyle();
edgeStyle[mxConstants.STYLE_EDGE] = 'orthogonalEdgeStyle';
mxGraphHandler.prototype.guidesEnabled = true;
Array.from(sourceEles).forEach((ele) => {
// 拖拽时的虚影
const dragElt = document.createElement('img');
dragElt.setAttribute('src', ele.getAttribute('src'));
// 拖拽虚影的大小
dragElt.setAttribute('style', 'width:50px;height:50px;');
mxUtils.makeDraggable(ele, dropValidate, dropSuccessCb, dragElt,
null, null, null, true);
三、最终效果
代码中只列出了关键的代码,省略了部分。
目前遇到的问题:如何将xml导出,然后再回显回来?目前测试下来,总是会提示节点Id冲突。还在想办法解决中。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第1天,点击查看活动详情