mxGraph介绍
一、简介
1、mxGraph是什么?
先放上官方的文档:
API:http://jgraph.github.io/mxgraph/docs/js-api/files/index-txt.html
Demo:http://jgraph.github.io/mxgraph/javascript/index.html
简单来说,mxGraph是一个JavaScript工具库,实现图形的可视化交互。mxGraph主要包含一个JavaScript文件,mxGraph的全部函数都在这个文件中。它需要被加载到一个浏览器的Web页面的Javascript中并执行在HTML容器中。它结构简单,只要一个web服务器来提供html页面和一个支持JavaScript的浏览器就可以了。
2、mxGraph有什么优点?
- 不需要第三方插件,纯js的工具库,兼容性非常好。
- 涉及到的技术都是开源的。
- 支持多种语言(Java、JavaScript、PHP、.NET),所绘制的图形可以在主流浏览器以及原生应用上使用。
- mxGraph默认绘制的是svg图形,所以支持后端语言进行预渲染,同时也支持保存和导出,转化为位图也非常方便。
3、mxGraph有什么缺点?
- API是全英文的。
- 组件默认的样式比较丑,需要自己优化样式。
4、mxGraph的使用场景有哪些?
官方给出的场景有四个:图形可视化、图形交互、图形布局、图形分析。比如:过程图、工作流和BPM的可视化图表、流程图、交通或水流量、 数据库可视化、网络和电信显示、映射应用和地理信息系统、UML图、电子线路、金融、 超大规模集成电路和社会网络、数据挖掘、生化、生态循环、实体和因果关系和组织图表。
- 图形可视化
图形可视化是mxGraph的主打功能,这个很好理解,就是把一些抽象的概念用图形来表示,比如常见的流程图、思维导图、实体关系图等。 需要注意的是mxGraph所绘制的图主要是由“点”(也包括矩形、圆形这类基本形状)和“边”组成的,下图是官方提供的一张样图。

- 图形交互
mxGraph除了绘制图形之外还提供了丰富的编辑功能,比如拖拽、选择、复制、调整大小等。 mxGraph甚至还专门提供了一个API类用来支持在线编辑器。

- 图形布局
非常重要的一个功能,能自动排列图形元素。 mxGraph提供了多种布局方式,比如树形布局、栈式布局、圆形布局。

- 图形分析
支持图相关的算法分析,比如找出图中两个节点的最短路径。

二、mxGraph使用
1、获取mxGraph包
mxGraph可以从github项目上下载:https://github.com/jgraph/mxgraph
2、导入项目中
从下载的文件中可以获得一系列的js文件,将js文件复制到项目中,在html中引用mxClient.js(mxClient.js会引用其他的工具类)


3、参考mxGraph的API进行开发()
- 新建第一个图形(点+线)
- 给画布增加一些辅助属性
- 自定义节点的样式
- 自定义布局
- 增加操作按钮
- 查看图形的xml
- 通过解析xml展示图形
- 添加右键事件
- 定义拖拽事件
附上源代码:
index.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>mxGraph</title> 6 <link href="css/index.css" rel="stylesheet"> 7 </head> 8 <body onload="main(document.getElementById('graphContainer'))"> 9 <!-- 操作按钮容器 --> 10 <div id="methods"> 11 <div id="buttons" style="height: 50px;"></div> 12 </div> 13 <!-- 拖拽组件 --> 14 <div id="drag"> 15 <span id="in1">表输入</span> 16 <span id="out1">表输出</span> 17 <span id="trans1">字符串替换</span> 18 <span id="scp1">执行存储过程</span> 19 </div> 20 <!-- 画布区域 --> 21 <div id="graphContainer"></div> 22 </body> 23 <script src="js/mxClient.js"></script> 24 <script src="js/index.js"></script> 25 </html>
index.js
1 var mxBasePath = '../mxgraph'; 2 function main(container) { 3 // 禁用鼠标右键 4 mxEvent.disableContextMenu(container); 5 6 var graph = new mxGraph(container); 7 // 设置这个属性后节点之间才可以连接 8 graph.setConnectable(true); 9 //开启节点不可改变大小 10 graph.setCellsResizable(false); 11 //边被拖时,始终保持连接 12 graph.setDisconnectOnMove(false); 13 //开启tooptip提示 14 graph.setTooltips(true); 15 // 启用对齐线帮助定位 16 mxGraphHandler.prototype.guidesEnabled = true; 17 // 设置启用,就是允不允许你改变CELL的形状内容 18 graph.setEnabled(true); 19 20 //定义节点样式 21 //API:https://jgraph.github.io/mxgraph/docs/js-api/files/util/mxConstants-js.html 22 var nodeStyle = {}; 23 nodeStyle[mxConstants.STYLE_FILLCOLOR] = "#3CAEA3"; 24 nodeStyle[mxConstants.STYLE_FONTSIZE] = 15; 25 nodeStyle[mxConstants.STYLE_STROKE_COLOR] = "white"; 26 nodeStyle[mxConstants.STYLE_FONTCOLOR] = "white"; 27 nodeStyle[mxConstants.STYLE_ROUNDED] = 1; 28 // 把定义好的样式object push到stylesheet 29 graph.getStylesheet().putCellStyle("nodeStyle", nodeStyle); 30 31 // 开启区域选择 32 new mxRubberband(graph); 33 const parent = graph.getDefaultParent(); 34 graph.getModel().beginUpdate(); 35 //定义布局(可以使用多种布局) 36 var layout = new mxEdgeLabelLayout(graph); 37 try { 38 /*insertVertex参数 39 **参数1:parents 生成节点要插入的父级容器 40 **参数2:null 此处可以设置节点的id,便于识别节点,null为默认id 41 **参数3:label 此处设置节点的内容 42 **参数4:设置节点大小及节点在父级容器中的相对位置*/ 43 const v1 = graph.insertVertex(parent, null, '起点,', 20, 20, 80, 30); 44 const v2 = graph.insertVertex(parent, null, '终点', 200, 150, 80, 30, 'nodeStyle'); 45 /*insertVertex参数 46 **参数1:parents 生成边要插入的父级容器 47 **参数2::null 此处可以设置节点的id,便于识别边,null为默认id 48 **参数3:label 此处设置节点的内容 49 **参数4:边的起始节点和终止节点*/ 50 const e1 = graph.insertEdge(parent, null, 'OK', v1, v2); 51 /* 52 var xml= 53 '<mxGraphModel>'+ 54 ' <root>'+ 55 ' <mxCell id="0" />'+ 56 ' <mxCell id="1" parent="0" />'+ 57 ' <mxCell id="2" value="起点," vertex="1" parent="1">'+ 58 ' <mxGeometry width="80" height="30" as="geometry" />'+ 59 ' </mxCell>'+ 60 ' <mxCell id="3" value="终点" style="nodeStyle" vertex="1" parent="1">'+ 61 ' <mxGeometry y="130" width="80" height="30" as="geometry" />'+ 62 ' </mxCell>'+ 63 ' <mxCell id="4" value="OK" style="noEdgeStyle=1;orthogonal=1;" edge="1" parent="1" source="2" target="3">'+ 64 ' <mxGeometry relative="1" as="geometry">'+ 65 ' <Array as="points">'+ 66 ' <mxPoint x="40" y="42" />'+ 67 ' <mxPoint x="40" y="118" />'+ 68 ' </Array>'+ 69 ' </mxGeometry>'+ 70 ' </mxCell>'+ 71 ' </root>'+ 72 '</mxGraphModel>'; 73 var doc = mxUtils.parseXml(xml); 74 var codec = new mxCodec(doc); 75 codec.decode(doc.documentElement, graph.getModel());*/ 76 layout.execute(parent); 77 } finally { 78 graph.getModel().endUpdate(); 79 } 80 81 /****************************定义操作按钮******************************/ 82 //选中所有 83 document.getElementById("buttons").appendChild( 84 mxUtils.button('选中所有', function() { 85 graph.selectAll() 86 }) 87 ) 88 89 //选择一个 90 document.getElementById("buttons").appendChild( 91 mxUtils.button('选择一个', function() { 92 graph.selectCell() 93 }) 94 ) 95 96 //取消选择 97 document.getElementById("buttons").appendChild( 98 mxUtils.button('取消选择', function() { 99 var cells = graph.getSelectionCells() 100 graph.removeSelectionCells(cells) 101 }) 102 ) 103 104 //删除所选 105 document.getElementById("buttons").appendChild( 106 mxUtils.button('删除所选', function() { 107 var cells = graph.getSelectionCells() 108 graph.removeCells(cells) 109 }) 110 ) 111 112 //放大节点 113 document.getElementById("buttons").appendChild( 114 mxUtils.button('放大节点', function() { 115 graph.zoomIn() 116 }) 117 ) 118 119 //缩小节点 120 document.getElementById("buttons").appendChild( 121 mxUtils.button('缩小节点', function() { 122 graph.zoomOut() 123 }) 124 ) 125 126 //还原节点 127 document.getElementById("buttons").appendChild( 128 mxUtils.button('还原节点', function() { 129 graph.zoomActual() 130 }) 131 ) 132 133 //清空画板 134 document.getElementById("buttons").appendChild( 135 mxUtils.button('清空画板', function() { 136 graph.removeCells(graph.getChildVertices(graph.getDefaultParent())) 137 }) 138 ) 139 140 //查看图形的xml 141 document.getElementById("buttons").appendChild(mxUtils.button('查看XML', function() 142 { 143 var encoder = new mxCodec(); 144 var node = encoder.encode(graph.getModel()); 145 mxUtils.popup(mxUtils.getPrettyXml(node), true); //以窗口的方式展示处理 146 })); 147 148 //添加右键事件 149 graph.popupMenuHandler.factoryMethod = function(menu, cell, evt) { 150 return createPopupMenu(graph, menu, cell, evt); 151 }; 152 153 createDragSource(graph); 154 } 155 156 //添加右键事件 157 function createPopupMenu(graph, menu, cell, evt){ 158 menu.addItem("删除步骤", "", function() { 159 var cells = graph.getSelectionCells(); 160 graph.removeCells(cells); 161 }); 162 } 163 164 //定义拖拽事件 165 function createDragSource(graph) { 166 var in1 = this.createDragImage( 167 graph, 168 "in1", 169 "./images/in.png", 170 "表输入" 171 ); 172 //创建输出拖动源 173 var out1 = this.createDragImage( 174 graph, 175 "out1", 176 "./images/out.png", 177 "表输出" 178 ); 179 //创建转换拖动源 180 var trans1 = this.createDragImage( 181 graph, 182 "trans1", 183 "./images/replace.png", 184 "字符串替换" 185 ); 186 //创建脚本拖动源 187 var scp1 = this.createDragImage( 188 graph, 189 "scp1", 190 "./images/sql.png", 191 "执行存储过程" 192 ); 193 } 194 195 //创建拖拽源 196 function createDragImage(graph, id, image, text) { 197 var img = mxUtils.createImage(image); 198 img.style.width = "30px"; 199 img.style.height = "30px"; 200 img.style.margin = "0px"; 201 document.getElementById(id).appendChild(img); 202 203 var style = this.getStyle(graph, image, id); 204 205 // 检查图形中是否包含对应的elt节点 206 function containsElt(graph, elt) { 207 while (elt != null) { 208 if (elt == graph.container) { 209 return true; 210 } 211 elt = elt.parentNode; 212 } 213 return false; 214 } 215 216 // 在给定的位置插入一个元素 217 var funct1 = function(graph, evt, target, x, y) { 218 var cell = new mxCell(text, new mxGeometry(0, 0, 50, 50), id); 219 cell.vertex = true; 220 var cells = graph.importCells([cell], x, y, target); //插入元素、位置、大小 221 }; 222 223 // 禁用IE浏览器中的DnD功能(这是为了跨浏览器平台而设计的,见下文) 224 if (mxClient.IS_IE) { 225 mxEvent.addListener(img, "dragstart", function(evt) { 226 evt.returnValue = false; 227 }); 228 } 229 230 // 创建拖动源的预览 231 var dragElt = document.createElement("div"); 232 dragElt.style.border = "dashed black 1px"; 233 dragElt.style.width = "120px"; 234 dragElt.style.height = "40px"; 235 236 // 在点击拖动源图标时提供预览。 预览是提供的仅仅是拖动源的图片 237 // 只有拖动源到容器内时才会显示元素的坐标预览 238 239 var ds = mxUtils.makeDraggable( 240 img, 241 graph, 242 funct1, 243 dragElt, 244 null, 245 null, 246 graph.autoscroll, 247 true 248 ); 249 250 //从拖动源拖动时显示导航线。 251 //注意,对图形中已存在的元素拖动时显示导航线不在本方法约束范围。 252 ds.isGuidesEnabled = function() { 253 return graph.graphHandler.guidesEnabled; 254 }; 255 256 //从拖动源拖动元素到图形以外的区域时,显示拖动源图片预览 257 ds.createDragElement = mxDragSource.prototype.createDragElement; 258 } 259 260 function getStyle(graph, url, styleName) { 261 // 声明一个object 262 var style = {}; 263 // 克隆一个object 264 style = mxUtils.clone(style); 265 style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_LABEL; // 不设置这个属性 背景图片不出来 266 // 边框颜色 267 style[mxConstants.STYLE_STROKECOLOR] = "#15428b"; 268 //圆角 269 style[mxConstants.STYLE_ROUNDED] = "1"; 270 // 边框大小 271 style[mxConstants.STYLE_STROKEWIDTH] = "0.5px"; 272 // 字体颜色 273 style[mxConstants.STYLE_FONTCOLOR] = "#000"; 274 // 文字水平方式 275 style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_right; 276 // 文字垂直对齐 277 style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_TOP; 278 // 字体大小 279 style[mxConstants.STYLE_FONTSIZE] = 14; 280 style[mxConstants.STYLE_FILLCOLOR] = "transparent"; 281 // 底图水平对齐 282 style[mxConstants.STYLE_IMAGE_ALIGN] = mxConstants.ALIGN_LEFT; 283 // 底图垂直对齐 284 style[mxConstants.STYLE_IMAGE_VERTICAL_ALIGN] = mxConstants.ALIGN_TOP; 285 // 图片路径 286 //style[mxConstants.STYLE_IMAGE] = 'images/icons48/gear.png'; 287 style[mxConstants.STYLE_IMAGE] = url; //'./images/i_assignedSlave.png'; 288 // 背景图片宽 289 style[mxConstants.STYLE_IMAGE_WIDTH] = 40; 290 // 背景图片高 291 style[mxConstants.STYLE_IMAGE_HEIGHT] = 40; 292 293 // 上间距设置 294 // 即使下边定义了全局设置,但这里单独设置上边间距仍单独有效 295 // style[mxConstants.STYLE_SPACING_TOP] = 'spacingTop'; 296 // 四边间距设置 297 style[mxConstants.STYLE_SPACING] = 1; 298 style[mxConstants.STYLE_VERTICAL_LABEL_POSITION] = 299 mxConstants.ALIGN_BOTTOM; 300 graph.getStylesheet().putCellStyle(styleName, style); 301 }
项目结构如下,红色框中的是官方下载的文件


浙公网安备 33010602011771号