一、Hello World

  • HTML
<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="UTF-8"/>
		<title>mxGraph01</title>
		<script>
			mxBasePath = "../../src";
		</script>
		<script src="../../src/js/mxClient.js"></script>
		<script src="./example01.js"></script>
		<style>
			#graphContainer{
				position:relative;
				overflow:hidden;
				width:321px;
				height:241px;
				background:url('../editors/images/grid.gif');
				cursor:default;
			}
		</style>
	</head>
	<body>
		<div id="graphContainer"></div>
	</body>
</html>
说明:

这段HTML代码有三个script标签,第一个标签中指定了mxBasePath的路径,此路径为mxGraph源码的路径,此路径下的文件有: css、images、js和resources;第二个标签中引入了mxClient.js,此js中会判断是否设置了mxBasePath,如果没有设置此值,mxClient.basePath的值就为当前路径,否则为设置的mxBasePath的路径。之后会在此路径下异步加载必须的其他js文件,或者也可以直接使用包含了所有文件的mxClient.js或mxClient.min.js,后者适用于正式使用的场景。第三个script中引入了当前页面的js。

  • Script脚本(example01.js)
document.body.onload = function(){
	var container = document.querySelector("#graphContainer");
	var graph = new mxGraph(container);

	var parent = graph.getDefaultParent();
	graph.getModel().beginUpdate();
	try{
		var v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30);
		var v2 = graph.insertVertex(parent, null, 'World', 200, 150, 80, 30);
		var e1 = graph.insertEdge(parent, null, '连线', v1, v2);
	}finally{
		graph.getModel().endUpdate();
	}
};
说明:

mxGraph在改变model时使用了事务,这个例子中插入了两个节点和一条线,分别调用了mxGraph的insertVertex和insertEdge方法。

API如下:
insertVertex(parent, id, value, x, y,width, height, style, relative)
insertEdge(parent,id, value, source, target, style)

每次改变model时需要先调用beginUpdate()方法,然后改变model,最后调用endUpdate()完成对model的改变并发出事件改变通知。

二、其他辅助功能

1、选择线框

在选择图形的时候显示选择区域:

var rubberband = new mxRubberband(graph);

2、折叠/展开节点

设置mxCell是可折叠的:

graph.isCellFoldable = function(cell){
	return true;
};

3、自定义连线样式

mxEdgeStyle中定义了线的各种样式:Loop、ElbowConnector、SideToSide等等,可以通过以下方式自定义连线样式:

mxEdgeStyle.MyStyle = function(state, source, target, points, result){
	if (source != null && target != null){
		var pt = new mxPoint(target.getCenterX(), source.getCenterY());
		if (mxUtils.contains(source, pt.x, pt.y)){
			pt.y = source.y + source.height;
		}        
		result.push(pt);
	}
};

定义好样式后,还需要注册到mxStyleRegistry中:

mxStyleRegistry.putValue('myEdgeStyle', mxEdgeStyle.MyStyle);

最后使用mxGraphModel的setStyle方法将样式设置到指定的线上:

var e1 = graph.insertEdge(parent, null, '连线', v1, v2);
graph.getModel().setStyle(e1, 'edgeStyle=myEdgeStyle');

也可以在定义好自定义样式后,直接修改连线的默认样式:

var style = graph.getStylesheet().getDefaultEdgeStyle();
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.MyStyle;

4、节点Tooltip

使用 graph.setTooltips(true); 开启tooltip功能,当鼠标放到节点或线上的时候就会显示提示信息,效果如下:

也可以重写 graph.getTooltipForCell 方法,自定义tooltip显示:

graph.getTooltipForCell = function(cell){
	if(this.model.isEdge(cell)){
		return this.convertValueToString(this.model.getTerminal(cell, true))
			+ " --> " +
			this.convertValueToString(this.model.getTerminal(cell, false));
	}
	return mxGraph.prototype.getTooltipForCell.apply(this, arguments);
};

5、使用相对位置定位节点

var v3 = graph.insertVertex(parent, null, 'Hello World!', 95, 100, 110, 40);
v3.setConnectable(false);
var v31 = graph.insertVertex(v3, null, '♥', 1, 1, 20, 20);
v31.geometry.offset = new mxPoint(-10, -10);
v31.geometry.relative = true;

上面的代码在画布上插入一个”Hello World” 的节点,同时又给该节点添加了一个不允许连接的子节点,并定位到右下角。效果如下:

6、禁止拖动线的label

默认情况下线的label是可以拖动的,可以使用以下代码禁止拖动线的label:

graph.edgeLabelsMovable = false;

7、鼠标划过时高亮显示

new mxCellTracker(graph, '#00FF00'); 

可以通过以上代码添加对线和节点在鼠标划过时的高亮效果。

mxCellTracker(graph, color, funct)的第三个参数是可选的,如果设置了funct则需要在此函数中重写getCell逻辑。

8、开起“指引”功能

mxGraphHandler.prototype.guidesEnabled = true;

可以通过以上代码开起“指引”功能,即在拖动节点时会有对齐线等提示效果。

9、右键菜单

可以使用以下代码禁止弹出浏览器的右键菜单:

mxEvent.disableContextMenu(container);

也可以通过重写 graph.popupMenuHandler.factoryMethod 方法自定右键菜单:

function createPopupMenu(graph, menu, cell, evt){
	if(cell != null){
		//节点上右击
		menu.addItem('节点菜单项', 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/37/moren_chongjing_org.png', function(){
			mxUtils.alert('Hello Cell!');
		});
	}else{
		//图象上右击
		menu.addItem('画布菜单项', 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/5c/huanglianwx_org.gif', function(){
			mxUtils.alert('Hello Canvas!');
		});
	}
	//添加分隔线
	menu.addSeparator();
	menu.addItem('通用菜单项', 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/6a/laugh.gif', function(){
		mxUtils.alert(graph.getSelectionCount());
	});
}

graph.popupMenuHandler.factoryMethod = function(menu, cell, evt){
	return createPopupMenu(graph, menu, cell, evt);
};

上面的代码自定义了创建菜单的方法,对在节点上右击还是在画布上右击的菜单项做了不同的显示和回调处理。

  • 画布右击

  • 节点右击

附: