开始使用 mxGraph

mxGraph 是一个很优秀的 SVG 图形引擎、图形编辑器,但框架官方提供的文档太过偏向学术,实用价值低;社区对 mxGraph 的讨论也不多,致使框架入门成本极高。本人计划在将来一年内不按期推出 mxGraph 的使用教程,感兴趣的同窗欢迎关注,共同窗习,共同成长。javascript

1. 简介

mxGraph 第一个版本提交于 2012 年,当时前端工程化还在启蒙阶段,工具链严重缺失,用当下的眼光去看待 mxGraph 简直不堪入目。可是框架的架构设计的很是优雅,即便放在当前前端百家齐放的环境下依然足够优秀,做为一个范本,研究 mxGraph 源码能够学习到:html

  1. 编辑器开发以及编辑器实现中的常见设计模式
  2. 图形布局算法
  3. 图形引擎如何管理大量图形元素
  4. 如何抽象表达图形,以支持自定义扩展
  5. 等等

本文将做为系列教程的起点,介绍如何开始使用 mxGraph。前端

2. 使用本地文件

最简单的,可经过 git clone git@github.com:jgraph/mxgraph.git 将库文件下载到本地后,在页面中使用 script 标签引入例如:java

<!-- 使用本地文件 -->
<script src="./libs/mxGraph/mxClient.min.js"></script>
复制代码

clone 命令会将仓库全部克隆下来,其中只有 mxgraph/javascript/src/mxClient.min.jsmxgraph/javascript/src/mxClient.js 可以知足应用需求,其余文件忽略便可。webpack

引入 mxClient.min.js 后,全局对象 window 下会增长许多 mx 前缀的属性:git

后续可以使用这些全局变量构建应用,例如:github

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<title>mxGraph Demo</title>
	</head>
	<body>
		<div id="root"></div>

		<script type="text/javascript" src="../mxClient.min.js"></script>
		<script type="text/javascript"> // mxGraph 被暴露在window下,因此能够直接调用 const graph = new mxGraph(document.getElementById('root')); const parent = graph.getDefaultParent(); // 启动一次更新会话 graph.getModel().beginUpdate(); try { // 插入一个矩形 const v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30); // 插入第二个矩形 const v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30); // 链接两个矩形 graph.insertEdge(parent, null, '', v1, v2); } finally { // 结束更新会话 graph.getModel().endUpdate(); } </script>
	</body>
</html>
复制代码

示例效果:web

3. 使用 CDN

直接使用 mxClient.min.js 文件有两个主要缺点,一是须要将库文件下载后放入项目中,对后续的版本管理并不友好;二是落后的构建方式致使 mxClient.min.js 会暴露不少变量到全局空间形成污染。在这种状况下,若是仍是但愿能用 <script> 方式引入,能够考虑使用 CDN 服务:算法

<script src="//cdn.jsdelivr.net/npm/mxgraph@4.1.1/javascript/dist/build.min.js"></script>
复制代码

注意这里使用的是 build.min.js 文件,与 mxClient.min.js 不一样,该文件将 mxGraph 代码包裹进工厂函数中,以解决全局空间污染的问题:typescript

(function (root, factory) {
	if (typeof define === 'function' && define.amd) {
		define([], factory);
	} else if (typeof module === 'object' && module.exports) {
		module.exports = factory();
	} else {
		root.mxgraph = factory();
	}
})(this, function () {
	return function (opts) {
		for (var name in opts) {
			this[name] = opts[name];
		}
		var __mxOutput = {};
		/* 此处插入 mxGraph 代码 */
		return __mxOutput;
	};
});
复制代码

build.min.js 对外暴露了一个工厂函数,用法与上面示例略有不一样,须要先执行工厂函数初始化 mxGraph 命名空间,示例:

4
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<title>mxGraph Demo</title>
	</head>
	<body>
		<div id="root"></div>
		<script src="//cdn.jsdelivr.net/npm/mxgraph@4.1.0/javascript/dist/build.js"></script>
		<script> // 初始化命名空间 // 这里的 mxgraph 是 `build.min.js` 暴露出的工厂函数 const ns = mxgraph({ mxBasePath: '//cdn.jsdelivr.net/npm/mxgraph@4.1.0/javascript/src', }); const graph = new ns.mxGraph(document.getElementById('root')); const parent = graph.getDefaultParent(); // 启动一次更新会话 graph.getModel().beginUpdate(); try { const v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30); const v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30); graph.insertEdge(parent, null, '', v1, v2); } finally { // 结束更新会话 graph.getModel().endUpdate(); } </script>
	</body>
</html>
复制代码

提示:

上述代码虽然能正常渲染出 hello world! 字样,但控制台上会报不少错误,一样是由于构建方式致使的 bug,在本示例中请直接忽略。

3. 使用 webpack 等模块化方案引入

自 3.7.2 版本起,mxGraph 开始将库打包发布到 npm,开发者可使用 yarn add mxgraph 进行安装。 mxgraph 包的主入口文件是 build.min.js,默认导入的是如前面例子所说的工厂函数,示例:

const ns = require('mxgraph'))({});
// 或者 import 语法
// import mxGraphFactory from 'mxgraph';
// const ns = mxGraphFactory({});
const graph = new ns.mxGraph(this.$refs.main);

const parent = graph.getDefaultParent();

graph.getModel().beginUpdate();
try {
	const v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
	const v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
	const e1 = graph.insertEdge(parent, null, '', v1, v2);
} finally {
	graph.getModel().endUpdate();
}
复制代码

提示:

既然能够经过 npm 安装,前面为何还要花大量篇幅介绍 script 引入呢?主要是由于 mxGraph 文档极度不完善,其中最有参考价值的是 官方 examples,而这些示例代码全都使用 <script> 引入本地库文件,所以理解不一样引入模式可以帮助更好地理解示例。

另外,目前社区还没有有 mxGraph 比较好的 typescript 类型定义库,因此还没法在 ts 环境下畅快地使用。

下节预告

mxGraph 工程方案很是凌乱,仓库包含了许多无关代码以及难以理解的 trick,下一节将简要讨论 mxGraph 仓库中各个重要文件的做用,为后续理解源码作好铺垫。

相关文章
相关标签/搜索