基於 G6 和 React 的可視化圖編輯器javascript
GGEditor - Flow的簡單使用
import GGEditor, { Flow } from 'gg-editor'; const data = { nodes: [{ type: 'node', size: '70*70', shape: 'flow-circle', color: '#FA8C16', label: '起止節點', x: 55, y: 55, id: 'ea1184e8', index: 0, }, { type: 'node', size: '70*70', shape: 'flow-circle', color: '#FA8C16', label: '結束節點', x: 55, y: 255, id: '481fbb1a', index: 2, }], edges: [{ source: 'ea1184e8', sourceAnchor: 2, target: '481fbb1a', targetAnchor: 0, id: '7989ac70', index: 1, }], }; <GGEditor> <Flow style={{ width: 500, height: 500 }} data={data} /> </GGEditor>
GGEditor是容器組件。全部gg-editor定義的組件要在GGEditor內部才生效。在GGEditor組件上能夠掛載兩個事件:onBeforeCommandExecute和onAfterCommandExecute。node
onBeforeCommandExecute和onAfterCommandExecute內部能夠接收一個對象,這個對象包含一個command對象。command對象包含了一些操做方法,例如撤回上一步(back),執行命令(execute)。等等。react
Flow組件在GGEditor組件內部被使用,是流程圖組件。data接收一個對象,包含節點和連線的信息,初始化一個流程圖。data中nodes表明節點,edges表明連線,他們分別以數組的形式記錄圖形的特徵。Flow上能夠添加一系列圖例事件和鼠標事件,若是在繪圖過程當中須要處理數據能夠在這裏進行。數組
Props API
import { withPropsAPI } from 'gg-editor'; class Component extends React.Component { componentDidMount() { const { propsAPI } = this.props; console.log(propsAPI); } } export default withPropsAPI(Component);
通過 withPropsAPI
包裝的組件將會自帶 propsAPI
屬性。須要注意的是被裝飾的組件也必須是在GGEditor的子組件(不能用在GGEditor上)。編輯器
屬性 | 說明 | 類型 |
---|---|---|
executeCommand | 執行命令 | function(command) |
read | 讀取數據 | function(data) |
save | 保存數據 | function() => object |
add | 添加圖項 | function(type, model) |
find | 查找圖項 | function(id) |
update | 更新圖項 | function(item, model) |
remove | 刪除圖項 | function(item) |
getSelected | 獲取當前選中圖項 | function |
經過propsAPI調用的方法是操做圖例的正確方法(以前覺得data是能夠setState更改的我...)。svg
Command
下面是全部關於flow組件的內置命令。經過propsAPI.executeCommand()能夠調用下面的命令操做圖例。函數
命令英文名 | 命令中文名 | 快捷鍵(Mac) | 快捷鍵(Win) | 適用頁面 |
---|---|---|---|---|
clear | 清空畫布 | - | - | All |
selectAll | 全選 | ⌘A |
Ctrl+A |
All |
undo | 撤銷 | ⌘Z |
Ctrl + Z |
All |
redo | 重作 | ⇧⌘Z |
Shift + Ctrl + Z |
All |
delete | 刪除 | Delete |
Delete |
All |
zoomIn | 放大 | ⌘= |
Ctrl + = |
All |
zoomOut | 縮小 | ⌘- |
Ctrl + - |
All |
autoZoom | 自適應尺寸 | - | - | All |
resetZoom | 實際尺寸 | ⌘0 |
Ctrl + 0 |
All |
toFront | 提高層級 | - | - | All |
toBack | 降低層級 | - | - | All |
copy | 複製 | ⌘C |
Ctrl + C |
Flow |
paste | 粘貼 | ⌘V |
Ctrl + V |
Flow |
multiSelect | 多選模式 | - | - | Flow |
addGroup | 成組 | ⌘G |
Ctrl + G |
Flow |
unGroup | 取消組 | ⇧⌘G |
Shift + Ctrl + G |
Flow |
工具欄和圖例右擊操做,能夠經過配置command自由組合。工具
import GGEditor, { Flow, Command, Toolbar, ContextMenu } from 'gg-editor'; <GGEditor>
<Flow />
<Toolbar>
<Command name="undo"><button>Undo</button></Command>
<Command name="redo">Redo</Command>
</Toolbar>
<ContextMenu>
<Command name="undo">Undo</Command>
<Command name="redo">Redo</Command>
</ContextMenu>
</GGEditor>
ContextMenu下面還有NodeMenu,EdgeMenu,CanvasMenu分組能夠選擇性的引入。分別對應對節點右擊命令、連線右擊命令和空白畫布右擊命令設置。this
固然也能夠自定義命令。
import GGEditor, { Flow, RegisterCommand } from 'gg-editor'; <GGEditor> <Flow /> <RegisterCommand name={...} config={...} extend={...} /> </GGEditor>
其中name表示命令名稱配置,extend能夠繼承內置命令。
config可配置自定義命令的各項指標,是否能夠進入隊列,正反向執行命令函數等。
import React from "react"; import { RegisterCommand, withPropsAPI } from "gg-editor"; class DustomCommand extends React.Component { render() { const { propsAPI } = this.props; const { save, update, getSelected } = propsAPI; const config = { // 是否進入列隊,默認爲 true queue: true, // 命令是否可用 enable(/* editor */) { return true; }, // 正向命令邏輯 execute(/* editor */) { // console.log(propsAPI.editor); const chart = save(); console.log("chart", chart); const selectedNodes = getSelected(); selectedNodes.map(node => { update(node, { x: node.model.x + 2, y: node.model.y }); }); }, // 反向命令邏輯 back(/* editor */) { console.log("執行反向命令2"); }, // 快捷按鍵配置 shortcutCodes: [["ArrowLeft"], ["ArrowRight"]] }; return <RegisterCommand name="dustomCommand" config={config} />; } } export default withPropsAPI(DustomCommand);
這段代碼從codesandbox複製過來的。用以參考。
ItemPanel
<ItemPanel className={styles.itemPanel}> <Item type="node" size="72*72" shape="flow-circle" model={{ color: '#FA8C16', label: 'Start', }} // src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODAiIGhlaWdodD0iODAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxjaXJjbGUgaWQ9ImIiIGN4PSIzNiIgY3k9IjM2IiByPSIzNiIvPjxmaWx0ZXIgeD0iLTkuNyUiIHk9Ii02LjklIiB3aWR0aD0iMTE5LjQlIiBoZWlnaHQ9IjExOS40JSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0iYSI+PGZlT2Zmc2V0IGR5PSIyIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMiIgaW49InNoYWRvd09mZnNldE91dGVyMSIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIi8+PGZlQ29tcG9zaXRlIGluPSJzaGFkb3dCbHVyT3V0ZXIxIiBpbjI9IlNvdXJjZUFscGhhIiBvcGVyYXRvcj0ib3V0IiByZXN1bHQ9InNoYWRvd0JsdXJPdXRlcjEiLz48ZmVDb2xvck1hdHJpeCB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAuMDQgMCIgaW49InNoYWRvd0JsdXJPdXRlcjEiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0IDIpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGwtb3BhY2l0eT0iLjkyIiBmaWxsPSIjRkZGMkU4IiB4bGluazpocmVmPSIjYiIvPjxjaXJjbGUgc3Ryb2tlPSIjRkZDMDY5IiBjeD0iMzYiIGN5PSIzNiIgcj0iMzUuNSIvPjwvZz48dGV4dCBmb250LWZhbWlseT0iUGluZ0ZhbmdTQy1SZWd1bGFyLCBQaW5nRmFuZyBTQyIgZm9udC1zaXplPSIxMiIgZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQgMikiPjx0c3BhbiB4PSIyMyIgeT0iNDEiPlN0YXJ0PC90c3Bhbj48L3RleHQ+PC9nPjwvc3ZnPg==" > flow-circle </Item> </ItemPanel>
能夠拖拽圖形到界面上。ItemPanel做爲容器組件,包含Item組件。每一個Item拖拽元素上包含了圖形和數據信息。若是須要被拖拽的元素上包含數據信息,掛載在Item的model屬性中。其中src屬性是元素預覽,能夠不配置,在Item中間用文字表述當前內容。
其餘
當初遇到的問題
1.propsAPI獲取不到內容:withPropsAPI包裹的組件必須是GGEditor的子組件。
2.自定義組件如何使用:正確的辦法是經過config配置,參照上面的代碼(以前我在在內部RegisterCommand之後,在onAfterExecuteCommand中截獲命令,經過函數控制圖例操做。這中間須要下鑽到內部組件調用propsAPI,我就經過setState去設置狀態傳遞到子組件。)
3.如何設置拖拽組件:太羞恥了,竟然不曉得在Item雙標籤內放名稱。
4.操做流程圖後獲取數據延遲:若是獲取數據有延遲,嘗試使用setTimeout,時間間隔設爲0後再調propsAPI屬性的方法操做。