很欣慰,用mxgGaph開發流程圖,鍛煉了我的英語閱讀能力(這里有一個無奈的苦笑);
這里先記錄一下卡了我兩天的一個,怎么形容呢,一個小水坑。不踩不知道,踩了哈哈笑。PS:此處不記錄過程,只記錄問題,適用於用過此插件並對插件有一定了解的寶寶們。
1、關於mxgraph的自動布局:
a、使用mxgraph的自動布局,要設置節點可編輯,否則布局無效,小水坑呀小水坑,歡樂的小水坑:
b、很多后台流程是有回調,所以節點之間的連線是雙向的,這時候用樹形布局,就失效了,因為雙向的連線不符合樹形布局,這時候可以換成mxHierarchicalLayout布局例如這種:
2、關於使用html代碼來渲染節點
第一步,設置開啟支持html:
第二步,創建節點並添加到畫布:
3、節點中使用圖片,要設置STYLE_SHAPE 為 SHAPE_LABEL 才可以,以下是一段節點使用圖片的樣式設置,label在圖片下方:
4、在vue-cli3 中, 通過npm安裝並使用 mxgraph
項目任務比較緊,這次就偷懶使用了官方腳手架,單頁面開發方式,使用vue-router做路由。
網上其他關於vue-cli3 使用 mxgraph的文章中都提到了報錯,但是我並沒有遇到,這里就貼一下我的整合方式吧:
mxgraph.js中:
vue頁面或者組件中:引入mxgraph 並 定義 需要用到的類
最后,附上mxgraph組件的代碼:
<template> <div class="container" :class="boxClass"> <div id="pannel"></div> </div> </template> <style> .cirlce{ height: 60px; width: 60px; background-color: green; border-radius: 30px; font-size: 16px; color: #fff; line-height: 60px; text-align: center; } </style> <script> import mxgraph from '../../../plugins/mxgraph'; import utils from '../../base/utils'; import { popup } from '../popup/popup'; const {mxHierarchicalLayout,mxConstants,mxCell,mxClient,mxGraph,mxGraphModel,mxGeometry} = mxgraph; const colorMap = { '00': '#999', // 正常 '11': 'red' // 失敗 } var graph; export default { name: 'workflow', props: { boxClass: String, oriData: Object }, data() { return { } }, mounted(){ this.init(); }, methods: { init(){ var container = document.getElementById('pannel'); // Checks if the browser is supported if(!mxClient.isBrowserSupported()){ // Displays an error message if the browser is not supported. popup.bubble('error','Browser is not supported!'); return; } //init容器 var model = new mxGraphModel(); graph = new mxGraph(container, model); //設置元素可被連接線連接 graph.setConnectable(false); //設置元素可編輯,不然無法自動布局 graph.setCellsLocked(false); //設置兩個節點是否可以建立多個連接 graph.setMultigraph(true); //cell創建支持傳入html graph.setHtmlLabels(true); //是否允許線單獨存在 graph.setAllowDanglingEdges(false); //設置cell可選中 graph.setCellsSelectable(false); //設置面板可以擴大 graph.setPanning(false); /*設置連接線樣式*/ var style = graph.getStylesheet().getDefaultEdgeStyle(); //圓角連線 style[mxConstants.STYLE_ROUNDED] = true; //labelsize style[mxConstants.STYLE_FONTSIZE] = 18; //label位置 style[mxConstants.STYLE_SPACING_BOTTOM] = 30; this.initProcessData(); }, initProcessData(){ const parent = graph.getDefaultParent(); const model = utils.copyObject(this.oriData); if(model.nodeList.length <= 0)return; var lines = model.lineList || []; var nodes = model.nodeList || []; nodes.map((item)=>{ var info = { key: item.key, name: item.name, state: item.state } this.addCell(info, item); }); lines.map((item)=>{ var sourceCell = this.getCellById(item.source); var targetCell = this.getCellById(item.target); if(!sourceCell || !targetCell)return; var line = graph.insertEdge(graph.getDefaultParent(), item.key, "", sourceCell, targetCell); this.setCellStyle('strokeColor', colorMap[item.state], [line]); }); // 自動布局 var layout = new mxHierarchicalLayout(graph,mxConstants.DIRECTION_WEST); layout.execute(graph.getDefaultParent()); this.adjustPos(); // 調整位置,讓流程圖劇中 }, adjustPos(){ var bounds = graph.getGraphBounds(); var margin = margin || 10; graph.container.style.overflow = "hidden"; graph.view.setTranslate( -bounds.x -(bounds.width - graph.container.clientWidth)/ 2, -bounds.y - (bounds.height - graph.container.clientHeight) / 2 ); while( (bounds.width + margin * 2) > graph.container.clientWidth || (bounds.height + margin * 2) > graph.container.clientHeight ){ graph.zoomOut(); bounds = graph.getGraphBounds(); } graph.container.style.overflow = "auto"; }, getCellById(id){ var cells = graph.getChildVertices(graph.getDefaultParent()); var nodes = cells.filter((item)=>{ return item.id == id; }); if(nodes.length > 0)return nodes[0]; }, addCell(info){ /*info{ key,//節點唯一標識 name, //節點label state: }*/ if(!info)return; // 清除默認樣式 var style = 'text;strokeColor=none;fillColor=none;html=1;whiteSpace=wrap;verticalAlign=middle;overflow=hidden;'; // 節點html結構 var html = '<div class="cirlce">'+info.name+'</div>' // 創建節點 var cell = new mxCell(html, new mxGeometry(0, 0, 65, 85), style); // 設置cell為節點(在mxgraph中,鏈接線段也屬於一種cell,所以這里新建了cell以后要設置它的類型) cell.setVertex(true); // 添加節點到畫布 graph.addCell(cell); if(info.key){ cell.setId(info.key); } }, setCellStyle(key, value, cells){ if(!cells)return; graph.setCellStyles(key, value, cells); //graph.refresh(cell); } }, watch: { oriData(){ this.initProcessData(); } } } </script>