很欣慰,用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>
