mxgraph介紹
github地址:https://github.com/jgraph/mxg...,源碼地址:https://github.com/jgraph/mxg... javascript
效果能夠參考 [https://app.diagrams.net/],實現相似 visio 畫圖的效果,流程圖是它主要的一個用途
mxgraph 是一個繪圖框架,除了javascript版本,還有java版本,c#版本等 html
咱們使用的是javascript版本用於web端,mxgraph 只實現了畫圖最核心的功能, 官方內置了不少簡單的demo,也有grapheditor等複雜的帶快捷鍵、工具欄,菜單功能的demojava
mxgraph 能兼容 ie8 等比較老的瀏覽器,所以代碼中也有不少處理兼容性的代碼,在主流瀏覽器中使用 svg 實現繪圖,但代碼中使用了 canvas 做爲變量,可能容易誤覺得是 canvas 來實現的。 git
根據業務需求,咱們須要進行大量的自定義擴展(oop方式),因此須要進行大量的源碼閱讀,理解其實現方式,並擴展實現本身的功能。github
網上關於mxgraph的介紹可參考: [mxGraph 入門實例教程]: https://segmentfault.com/a/11...web
官方文檔: https://jgraph.github.io/mxgr... json
官方api說明:https://jgraph.github.io/mxgr...canvas
mxgraph源碼目錄結構
1. view
負責圖形的渲染,內部邏輯控制,對外提供api
- 核心類 mxGraph,使用了調停者模式,經過擴展這個類,能夠自定義不少功能, 咱們外部使用的不少 api 都在這個文件內
- mxGraphView: 元件從新渲染邏輯,計算元件位置、背景網格等
- mxCell:保存元件的位置信息(geometry)
- mxCellState: 根據mxCell數據,保存元件真實位置,mxGraphView每次從新渲染會從新生成
- mxCellRenderer: 根據mxCellState信息渲染出svg圖形、label、control
- mxEdgeStyle: 鏈接線的形狀,支持直線、折線等其餘形狀,目前使用的是 elbowEdgeStyle
- mxPerimeter: 不一樣形狀的邊緣位置計算方法
2. util
主要工具類實現:日誌打印、底層畫圖api、工具欄、撤銷、請求、拖拽
mxPoint、mxRectangle等基本數據類型
mxEventSource,mxEventObject 實現發佈訂閱模式c#
3. model
核心模塊mxGraphModel,全部對mxCell的操做都都由這個模塊負責,改變mxCell的geometry、父元素、value、style等,撤銷功能主要由mxUndoManager、mxUndoableEdit、和這個目錄下的文件實現segmentfault
4. handle
文件夾內包含了處理鼠標事件的類,好比鼠標選中、圖形放大、縮小、鼠標拖動選中多個圖形效果等
5. shape
文件夾下包含了常見的形狀、正方形、圓形、橢圓、多邊形、還能夠自定義各類形狀、基類 mxShape
mxSwimlane 是流程圖中比較常見的一種形狀:泳道,目前沒有使用到,代碼中有出現相關邏輯,須要注意下
6. layout
包含了處理圖形展現的類,各類佈局方式,樹形佈局、圓形佈局等,暫時不須要了解
7. io
內部的序列化實現,採用xml形式,目前已實現了json格式的序列化方式,暫不須要關心這部分
8. editor
簡單快捷鍵、菜單支持,這部分功能將本身實現,暫不須要關心這部分
mxgraph架構及運行流程
- mxGraph: 啓動模塊,負責關聯內部其餘模塊,實現總體功能,控制畫布的api都在這個模塊
- mxGraphView: 計算元件位置,調用mxCellRenderer渲染元件,控制總體渲染邏輯
- mxGraphModel:處理mxCell屬性,元件父子關係,實現撤銷功能等,全部對mxCell的修改操做都由這個模塊完成
- mxCell: 表明一個圖形元件,能夠是圖形,也能夠是邊,vertex表明元件,edge表明邊
- mxCellState: 根據mxCell中的位置,計算出的真實位置保存在這個模塊
- mxConnectionHandler: 負責2個元件以前的鏈接線,自帶的鼠標hover鏈接點效果
- mxGraphHandler: 元件選中效果
- mxVertexHandler: 元件resize效果
- mxRubberband: 鼠標按住左鍵,批量選中效果
- mxPanningHandler: 鼠標按住右鍵拖動畫布效果
- mxEdgeHandler:鏈接線移動,改變線段位置
- mxCellMarker: 元件高亮效果
- mxPerimeter: 計算元件的邊緣,用來計算鏈接線的起始點位置和終點位置
- mxGeometry: 座標、寬度、高度,用於mxCell,relative屬性表示相對於父容器佈局,區間爲0-1,[0,0]表明父容器左上角,[1,1]表明父容器右下角
- mxGuide:元件和其餘元件出現水平或垂直對齊時,將出現對齊線段
- mxConstraintHandler: 框架內置的元件鏈接點,目前沒有使用這個功能,不知足需求
- mxUndoManager:配合mxGraphModel、mxUndoableEdit實現撤銷功能
其中不少模塊都繼承了mxEventSource,以實現發佈訂閱模式,內部也很是多的使用了這個模式。
好比mxGraphView監聽鼠標事件,而後通知全部的handler處理這些事件,以實現對應的交互效果。
每次添加元件、刪除元件、撤銷操做、移動,都會觸發對應的事件,外部只須要監聽對應模塊的對應事件,就能夠作一些特殊判斷等。
主要流程:
- mxGraph初始化,生成內部實例mxGraphView、mxGraphModel、各類須要的handler等
- mxGraph調用mxGraphView初始化dom容器,mxGraphView綁定鼠標點擊事件,並生成背景網格
- 觸發外部事件:
3.1 外部添加、刪除元件,調用mxGraph.importCells、removeCells等方法,觸發mxGraphModel修改mxCell屬性,而後通知mxGraphView從新渲染整個畫布,從新計算mxCellState,調用mxCellRenderer渲染單個元件
3.2 鼠標選中等事件,mxGraphView監聽鼠標事件,通知對應的handler模塊,handler模塊調用mxGraph模塊,mxGraph通知mxGraphModel修改mxCell屬性,從新渲染
撤銷功能實現原理:
- mxGraphModel有2個使用頻率很高的api,beginUpdate和endUpdate,各個demo中都使用了這2個api,能夠嵌套使用,用來記錄一次操做,以支持撤銷。
- 因爲mxCell保存了畫布全部元件,每次新增元件、移動位置操做都將經過mxGraphModel生成一個mxUndoableEdit對象,裏面維護了多個修改操做,由各類Change組成,
model文件夾下的各個Change模塊是實際執行撤銷操做的,內部維護了previous屬性,用來進行撤銷操做。
mxgraph 經常使用函數、屬性、style屬性
mxGraph
表明一個畫布實例,能夠對畫布放大、縮小、移動、撤銷、
使用到的方法介紹:
- insertVertex: 插入元件
- insertEdge: 插入鏈接線
- setPanning:支持按住鼠標右鍵移動
- groupCells:將元件封裝成一個新的元件
- cellsAdded:當新的元件添加到畫布時觸發
- translateCell:移動指定元件
- resizeCell: 縮放元件
- getBoundingBoxFromGeometry:獲取指定元件組成的範圍大小
- center: 將畫布位置居中顯示
- setCellStyles: 給元件設置新的樣式,改變元件顏色,寬高等
- zoomIn: 放大畫布
- zoomOut: 縮小畫布
mxCellRenderer
- redrawLabel: 控制元件的label是否顯示
- isShapeEvent: 控制是否響應元件的事件
- redraw: 從新渲染單個元件
mxConnectionHandler
mxGraphView
- validate:從新渲染畫布
- validateCellState: 從新計算元件的真實寬高
- getPerimeterPoint: 計算鏈接點的起始點、終點位置
mxGraphModel(這個模塊的函數主要由mxGraph調用)
- cloneCells: clone元件
- remove: 刪除元件
- add: 添加元件
- setVisible: 設置是否可見
- beginUpdate: 開始一個事物(撤銷功能)
- endUpdate: 結束一個事物(撤銷功能)
mxCellMarker(引用mxCellHighlight實現高亮效果)
- process: 處理鼠標事件,判斷是否高亮元件
- intersects: 判斷鼠標是否在元件的中心
mxCell(表明一個圖形,包括元件和鏈接線)
- value: 元件的label值
- style: 當前圖形的樣式
- vertex: 是不是元件
- edge: 是不是鏈接線
- children: 列表,當前圖形的子圖形
元件style屬性列表,不一樣元件會有本身的私有屬性,下面是通用的一些屬性
- width 元件寬度
- height 元件高度
- shape 當前元件的形狀
- fillColor 元件填充顏色
- strokeColor 元件圖形顏色
- align label對齊方式
- opacity 透明度
- flipH 水平翻轉
- rotation 選擇角度