本教程是基于mxgraph 3.9.12,mxgraph感觉在国内用的人比较少,百度上搜一圈都是一些简单的操作,稍微偏一些的操作或者问题都没有涉及,在官方example和官方API挣扎了几个月后终于有所感悟,于是写下这篇教程,一是方便后人,二是做为自己的记录。(mxgraph 和 vue的集成可以参考我另一篇博客。Vue-cli3 生成的 Vue 项目加载Mxgraph )推荐先成功集成了mxGraph,并写了一个HelloWorld,有了一个感性的认识后再阅读

Demo,欢迎围观提issue

官网的搜索有些许的蛋疼,所以自己写了个搜索,可以根据描述和标题中的关键字搜索结果。

基本概念


欲先善其事,必先利其器,在开始之前还是要先介绍一下mxGraph的一些基本概念,下面列出了一些我任何用到比较多的方法和需要先掌握的概念。(虽然JS中没有强类型语言中类的概念,但我还是比较喜欢说类,对象,实例化等)

mxGraph

这个类应该是我们最常用到的了,每次我们开始一个mxGraph的项目,都必定会运行一遍 new mxGraph([DOM 容器]) 创建一个新的mxGraph对象。我们接下来所有的操作都要在拥有这个对象的基础上进行。我们一般会用这个对象设置一些全局的回调或者是设置一些全局的定值。

参考 http://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGraph-js.html#mxGraph

mxCell

这个类也是我们遇到的比较多的类,但刚开始写mxGraph的时候,可能很多人会问这个类在哪啊,我怎么没见过啊,其实我们每次调用 mxGraph.insertVertex() 方法创建图形时的返回值就是实例化自这个类。我们一般会通过这个对象获得一些其他的对象,比如说下面会说到的mxCellState和mxGeometry。当然这个类除了被做为跳板之外,还有一些比较实用的方法,比如说设置一个图形的可见性,是否可以被连接等。

参考 http://jgraph.github.io/mxgraph/docs/js-api/files/model/mxCell-js.html#mxCell

mxCellState

这个类是个大宝贝啊,可以通过mxGraph.view.getState([cell])得到,从中可以获取到关于一个图形的基本位置信息,包括相对于Graph容器的位置信息和相对于浏览器的位置信息,还有等等有用的信息,不知在多少个的晚上,是它帮我少掉了几根头发。

参考 http://jgraph.github.io/mxgraph/docs/js-api/files/view/mxCellState-js.html#mxCellState

mxGeometry

这个类也是个大宝贝,可以直接通过 mxCell.geometry 得到,可以从中获取到图形基本的信息,比如长度,高度,x,y等等,而且可以通过直接修改这些值来改变图形,为我们省了很多事,效果堪比生发剂啊。

参考 http://jgraph.github.io/mxgraph/docs/js-api/files/model/mxGeometry-js.html#mxGeometry

当然还有很多其他有用的类,但这就不一一列举了(再举这b就装不下去了),上面说的这些都是一些非常基础的类,有兴趣可以看官方的API详细了解。(虽然官方API的关联查询做的很那啥,但关键时刻还是能救命的)

监听和回调

做过C#可视化开发,或者是学习过C#可视化的同学,一定都知道C#可视化是基于事件驱动的,什么意思呢,就是只要你在后台定义了一个按钮的单击事件监听,那只要在界面上单击了这个按钮,那么就会触发这个监听事件,我们写在这个监听事件里的代码也会被执行,QT的信号槽的概念也是同理,为什么要说这个呢,因为在mxGraph中,也是有类似这样的监听事件的,大部分的事件是有默认的实现,我们可以对其进行改写,可能也有少部分是完全要我们自己实现的(我还没碰到)。

举个例子,假如我现在想监听单击事件,我需要下面的代码:

graph.addListener(mxEvent.CLICK, function(sender, evt)
{
  var e = evt.getProperty('event'); // mouse event
  var cell = evt.getProperty('cell'); // cell may be null

  if (cell != null)
  {
    // Do something useful with cell and consume the event
    evt.consume();
  }
});

上面是一个官方的例子,首先我们使用 graph.addListener() 方法创建一个监听(然后这不是唯一一种创建监听的方法),这个方法需要我们传入两个参数,分别是监听的事件类型和监听的回调函数。

监听的类型我们可以在API官网的mxEvent中找到,传入的回调函数会提供给我们两个值,一个是sender,一个是evt,sender我也用的不多… 但我们需要的信息基本都在evt中,比如事件的类型,事件的触发的图形对象等,我们可以在回调中实现自己的代码逻辑,完成开发需求。

其他

其他还想说一些基本下文中可能会经常提到的简写和概念:

cell

这说的cell就是上文一直提到的图形,就是通过mxGraph.insertVertex()创建返回的对象,下文中就不再说图形而是直接说cell了。

style

style的概念在mxGraph中尤其的重要,比如我想改变cell中文字的字体的大小,你在mxCell对象中找半天也是找不到有关于字体的接口和属性的,而这些东西全是在style中的,看到这你可能就会问TM到底什么是style(突然想到了freeStyle),style就是一个图形的样式,包括背景颜色,线条颜色,文字对其方式等等,基本你能想到的关于一个图形的表述里面都有。那么重点来了,竟然style这么好,那么到底要怎么设置又有哪些style呢?

设置style

先说一下我所知的设置style的三种方式:

  1. 通过参数的方式在生成CELL时传入一个style。
graph.insertVertex(parent, null, 'hello', 30, 20, 20, 20, "shape=triangle;direction=west;");

shape=triangle;direction=west;就是我们的style字符串了,这句中说的是生成的cell是三角形,并三角形面朝西。

  1. 生成CELL时传入一个名称字符串,然后再设置这个名称所代表的样式。
graph.insertVertex(parent, null, 'in1', 30, 20, 20, 20, 'testStyle');

let style ={};

style[MxConstants.STYLE_FILLCOLOR] = 'transparent';
style[MxConstants.STYLE_STROKECOLOR] = 'transparent';
style[MxConstants.STYLE_SHAPE] = MxConstants.SHAPE_LABEL;
style[MxConstants.STYLE_ALIGN] = MxConstants.ALIGN_CENTER;
style[MxConstants.STYLE_VERTICAL_ALIGN] = MxConstants.ALIGN_CENTER;
style[MxConstants.STYLE_IMAGE_ALIGN] = MxConstants.ALIGN_CENTER;
style[MxConstants.STYLE_IMAGE_VERTICAL_ALIGN] = MxConstants.ALIGN_CENTER;
style[MxConstants.STYLE_IMAGE] = require('@/assets/mxgraph/images/symbols/fork.png');
style[MxConstants.STYLE_IMAGE_WIDTH] = '48';
style[MxConstants.STYLE_IMAGE_HEIGHT] = '48';

graph.getStylesheet().putCellStyle('testStyle', style);

这一段中我们首先将shape=triangle;direction=west;替换为了testStyle,testStyle代表了一套style,接下来声明了一个对象做为style的载体,MxConstants.xxx 代表了xxx类型的style,在这分别设置了填充色,线条颜色,形状,文字对齐方式,文字垂直方向对齐方式,插入图片的对齐方式,插入图片在垂直方向的对齐方式,插入图片的地址,插入图片的宽度,插入图片的高度,最后把建立这个style载体对象和testStyle之间的关系。

  1. 通过mxCell.setStyle()方法设置style。
function str2StyleObject(){
    xxxx
}

function setStyleObject(styleObject, [{styleName: styleValue},...]){
    xxxx
}

function styleObject2Str(){
    xxxx
}

let tmpStyleObject = str2StyleObject(cell.getStyle());

setStyleObject(tmpStyleObject, [{'shape': 'rect'}]);

cell.setStyle(styleObject2Str(tmpStyleObject));

通过这种方式设置style,需要注意的是这个设置是全覆盖的,什么意思呢,举个例子,一个cell本来设置了shape和fontSize两种style,那这个cell的style就是shape=xxx;fontSize=xxx;,然后通过setStyle方法只设置了shape,那这个cell的style就是shape=xxx;,我们就丢失了关于fontSize的信息。所以想通过这种方式修改style的话,我们一般会先通过cell.getStyle()获取到现有的style字符串,然后将字符串转为对象,接着修改对象的值,然后再将对象转为符合要求的字符串,最后通过cell.setStyle()方式设置cell的style。

这三种方式其中前两种都是在创建cell时就决定了cell的style,第三种就是可以在回调中动态的更改cell的style。在书写方式上第一种和第三种是通过字符串的方式设置,第二种则是通过对象属性值的方式设置。

属性第一种第二种第三种
书写时期生成CELL时生成CELL时CELL生成后的任意时间
书写方式字符串形式对象属性值字符串形式
style的类型

再说有哪些style,我们可以在API官网关于mxConstants的部分找到有哪些style,举个例子,我们可以在其中找到如下的描述:

STYLE_FONTSIZE
STYLE_FONTSIZE: 'fontSize'
Defines the key for the fontSize style (in px).  The type of the value is int.  Value is “fontSize”.

这一段说的是有一个Style叫STYLE_FONTSIZE,这个名称就是我们在上面讲到的第二种修改style的方式中会使用到的,STYLE_FONTSIZE: 'fontSize' 这里面提到的 fontSize 就是我们在的第一种和第三种中会用到的,最后就是关于这个style的一些描述。

随后还会更新一些常用操作。

关于mxStencil的请看这。

Logo

前往低代码交流专区

更多推荐