1. 程式人生 > >用svg做流程管理

用svg做流程管理

strong attr reduce val 之前 安裝 svi 好的 runt

說起流程管理這個功能,如果沒有個動態圖配合顯示,簡直就是太沒有客戶體驗感了。就比如說請假流程吧,流程走到哪一步了,流程走向過程中都那些人審批的,審批的結果等等,如果就來個列表,也不是說不行,就是覺得太不人道主義了。

曾經在上海做過流程管理,采用的IBM研發的FileNet,是一個很大型的工具,安裝復雜,而且還是付費的。而現在要開發流程管理,想必是不用考慮讓公司去購買FileNet的了,原因就不必多說了。

重要的是,即使什麽都沒有,也是可以開發流程管理的,那就是svg,對於svg我是真的愛到無法自拔的了,之前的配電室監控、場景監控用的都是svg技術,用的是一個叫raphael.js前端插件,其實也就是封裝的對svg元素的操作。

下面來講講這個開發思路,首先,肯定是要錄入流程圖的,根據不同的流程,創建不同的流程圖。

流程圖怎麽創建?總不至於要手寫svg代碼吧?慶幸的是不用,很多工具可以畫流程圖,然後導出svg文件,懶得安裝也懶得找,記得之前正好有用過網上一個免費的在線畫圖的網址(https://processon.com),就是這個了,免費、好用、免安裝,畫圖還好看,還有什麽可挑剔的,總之我是很喜歡,下面奉上一個畫好的請假流程圖

技術分享圖片

下載成svg文件就可以使用了

動態呢用js就可以控制啦,比如下面這個門使用能導航的功能

首先把svg弄到頁面中,放在body裏就可以了

技術分享圖片

然後在瀏覽器中打開這個頁面

技術分享圖片

右鍵檢查自己想要控制的方塊

技術分享圖片

就能看到自己想要控制的這個svg元素了,這裏需要控制的是這個path節點,獲取這個節點的id,配置到json中,由於id的前綴都是一樣的,只要記錄後面的數字就可以了,比如這裏的id(ProcessOnPath1030),只要記錄(1030)就可以了,下面上代碼:

var DOOR_FLOW_CHART_DATA = {
    ‘1029‘: {‘path‘: ‘1030‘, ‘url‘: ‘https://www.baidu.com/?tn=39042058_18_oem_dg‘},
    ‘1067‘: {‘path‘: ‘1068‘, ‘url‘: ‘http://fanyi.baidu.com/‘},
    
/* ‘1038‘: {path: ‘1039‘, url: ‘/accesscontrol/SystemDeviceInfo‘}, */ /* ‘1059‘: {path: ‘1060‘, url: ‘/accesscontrol/SystemDeviceInfo‘}, */ /* 添加門禁所使用的通訊服務ProcessOnG1033 */ ‘1033‘: {path: ‘1034‘, url: ‘/runtime/SystemProxyService‘}, /* 添加卡類型ProcessOnG1055 */ ‘1055‘: {path: ‘1056‘, url: ‘/card/ecardtype‘}, /* 人員發卡ProcessOnG1063 */ ‘1063‘: {path: ‘1064‘, url: ‘/card/cardinfo‘}, /* 添加門禁時間組ProcessOnG1075 */ ‘1075‘: {path: ‘1076‘, url: ‘/accesscontrol/accesscontrolsegion‘}, /* 設置門禁聯動事件及視頻聯動ProcessOnG1099 */ ‘1099‘: {path: ‘1100‘, url: ‘/gangcontrol/accessVideoControl‘}, /* 使用門禁監控功能ProcessOnG1104 */ ‘1104‘: {path: ‘1105‘, url: ‘/supervise/supervise-only-door‘, target: ‘門禁實時監控‘}, /* 門禁授權ProcessOnG1118 */ ‘1118‘: {path: ‘1119‘, url: ‘/accesscontrol/impowerdoor‘} };

只要配置好這個,所有的流程圖就是統一的一個操作了,就是根據這個配置,獲取svg節點,然後綁定事件,這裏加了mouseover、mouseout和點擊事件,見代碼:

window.onload = function () {
    for (var i in DOOR_FLOW_CHART_DATA) {
        var data = DOOR_FLOW_CHART_DATA[i];
        var path = $(‘#ProcessOnPath‘ + data.path)[0];
        
        Node_Color[data.path] = Node_Color[data.path] || {};
        var oldcolor = path.attributes["fill"].value;
        Node_Color[data.path].mouseout = oldcolor;
        Node_Color[data.path].mouseover = color2darker(oldcolor);
        
        (function(D, P){
            $(‘#ProcessOnG‘ + i).on(‘mouseover‘, function(){
                P.attributes["stroke-width"].value = 3;  //#FFEB3B
                P.attributes["fill"].value = Node_Color[D.path].mouseover;
            }).on(‘mouseout‘, function(){
                P.attributes["stroke-width"].value = 2;
                P.attributes["fill"].value = Node_Color[D.path].mouseout;
            }).on(‘click‘, function(){
                window.open(D.url, ‘_blank‘);
            }).css({‘cursor‘: ‘pointer‘});
        })(data, path);
        
    }
    
    window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
};

color2darker方法是幹嘛的呢?


是為了讓鼠標移動到節點上的時候,節點顏色加深,顏色如何加深?見代碼:
var Hex_Reduce = {
    0: "0",
    1: "0",
    2: "0",
    3: "1",
    4: "2",
    5: "3",
    6: "4",
    7: "5",
    8: "6",
    9: "7",
    a: "8",
    b: "9",
    c: "a",
    d: "b",
    e: "c",
    f: "d"
};

/**
 * 亮度計算公式
 * RGB計算色彩知覺亮度的公式
 * Y = ((R*299)+(G*587)+(B*114))/1000
 * 比如這個值:#ffcccc,ff cc cc 分別對應R G B 的值,那麽只要這三個值都變小了,自然顏色就深了
 * 下面這個方法,讓每位值都減小2,這樣就可以達到顏色變深的目的啦
 */
function color2darker(str){
    var arr = str.split("");
    return arr[0] + Hex_Reduce[arr[1]] + Hex_Reduce[arr[2]] 
        + Hex_Reduce[arr[3]] + Hex_Reduce[arr[4]] + Hex_Reduce[arr[5]] + Hex_Reduce[arr[6]];
}

懶得寫十進制和十六進制的轉換,就搞了個上面的代碼,下面見見效果圖吧

技術分享圖片

技術分享圖片

技術分享圖片

鼠標移動上去會根據原有的顏色讓顏色變得更深顯示,這樣就做了一個動態的效果




用svg做流程管理