设为首页 加入收藏

TOP

canvas绘制流程图(一)
2019-09-17 18:37:24 】 浏览:116
Tags:canvas 绘制 流程图

最近在做一个需求,根据数据动态生成以下类似的流程图,需要可以设置每个节点的颜色,每个节点可添加点击移动等相关的事件

代码中有做很多的注释和说明,相关的文档说明链接:https://9eb75i.axshare.com

drawFlowChart.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'){
      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;
}
//话每个图形的箭头指向
funct
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/8/8
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Vue模板语法中数据绑定 下一篇vueSSR渲染原理

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目