基本概念

什么是mGraph

mxGraph 是一个JS的Graph库,提供基础的API,并不是一个开箱即用的产品,它不同于一般的Chart库,虽然有很多相似的地方。包括以下特点:

  1. 无第三方依赖。
  2. 所使用的技术均是开源技术。
  3. 即提供了客户端代码,也提供了服务器端代码。

包含的组件如下: 组件图

基本概念

Graph可视化

一般的Chart包括了饼图,线图等,但Graph意指所有的图形。它由节点和线组成,Graph中包含的各个元素都可以称为Cell,Cell可以是节点,线或者分组。Graph提供很广泛的显示元素,节点可以是shape,图形,动画,和浏览器中任何可视化的内容。

Graph交互

Graph支持拖动,克隆,改变大小或者重新resize,链接或者断开链接,也可以拖入外部图片,并且在交互方面提供了可编程的方式来增加灵活性。许多复杂的应用程序都依赖于服务器的相应来构造客户端的显示,同时交互的事件也会依赖于这种方式。尽管可以通过ajax的方式来支持,但是这样强依赖服务器端的交互并不适合强交互的应用,每次交互可能都需要花费0.2s的时间,这对于客户端的用户体验并不是很好。将所有的交互放在客户端,可以提供作为一个完整应用的体验,而不是仅仅是一个远程使用端,同时也支持离线应用。

Graph布局

Graph可以被画在任何一个应用程序中,这里涉及到一个布局计算问题,对于非编辑型的图表,这个应用程序仅处理布局算法进行展示,对于交互性的图表,那些可以被编辑的节点,要允许用户可以编辑,同时在编辑之后,还可以应用布局算法来重新计算布局的展现。算法的分析上决定了算法中的很多结构上的细节,比如两个节点间的最短路径等。

整合&扩展

mGraph和其他框架整合非常简单,他只需要一个DIV,初次之外不会对界面的其他部门产生影响,它有自己的事件系统,页面的其他部门甚至可以有自己的事件系统,这些都无所谓的。

扩展mGraph遵循两个原则:

  1. 不要试图改变内部的原型链
  2. 不要限制JAVASCRIPT的能力 mGraph提供了两种类型的对象,一个是classes,一个是sington。sington是单例类,被注册在全局对象上,比如mxConstants。class带有构造器和原型链,并且扩展了实例方法和属性,比如mxEditor。mGraph中的所有类都是以mx开头。

mxGraph模型与元素

mxGraphModel模型描述了图形的结构,提供了改变和删除模型结构的方法,也提供了改变模型状态的方法,比如可见性,分组和样式等。尽管这些处理方法属于模型的职能,但这些方法在mxGraph上也都存在对应的公共接口,这是因为从业务上更好理解:”增加元素到图形中“而不是增加元素到图形模型中。因此在模型上的这些方法在mxGraph都会存在一份调用拷贝。尽管许多外部api的调用用的是mxGraph,但一定要记住,隐藏在下面的实际上是mxGraphModel。

mxGraph提供了一系列事务性的方法来对模型进行改变,比如下面的例子:

// Adds cells to the model in a single step
graph.getModel().beginUpdate();
try
{
   var v1 = graph.addVertex(parent, null, 'Hello,', 20, 20, 80, 30);
   var v2 = graph.addVertex(parent, null, 'World!', 200, 150, 80, 30);
   var e1 = graph.addEdge(parent, null, '', v1, v2);
}
finally
{
   // Updates the display
   graph.getModel().endUpdate();
}

对graph的模型进行更改时,必须以beginUpdate开始,然后以endUpdate结束。最主要的方法包括:

  • mxGraphModel.beginUpdate() - 开始更新.
  • mxGraphModel.endUpdate() - 结束更新.
  • mxGraph.addVertex() - 往父元素中增加一个节点.
  • mxGraph.addEdge() - 增加连接线. 注意endUpdate必须在finally中。 注意:技术上来说,你也可以不用begin&update来包装你的代码,改变也可以是立即生效的。实际上,直接在模型上的事务性的改变策略可以控制timing和事件监听的链接。

事务性Model

mGraph同时支持子事务的更新,事务性的代码可以嵌套。在模型中存在一个计数器,当遇到一个beginUpdate时,会加1,当遇到endUpdate时会减1。当减到1的时候,count为0,整个模型的事务性代码完成提交并进行模型改变的事件性通知。这种方式带来的好处是可以对所有的更改只发送一个事件,也可以每次改变发送一个事件,对于undo的处理也更加的细分化。

在自动布局中,用户的改变会根据某种算法来重新排列,在begin&end之间的代码会被直接操纵在模型上,布局就可以一次性的操作模型的状态,可以减少重绘的过程。当endupdate调用的时候,模型改变的事件会被触发,此时在事件中就可以一次性的拿到所有模型改变的状态来进行处理。

下面是一系列的模型改变方法:

  • add(parent, child, index)
  • remove(cell)
  • setCollapsed(cell, collapsed)
  • setGeometry(cell, geometry)
  • setRoot(root)
  • setStyle(cell, style)
  • setTerminal(cell, terminal, isSource)
  • setTerminals(edge,source,target)
  • setValue(cell, value)
  • setVisible(cell, visible)

初次之外,还有两个重要的方法,下面两个方法都被包含在begin&update中。

  • mxGraph.insertVertex(parent, id, value, x, y, width, height, style) – 插入一个节点
  • mxGraph.insertEdge(parent, id, value, source, target, style) – 插入一个线.

mxCell

mxCell是节点和线的通用类,他也像模型一样,提供了一个通用的操作方法。最大的不同是,使用模型的方法可以触发事件通知和undo操作,使用cell的方法不会记录这些内容。但是这对于一些可视化的行为,比如动画,鼠标操作等是非常有用的。作为一个通用的机制,建议统一使用model上的api,而不是cell中的api。

Styles

Sytles类似于CSS,他是一个hashtable结构,默认提供了defaultVertex和defaultEdge样式,可以对其进行修改。设置样式可以使用setStyle方法,也可以在insertVertex的时候插入样式。核心的方法包括:

  • mxGraph.setCellStyle(style, cells) – 设置cell的style
  • mxGraph.getCellStyle(cell) – 返回cell的style 创建全局性的Style
    var style = new Object();
    style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
    style[mxConstants.STYLE_OPACITY] = 50;
    style[mxConstants.STYLE_FONTCOLOR]= '#774400';
    graph.getStylesheet().putCellStyle('ROUNDED',style);
    

几何属性

mxGeometry属性单独存放而不是存在mxGeometry的类中是因为线条也有几何属性,线条的宽度和高度经常被忽略,初次之外,还包括线上label的相对位置,线还有控制点的概念。

相对定位

坐标在无关位置: x和y是相对父容器的定位位置,这里不讨论parent和分组的概念,如果没有parent,x和y就是相对于整个graph的定位。 相对定位 上图中可以看出,子节点相对于父节点的xy值。 而线条中的lable却是绝对定位的,xy分别到线中坐标的左上角。 线条中的label

坐标在相关位置:

如果相对模式下,xy是父节点的百分比。(0,0)和父容器左上角同源,(1,1)和父容器的右下角同源。这种方式可以同父元素的比例保持一个很好的固定大小比例关系。 垂直模型

线上的label是从线的中点开始定位的。x轴是从线开始的相对距离,y轴是线直角的相对距离。

  • mxGraph.resizeCell(cell, bounds) – 重新调整cell的大小
  • mxGraph.resizeCells(cells, bounds) – 批量调整cell的大小

业务数据

UserObject就是存放在节点总的数据,支持从和服务器端进行交互。还有一个cellType的问题。可以存放任何的对象。

分组

mxGraph中有一个分组的概念,其他的产品中叫做子图,从数据结构上来说,他通常包含了一个或者多个元素。分组有以下特点:

  1. 子图,可以让整体流程看上去更加紧凑。
  2. 折叠和扩展
  3. 分层:可以设置z-order来达到分组组织。
  4. 钻取 在分组中,所有的元素被赋值给一个不可见的父对象,这个对象作为他们的缺省对象。graph.getDefaultParent()可以返回这个对象。核心的api包括:
  5. mxGraph.groupCells(group, border, cells) – 将指定的cell加入到group中。 mxGraph.ungroupCells(cells) – 将指定的cell从group中移除。

复杂性管理

一个图中的节点不能太多,一个是性能问题,一个是用户的使用问题。

折叠

相关函数:

  1. mxGraph.foldCells(collapse, recurse, cells)
  2. mxGraph.isCellFoldable(cell, collapse)
  3. mxGraph.isCellCollapsed(cell) 当被折叠的时候发生了三件事情:
  4. 这个cell的儿子节点均被隐藏。
  5. 在上级图中使用分组边界。
  6. 线的提升。

钻取

核心的api包括

  1. mxGraph.enterGroup(cell) – 钻取进入
  2. mxGraph.exitGroup() - 钻取退出.
  3. mxGraph.home() - 进入根节点.

层级

有个概念是z-order,类似于中css中的在z-index. 核心的api包括:

  1. mxGraph.orderCells(back, cells)

通过分组和分层可以让你的图标从逻辑上更加简单。

results for ""

    No results matching ""