mxgraph 系列【1】: 開始使用

mxgraph 是一個很優秀的 SVG 圖形引擎、圖形編輯器,但框架官方提供的文檔太過偏向學術,實用價值低;社區對 mxgraph 的討論也不多,致使框架入門成本極高。本人計劃在將來一年內不按期推出 mxgraph 的使用教程,感興趣的同窗歡迎關注,共同窗習,共同成長。

1. 簡介

mxgraph 第一個版本提交於 2012 年,當時前端工程化還在啓蒙階段,工具鏈嚴重缺失,用當下的眼光去看待 mxgraph 簡直不堪入目。可是框架的架構設計的很是優雅,即便放在當前前端百家齊放的環境下依然足夠優秀,做爲一個範本,研究 mxgraph 源碼能夠學習到:javascript

  1. 編輯器開發以及編輯器實現中的常見設計模式
  2. 圖形佈局算法
  3. 圖形引擎如何管理大量圖形元素
  4. 如何抽象表達圖形,以支持自定義擴展
  5. 等等

本文將做爲系列教程的起點,介紹如何開始使用 mxgraph。html

2. 使用本地文件

最簡單的,可經過 git clone git@github.com:jgraph/mxgraph.git 將庫文件下載到本地後,在頁面中使用 script 標籤引入例如:前端

<!-- 使用本地文件 -->
<script src="./libs/mxgraph/mxClient.min.js"></script>

clone 命令會將倉庫全部克隆下來,其中只有 mxgraph/javascript/src/mxClient.min.jsmxgraph/javascript/src/mxClient.js 可以知足應用需求,其餘文件忽略便可。java

引入 mxClient.min.js 後,全局對象 window 下會增長許多 mx 前綴的屬性:webpack

後續可以使用這些全局變量構建應用,例如:git

<!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>

示例效果:github

3. 使用 CDN

直接使用 mxClient.min.js 文件有兩個主要缺點,一是須要將庫文件下載後放入項目中,對後續的版本管理並不友好;二是落後的構建方式致使 mxClient.min.js 會暴露不少變量到全局空間形成污染。在這種狀況下,若是仍是但願能用 <script> 方式引入,能夠考慮使用 CDN 服務:web

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

注意這裏使用的是 build.min.js 文件,與 mxClient.min.js 不一樣,該文件將 mxgraph 代碼包裹進工廠函數中,以解決全局空間污染的問題:算法

(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 命名空間,示例:typescript

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 倉庫中各個重要文件的做用,爲後續理解源碼作好鋪墊。

相關文章
相關標籤/搜索