用svg做流程管理

说起流程管理这个功能,如果没有个动态图配合显示,简直就是太没有客户体验感了。就比如说请假流程吧,流程走到哪一步了,流程走向过程中都那些人审批的,审批的结果等等,如果就来个列表,也不是说不行,就是觉得太不人道主义了。

曾经在上海做过流程管理,采用的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]];
}

懒得写十进制和十六进制的转换,就搞了个上面的代码,下面见见效果图吧

鼠标移动上去会根据原有的颜色让颜色变得更深显示,这样就做了一个动态的效果




原文地址:https://www.cnblogs.com/LcxSummer/p/9343269.html