html css画流程图,css canvas 绘制流程图(1)

//1.引入js

//画流程图

//画所有的图形:画图和画对应的箭头

function drawFlowChart(context, canvas, flowdata, initTop, initSpaceH) {

//1、判断是否有需要平均计算x的数据

flowdata.forEach(function (row) {

if (row.isAverage) {

row.data = calChartX(canvas.width, row.data, row.y);

}

});

//2、先要画完所有的图形

flowdata.forEach(function (row, rowIndex) {

row.y = row.y ? row.y : (rowIndex == 0 ? initTop + initSpaceH : initTop + initSpaceH * rowIndex);

row = drawRowChart(context, row); //画图形

});

//3、添加要指向的对象,必须要在画完所有图形之后

flowdata.forEach(function (row) {

row.data.forEach(function (item) {

if (item.arrowArr && item.arrowArr.length) {

item.arrowArr.forEach(function (mItem) {

mItem = addToObj(mItem, flowdata);

})

}

})

});

//4、给所有图形画上对应的画箭头,必须要在前两步完成之后

flowdata.forEach(function (row, rowIndex) {

row.data.forEach(function (item) {

if (item.arrowArr && item.arrowArr.length) {

drawSingleArrow(context, item);//画箭头

}

})

});

//5、给所有元素添加点击和悬浮事件

addMethod(canvas, flowdata)

}

//当一行有n个图形并且需要平均排列时用此方法计算每个图形的x

function calChartX(canvasW, data, dataY) {

var startW = 80;

var stepW = 120;

var CondW = 30;

var count = 0;

for (var i = 0; i < data.length; i++) {

if (data[i].type == 'Step') {

if (data[i].direction != undefined) {

stepW = -120;

}

count += stepW;

} else if (data[i].type == 'Start' || data[i].type == 'End') {

count += startW;

} else if (data[i].type == 'Condition') {

count += CondW;

}

}

//spaceW 计算一行中每个图形的平均间距

var spaceW = parseInt((canvasW - count) / (data.length + 1));

//计算坐标x

var prevDiv = [], curW = 0;

for (var i = 0; i < data.length; i++) {

if (data[i].type == 'Step') {

prevDiv.push(stepW);

curW = stepW / 2;

} else if (data[i].type == 'Start' || data[i].type == 'End') {

prevDiv.push(startW);

curW = startW / 2;

} else if (data[i].type == 'Condition') {

prevDiv.push(CondW);

curW = CondW / 2;

}

var preLength = 0;

for (var j = 0; j < i; j++) {

preLength += prevDiv[j];

}

var x = spaceW * (i + 1) + preLength + curW;

var y = data[i].y;

data[i]['x'] = x;

data[i]['y'] = y ? y : dataY;

}

return data;

}

//生成每列对应的图形

function drawRowChart(context, row) {

row.data.forEach(function (item, index) {

var s = null;

item.y = item.y ? item.y : row.y;

if (item.type == 'Step') {

s = new Step(context, item.x, item.y, item);

} else if (item.type == 'Condition') {

s = new Condition(context, item.x, item.y, item);

} else if (item.type == 'End') {

s = new End(context, item.x, item.y, item);

} else if (item.type == 'Start') {

s = new Start(context, item.x, item.y, item);

}

item.chartObj = s;

})

return row;

}

//绘制单个的图形

function drawSingleChart(context, item) {

var s = '';

if (item.type == 'Step') {

s = new Step(context, item.x, item.y, item);

} else if (item.type == 'Condition') {

s = new Condition(context, item.x, item.y, item);

} else if (item.type == 'End') {

s = new End(context, item.x, item.y, item);

} else if (item.type == 'Start') {

s = new Start(context, item.x, item.y, item);

}

item.chartObj = s;

return item;

}

//每个对象的坐标范围

function calRange(obj) {

var newObj = {

minX: obj.x - obj.w / 2,

maxX: obj.x + obj.w / 2,

minY: obj.y - obj.h / 2,

maxY: obj.y + obj.h / 2

}

return newObj;

}

//处理每一个箭头需要指向的对象

function addToObj(arrObj, flowData) {

flowData.forEach(function (rows) {

rows.data.forEach(function (item) {

if (item.name == arrObj.to) {

arrObj.to = item.chartObj;

}

})

})

return arrObj;

}

//话每个图形的箭头指向

function drawSingleArrow(context, data) {

var step1 = data.chartObj;

if (data.arrowArr && data.arrowArr.length) {

data.arrowArr.forEach(function (item) {

step1[item.arrow](item.to, context);

})

}

}

//清除单个图形

function repaintSingleChart(context, item) {

var range = item.chartObj.range;

//清除之前画的图形

context.clearRect(range.minX - 1, range.minY - 1, item.chartObj.w + 2, item.chartObj.h + 3);

}

//给所有图形添加事件

function addMethod(canvas, flowData) {

//给所有图形添加点击事件

canvas.onclick = function (ev) {

var ev = ev || window.event;

var ua = navigator.userAgent.toLowerCase();

var isIE = ua.indexOf("compatible") > -1 && ua.indexOf("msie") > -1 && !ua.indexOf("opera") > -1; //IE浏览器

var isEdge = ua.indexOf("Edge") > -1;

var isIE11 = ua.toLowerCase().match(/rv:([\d.]+)\) like gecko/);

var curx = (isIE || isEdge || isIE11) ? ev.offsetX : ev.layerX;

var cury = (isIE || isEdge || isIE11) ? ev.offsetY : ev.layerY;

flowData.forEach(function (row, listIndex) {

row.data.forEach(function (item) {

var range = item.chartObj.range;

if (curx >= range.minX && curx <= range.maxX && cury >= range.minY && cury <= range.maxY) {

var clickMethod = null;

if (row.method && row.method.onclick) { //如果每行定义了事件

//判断每个元素是否有单独定义事件,如果有,取改元素定义的事件,如果没有取每行定义的事件

if (item.method &

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值