用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]]; }
懒得写十进制和十六进制的转换,就搞了个上面的代码,下面见见效果图吧
鼠标移动上去会根据原有的颜色让颜色变得更深显示,这样就做了一个动态的效果