一個基於typescript + canvas 實現的開源在線繪圖的引擎Topology。採用引擎 + 圖形庫中間件的思路能夠方便、快速的擴展、集成到前端項目。目前暫時實現了基本圖形、流程圖圖形庫,能夠滿足微服務架構圖、網絡拓撲圖和流程圖的繪製。後面計劃陸續實現活動圖/時序圖/類圖等UML圖。
在線免費使用(因爲操作方便問題,暫時沒有適配移動端)
爲什麼重複造輪子
- 筆者工作中遇到比較多的微服務架構、雲資源運維、部署與運維可視化方面的需求
- 開源、滿足自己需求的不多
- typescript + 純粹canvas架構的不多
- 以中間件方式可定製滿足不同場景的不多
- 最重要的是,興趣 + 不難
特點
- 開源
- 可定製化
- 簡單易用,方便集成
- 較好的性能,非常流暢
- 方便的數據導入導出
- 圖片保存/預覽
- typescript + canvas
使用場景
- 微服務架構圖
- 運維時部署結構拓撲圖
- 流程圖
後續會推出的:
- 活動圖
- 時序圖
- 類圖等
架構設計
主要由:層、節點、連線和箭頭等組成。
層:這裏的層,主要是爲了提升性能的邏輯層;與ps裏面的用戶圖層無關。
離屏層:包含所有繪圖數據,是最穩定的圖層。
選中層:用戶選中部分或全部節點/連線的高亮圖層,並設置相關屬性、縮放、和旋轉等。
動畫層:主要用於演示動畫。
活動層:主要用於箭頭鼠標交互事件,比如錨點和連線過程。
節點:是畫布的主要組成部分,節點內部還可以包含圖標或文字。
連線和箭頭:連線和箭頭是關聯在一起的。連線兩端可以選擇設置或不設置箭頭。節點可以通過控制點進行整體縮放、旋轉。
繪畫與屬性
節點和連線各種有自身的繪畫屬性,同時還可以設置一個附加的自定義數據
快速集成使用
es6使用示例:
https://github.com/le5le-com/...
typescript使用示例:
https://github.com/le5le-com/...
安裝
# 安裝繪圖引擎
npm install topology-core
# 安裝圖形庫 - 流程圖
npm install topology-flow-diagram
# ...其他圖形庫
創建基礎畫布
// 1. 導入繪畫引擎
import { Topology } from 'topology-core';
// 2. 創建畫布
// 其中,第一個參數'topo-canvas'表示canvas的dom元素id;
// 第二個參數{}表示畫布選項,這裏表示全部使用默認值。具體選項請參考後面的api文檔。
var canvas = new Topology('topo-canvas', {});
// 3. 渲染圖形
// 其中,第一個參數{}表示圖形數據
// 第二個參數true,表示打開一個新文件;否則在當前文件打開,覆蓋已存在的圖形數據
canvas.render({}, true);
常用畫布方法
// 獲取畫布數據
const data = this.canvas.data();
// 保存爲圖片blob
// toImage函數參數:type, quality, callback
this.canvas.toImage(null, null, blob => {
// Do sth.
});
// 下載爲圖片
// saveAsImage函數參數:filename, type, quality
this.canvas.saveAsImage('canvas.png');
// 編輯相關操作
this.canvas.cut();
this.canvas.copy();
this.canvas.parse();
this.canvas.undo();
this.canvas.redo();
引用第三方圖形庫
// 使用第三方圖形庫
// 1. 先導入註冊函數
import { registerNode } from 'topology-core/middles';
// 2. 導入圖形庫圖形及其相關元素
import {
flowData,
flowDataAnchors,
flowDataIconRect,
flowDataTextRect,
flowSubprocess,
flowSubprocessIconRect,
flowSubprocessTextRect,
flowDb,
flowDbIconRect,
flowDbTextRect,
flowDocument,
flowDocumentAnchors,
flowDocumentIconRect,
flowDocumentTextRect,
flowInternalStorage,
flowInternalStorageIconRect,
flowInternalStorageTextRect,
flowExternStorage,
flowExternStorageAnchors,
flowExternStorageIconRect,
flowExternStorageTextRect,
flowQueue,
flowQueueIconRect,
flowQueueTextRect,
flowManually,
flowManuallyAnchors,
flowManuallyIconRect,
flowManuallyTextRect,
flowDisplay,
flowDisplayAnchors,
flowDisplayIconRect,
flowDisplayTextRect,
flowParallel,
flowParallelAnchors,
flowComment,
flowCommentAnchors
} from 'topology-flow-diagram';
// 3. 向引擎註冊圖形庫圖形及其相關元素
registerNode('flowData', flowData, flowDataAnchors, flowDataIconRect, flowDataTextRect);
registerNode('flowSubprocess', flowSubprocess, null, flowSubprocessIconRect, flowSubprocessTextRect);
registerNode('flowDb', flowDb, null, flowDbIconRect, flowDbTextRect);
registerNode('flowDocument', flowDocument, flowDocumentAnchors, flowDocumentIconRect, flowDocumentTextRect);
// ...
// 下面是簡單的註冊函數介紹,詳情請參考api文檔
// registerNode: 註冊一個自定義圖形節點node.
// name - node名稱.
// drawFn - node渲染函數。傳入canvas ctx和node數據,自己決定如何繪畫node
// anchorsFn - 計算node的錨點,如果爲null,表示使用缺省計算錨點方法
// iconRectFn - 計算node的圖標區域,如果爲null,表示使用缺省計算圖標區域方法
// textRectFn - 計算node的文字區域,如果爲null,表示使用缺省計算文字區域方法
// force - 如果已經存在同名node,是否覆蓋.
export function registerNode(
name: string,
drawFn: (ctx: CanvasRenderingContext2D, node: Node) => void,
anchorsFn?: (node: Node) => void,
iconRectFn?: (node: Node) => void,
textRectFn?: (node: Node) => void,
force?: boolean
);
開發自己的圖形庫
參考開發文檔:https://www.yuque.com/alsmile...
項目地址
聯繫與幫助
微信: alsmile123