作者: Fred F.M. Wang (FW知識瑣記) 日期:2021/6/12
前一篇 BPM系統如何使用jQuery動態顯示流程圖含範例 --- 使用flowchart.js
由前一篇文章提出flowchart.js的三個缺點
1 流程圖繪製比較不具彈性,流程線只能選擇向右,向下與向左,不能決定每一條線繪製的
長短與位置,向左方繪製的流程線繪製會有問題,如下圖
2 決策節點只能有yes, no兩種選項,不能有更多重的選項。無法解決三種或三種以上條件的流
程,例如: 三種請購單類型分別走三種不同的審核流程。
3 流程線無法個別設定要顯示的文字。
由於這幾個缺點,我決定不使用 flowchart.js作為我後續開發使用的程式庫。
嘗試了其他jQuery程式庫,如flowSVG.js 與 flowcharty.js
flowSVG.js似乎沒辦法做到退回流程,也就是如果特定審核關卡如果退回,需要有一條退回到前一關卡的線,怎樣試都畫不出來,因此被我淘汰掉了。下面是flowSVG的範例圖。
嘗試了flowcharty.js覺得還不錯,沒有上面flowchart.js與flowSVG.js的缺點,可以提供給大家參考。
下面是flowcharty.js的優點 :
1 網格方式布局流程元件, 增加dummy節點,讓流程圖繪製更具彈性,流程線可以控制
繪製的方向與位置。
2 決策點可以有超過兩種以上的選項。
3 流程線可以個別設定要顯示的文字。
唯一不如 flowchart.js的是flowcharty.js不提供流程圖元件點擊連結與顯示訊息。
flowcharty.js GitHub網址 :https://github.com/atago0129/flowcharty
簡單說明 : https://www.cssscript.com/svg-flowchart-d3-flowcharty/
demo : https://www.cssscript.com/demo/svg-flowchart-d3-flowcharty/
我由官方範俐改寫為一個簡單的請購單審核流程 ,如下:
確實可以達到我的需要。
下面是我寫的範例內容 :
<svg width="960" height="720"></svg>
<script src="//d3js.org/d3.v5.min.js"></script>
<script type="text/javascript" src="<?= base_url() ?>javascript/flowcharty.js"></script>
<script>
var data = {
nodes: [
{id: 'start', label: {name: '開始'}, style: {fillColor: '#fff'}},
{id: 'process1',
label: {name: '填寫請購單', color: '#fff', dx: 0, dy: 0, textAnchor: 'middle'},
style: {shape: "rect", width: 150, height: 50, rx: 3, ry: 3, fillColor: '#706CAA', strokeColor: '#7152aa'}
},
{id: 'process2', label: {name: '主管審核', color: '#fff', dx: 0, dy: 0, textAnchor: 'middle'}, style: {shape: "rect", width: 150, height: 50, rx: 3, ry: 3, fillColor: '#706CAA', strokeColor: '#7152aa'}},
{id: 'process3', label: {name: '承辦人審核', color: '#fff', dx: 0, dy: 0, textAnchor: 'middle'}, style: {shape: "rect", width: 150, height: 50, rx: 3, ry: 3, fillColor: '#706CAA', strokeColor: '#7152aa'}},
{id: 'decision1', label: {name: '作廢?'}},
{id: 'decision2', label: {name: '核准?'}},
{id: 'decision3', label: {name: '核准?'}},
{id: 'dummyNodeP1', label: {name: ''}, style: {shape: 'nothing', strokeWidth: 0, width:0, height:0}},
{id: 'dummyNodeD1', label: {name: '作廢'}, style: {shape: 'nothing', strokeWidth: 0, width:0, height:0}},
{id: 'dummyNodeE', label: {name: ''}, style: {shape: 'nothing', strokeWidth: 0, width:0, height:0}},
{id: 'dummyNodeD2', label: {name: '退回'}, style: {shape: 'nothing', strokeWidth: 0, width:0, height:0}},
{id: 'dummyNodeD3', label: {name: '退回'}, style: {shape: 'nothing', strokeWidth: 0, width:0, height:0}},
{id: 'end', label: {name: '結案'}, style: {fillColor: '#fff'}}
],
map: [
['', 'start'],
['', 'process1', 'dummyNodeP1'],
['dummyNodeD1', 'decision1', ''],
['', 'process2'],
['', 'decision2', 'dummyNodeD2'],
['', 'process3'],
['', 'decision3', 'dummyNodeD3'],
['dummyNodeE', 'end']
],
links: [
{source: 'start', target: 'process1'},
{source: 'process1', target: 'decision1'},
{source: 'decision1', target: 'dummyNodeD1',
label: {name: 'yes'},
style: {headType: 'none', color: '#afafaf', curveType: 'stepAfter'}
},
{source: 'decision1', target: 'process2', label: {name: 'no'}},
{source: 'dummyNodeD1', target: 'dummyNodeE', style: {headType: 'none',color: '#afafaf', curveType: 'stepBefore'}},
{source: 'dummyNodeE', target: 'end', style: {color: '#afafaf', curveType: 'stepBefore'}},
{source: 'process2', target: 'decision2'},
{source: 'decision2', target: 'dummyNodeD2',
label: {name: 'no'},
style: {color: '#afafaf', curveType: 'stepAfter'}
},
{source: 'decision2', target: 'process3', label: {name: 'yes'}},
{source: 'dummyNodeD2', target: 'dummyNodeP1', style: {headType: 'none',color: '#afafaf', curveType: 'stepBefore'}},
{source: 'dummyNodeP1', target: 'process1', style: {color: '#afafaf', curveType: 'stepBefore'}},
{source: 'process3', target: 'decision3'},
{source: 'decision3', target: 'dummyNodeD3',
label: {name: 'no'},
style: {color: '#afafaf', curveType: 'stepAfter'}
},
{source: 'decision3', target: 'end', label: {name: 'yes'}},
{source: 'dummyNodeD3', target: 'dummyNodeP1', style: {headType: 'none',color: '#afafaf', curveType: 'stepBefore'}},
]
};
var flowcharty = new Flowcharty.default();
flowcharty.nodeRX = 7;
flowcharty.nodeRY = 7;
flowcharty.nodeFillColor = "#000";
flowcharty.render(d3.select("svg"), data);
</script>