老规矩,先来一张效果图压压惊,流程来源于某宝,某鱼,某电商平台的货物流转流程,自己稍微修改了一下。仅供学习参考使用。
使用 echarts 等开源框架开发可以减少自己的开发时间,提高工作效率。
一般流程图如果仅仅是作为静态页面,不需要考虑交互还是很容易画出来的,但是如果需要考虑到交互效果,那就需要自己在基于对开源框架集成使用中多加思考了,毕竟现在很多开源框架的基本思想都是组合优于继承,所以在使用中可以很灵活的融入自己的想法。
上面所展示的流程图中很明显的可以看到三种颜色。
灰色:代表不可用,点击无效。
蓝色:代表可用,但是当前并不处于这个节点
黄色:代表当前处于这个点,或者节点被点击
在渲染流程图时要考虑通用和可扩展,可插拔,所以在渲染时,使用配置来进行渲染,也是比较符合当前主流思想。
核心代码,代码里面注释写的很详细。仔细研读。
//配置点击后有响应的模块。模块名为key , 方法名后缀为 value,方法名称要写成draw value首字母大写为函数名
var forcemap = {
'异常': 'exception'
, '质检': 'check'
, '复检': 'rqc'
, '质控': 'iqc'
, '品控': 'uqc'
, '抽检': 'random'
, '清除隐私': 'clear'
, '入库': 'in'
, '暂存': 'tally'
, '用户退货': 'returns'
, '出库': 'out'
, '库存': 'inventory'
, '上架': 'auction'
, '退货审核': 'reject'
, '库存锁定': 'lock'
};
//配置流程图的颜色,设置不可点击为灰色,可以点击为蓝色,当前点为黄色,并且点击蓝色的,把其他的都设置为蓝色,当前的设置为橘黄色
var colormap = {
'提交': '#999'
, '零售仓库': '#999'
, '发货': '#999'
, '收货': '#999'
, '付款': '#999'
, '商家退货': '#999'
, '结束': '#999'
, '维修': '#999'
, '复检': '#1b9acf'
, '异常': '#1b9acf'
, '质检': 'orange'
, '质控': '#1b9acf'
, '暂存': '#1b9acf'
, '品控': '#1b9acf'
, '用户退货': '#1b9acf'
, '入库': '#1b9acf'
, '退货审核': '#1b9acf'
, '清除隐私': '#1b9acf'
, '库存': '#1b9acf', '上架': '#1b9acf', '库存锁定': '#1b9acf', '抽检': '#1b9acf', '出库': '#1b9acf'
};
//为了颜色可以控制,将所有蓝色的节点放入list中
var seriallist = ['异常', '质检', '复检', '质控', '品控', '维修', '清除隐私', '抽检', '退货审核', '入库', '暂存', '用户退货', '出库', '库存', '上架', '库存锁定'];
//这个是点击按钮,打印handler可以看到dataindex的值,每一个都记录下来。如果渲染的流程图有变化,相应的坐标也要在代码中改变
var serialmap = {
'异常': 14
, '质检': 3
, '复检': 16
, '质控': 4
, '品控': 18
, '维修': 19
, '抽检': 20
, '清除隐私': 15
, '退货审核': 21
, '入库': 5
, '暂存': 6
, '用户退货': 17
, '出库': 11
, '库存': 8
, '上架': 9
, '库存锁定': 23
};
//具体的绘制流程图的方法
var drawforcechart = function () {
var forceoption = {
tooltip: {
trigger: 'item',
formatter: function (para) {
if (para.name == 'x' || para.name == 'y') {
//当这个点知识为了连接两条线的时候,鼠标放在上面显示空。
return '';
} else if (para.name.indexof("y") > -1 || para.name.indexof("x") > -1) {
//这个地方是为了处理复杂的转折点,可以用一个点来连接两条线,伪装成一条线。然后鼠标放在线上的时候,就会显示我们 return 的值
return '复检 > 入库';
} else {
//其他的都正式显示,自己是什么就显示什么。
return para.name;
}
}
},
animationdurationupdate: 1500,
animationeasingupdate: 'quinticinout',
textstyle: {
color: '#000'
},
series: [
{
type: 'graph',
tooltip: {
backgroundcolor: 'skyblue',
//formatter: "{b}
{a} : {c} h "
},
layout: 'none',
symbolsize: 10,
roam: false,
label: {
normal: {
show: true,
position: 'inside',
//offset: [0,-60],//居上 20
textstyle: {
fontsize: 12,
color: '#fff',
fontweight: 'bold',
},
formatter: function (para) {
//第一个判断条件是判断有5个字的
if (para.name == 'hhhhh' || para.name == 'yyyyy') {
return para.name.substring(0, 3) '\n' para.name.substring(3, 5);
} else if (para.name == '商家退货' || para.name == '库存锁定' || para.name == '零售仓库' || para.name == '清除隐私' || para.name == '用户退货' || para.name == '退货审核') {
return para.name.substring(0, 2) '\n' para.name.substring(2, 4);
} else if (para.name == 'x' || para.name == 'y') {
//转折点不显示
return '';
} else {
return para.name;
}
}
}
},
edgesymbol: ['circle', 'arrow'],
edgesymbolsize: [4, 10],
edgelabel: {
normal: {
textstyle: {
fontsize: 18
}
}
},
//注意,所有节点的位置都是根据自己设置的x, y坐标来设置的
data: [
{
name: '提交',
x: 100,
y: 300,
value: '提交',
//symbol:'rect', //让节点为矩形显示
symbolsize: 50,//节点的长和宽
itemstyle: {
normal: {
color: colormap["提交"]
}
}
},
{
name: '发货',
x: 200,
y: 300,
//symbol:'rect',
symbolsize: 50,
value: '发货',
itemstyle: {
normal: {
color: colormap["发货"]
}
}
},
{
name: '收货',
x: 300,
y: 300,
value: '收货',
//symbol:'rect',
symbolsize: [50, 50],
itemstyle: {
normal: {
color: colormap["收货"]
}
}
},
{
name: '质检',
x: 400,
y: 300,
//symbol:'rect',
symbolsize: [50, 50],
value: '质检',
itemstyle: {
normal: {
color: colormap["质检"]
}
}
},
{
name: '质控',
x: 500,
y: 300,
value: '质控',
//symbol:'rect',
symbolsize: [50, 50],
itemstyle: {
normal: {
color: colormap["质控"]
}
}
},
{
name: '入库',
x: 600,
y: 300,
value: '入库',
//symbol:'rect',
symbolsize: [50, 50],
itemstyle: {
normal: {
color: colormap["入库"]
}
}
},
{
name: '暂存',
x: 700,
y: 300,
value: '暂存',
//symbol:'rect',
symbolsize: [50, 50],
itemstyle: {
normal: {
color: colormap["暂存"]
}
}
},
{
//这个节点是转折点
name: 'y',
x: 600,
y: 400,
value: '',
//symbol:'rect',
symbolsize: [2, 2],
itemstyle: {
normal: {
color: '#1b9acf'
}
}
},
{
name: '库存',
x: 800,
y: 300,
value: '库存',
//symbol:'rect',
symbolsize: [50, 50],
itemstyle: {
normal: {
color: colormap["库存"]
}
}
},
{
name: '上架',
x: 900,
y: 300,
value: '上架',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["上架"]
}
}
},
{
name: '付款',
x: 1000,
y: 300,
value: '付款',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["付款"]
}
}
},
{
name: '出库',
x: 1100,
y: 300,
value: '出库',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["出库"]
}
}
},
{
name: '结束',
x: 1200,
y: 300,
value: '结束',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["结束"]
}
}
},
{
name: '零售仓库',
x: 150,
y: 400,
value: '零售仓库',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["零售仓库"]
}
}
},
{
name: '异常',
x: 350,
y: 200,
value: '异常',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["异常"]
}
}
},
{
name: '清除隐私',
x: 700,
y: 200,
value: '清除隐私',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["清除隐私"]
}
}
},
{
name: '复检',
x: 300,
y: 400,
value: '复检',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["复检"]
}
}
},
{
name: '用户退货',
x: 800,
y: 400,
value: '用户退货',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["用户退货"]
}
}
},
{
name: '品控',
x: 700,
y: 400,
value: '品控',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["品控"]
}
}
},
{
name: '维修',
x: 800,
y: 200,
value: '维修',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["维修"]
}
}
},
{
name: '抽检',
x: 900,
y: 200,
value: '抽检',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["抽检"]
}
}
},
{
name: '退货审核',
x: 600,
y: 500,
value: '退货审核',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["退货审核"]
}
}
},
{
name: '商家退货',
x: 1100,
y: 500,
value: '商家退货',
//symbol:'rect',
symbolsize: 50,
itemstyle: {
normal: {
color: colormap["商家退货"]
}
}
},
{
name: '库存锁定',
x: 900,
y: 400,
value: '库存锁定',
//symbol:'rect',
symbolsize: [50, 50],
itemstyle: {
normal: {
color: colormap["库存锁定"]
}
}
}
],
// links: [],
//这是点与点之间的连接关系
links: [
{
source: '提交',
target: '发货'
},
{
source: '发货',
target: '收货'
},
{
source: '收货',
target: '复检'
},
{
source: '复检',
target: 'y'//x是第一个小转折点
},
{
source: 'y',
target: '入库'
},
{
source: '收货',
target: '质检'
},
{
source: '质检',
target: '质控'
},
{
source: '质控',
target: '入库'
},
{
source: '入库',
target: '暂存'
},
{
source: '暂存',
target: '库存'
},
{
source: '库存',
target: '上架'
},
{
source: '上架',
target: '付款'
},
{
source: '付款',
target: '出库'
},
{
source: '出库',
target: '结束'
},
{
source: '提交',
target: '取货'
},
{
source: '提交',
target: '零售仓库'
},
{
source: '取货',
target: '发货'
},
{
source: '零售仓库',
target: '发货'
},
{
source: '收货',
target: '异常'
},
{
source: '异常',
target: '质检'
},
{
source: '暂存',
target: '清除隐私'
},
{
source: '暂存',
target: '品控'
},
{
source: '品控',
target: '用户退货'
},
{
source: '库存',
target: '维修'
},
{
source: '库存',
target: '抽检'
},
{
source: '抽检',
target: '库存'
},
{
source: '维修',
target: '抽检'
},
{
source: '退货审核',
target: '入库'
},
{
source: '商家退货',
target: '退货审核'
},
{
source: '出库',
target: '商家退货'
},
{
source: '库存',
target: '库存锁定'
},
{
source: '清除隐私',
target: '库存'
}
],
//线条的颜色
linestyle: {
normal: {
opacity: 0.9,
color: '#53b5ea',
type: 'dashed',
width: 1
}
}
}
]
};
var forcechart = echarts.init(document.getelementbyid('lay-index-pageone'));
forcechart.setoption(forceoption);
//监听节点点击事件
forcechart.on('click', function (handler, context) {
console.log(handler);
//节点的名称
var objname = handler.data.name;
console.log(objname);
//判断点击的节点是否在可用的 map中
console.log(forcemap.hasownproperty(objname));
if (forcemap.hasownproperty(objname)) {
//如果节点可用,则执行点击事件
//1改变节点颜色,为激活状态
forceoption.series[0].data[serialmap[objname]].itemstyle.normal.color = "orange";
//遍历所有可用节点,把其他的设置为蓝色。
for (var i = 0; i < seriallist.length; i) {
var e = seriallist[i];
if (objname != e) {
forceoption.series[0].data[serialmap[e]].itemstyle.normal.color = "#1b9acf";
}
}
//表示生效,否则只有浏览器屏幕发生变化时才会生效
forcechart.setoption(forceoption, false, false);
//获取要执行的方法的名称后缀
var modelname = forcemap[objname];
//根据自定义的规则执行要执行的方法。每个要执行的方法都是 'draw' modelname.substring(0, 1).tolocaleuppercase() modelname.substring(1, modelname.length)
//这样可以实现每个节点被点击执行对应的方法
callmodelfun('draw' modelname.substring(0, 1).tolocaleuppercase() modelname.substring(1, modelname.length));
}
//获取节点点击的数组序号
//var arrayindex = handler.dataindex;
//获取数据
//var urlparam = responsedata.data.date[arrayindex];
});
window.addeventlistener('resize', forcechart.resize);
};
//根据方法名调用方法
var callmodelfun = function(functionname) {
//根据函数名得到函数类型
var func = eval(functionname);
//创建函数对象,并调用
new func();
};
//调用方法
drawforcechart();
//蓝色的模块点击后执行的方法
var drawexception = function () {
console.log("调用异常模块");
};
var drawcheck = function () {
console.log("调用质检模块");
};
// ...
//其他的省略,只要写蓝色的也就是已经实现了的模块。