• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

在vue实现流程图

武飞扬头像
干前端的小阳哥
帮助1

第一步:需要一个flow.js作为依据,可自取。

  1.  
    /************************************************
  2.  
    * 业务流程显示、绘制基础类
  3.  
    * */
  4.  
    // 扩展图形和文本拖动
  5.  
    (function (R) {
  6.  
    R.el.draggable = function (move, start, up) {
  7.  
    this._ui = this._ui || {};
  8.  
     
  9.  
    var that = this;
  10.  
     
  11.  
    this._ui.onMove = R.is(move, 'function') ? move : function (distanceX, distanceY, x, y, deltaX, deltaY) {
  12.  
    that.translate(deltaX, deltaY);
  13.  
    };
  14.  
     
  15.  
    this._ui.onStart = R.is(start, 'function') ? start : function (x, y) { };
  16.  
     
  17.  
    this._ui.onEnd = R.is(up, 'function') ? up : function (x, y) { };
  18.  
     
  19.  
    function onMove(distanceX, distanceY, x, y) {
  20.  
    var deltaX = x - that._ui.lastX;
  21.  
    var deltaY = y - that._ui.lastY;
  22.  
    that._ui.lastX = x;
  23.  
    that._ui.lastY = y;
  24.  
    if (that.label) {
  25.  
    that.label.attr({ x: that.labelPoint.x deltaX, y: that.labelPoint.y deltaY });
  26.  
    that.labelPoint.x = that.labelPoint.x deltaX;
  27.  
    that.labelPoint.y = that.labelPoint.y deltaY;
  28.  
    }
  29.  
    that._ui.onMove(distanceX, distanceY, x, y, deltaX, deltaY);
  30.  
    try {
  31.  
    that.paper.safari();
  32.  
    } catch (e) {
  33.  
    console.log("not safari brower, don't care this message.");
  34.  
    }
  35.  
    };
  36.  
     
  37.  
    function onStart(x, y) {
  38.  
    that._ui.lastX = x;
  39.  
    that._ui.lastY = y;
  40.  
    that._ui.ddx = x - that.cfg.posLeft;
  41.  
    that._ui.ddy = y - that.cfg.posTop;
  42.  
    that._ui.onStart(x, y);
  43.  
    };
  44.  
     
  45.  
    function onEnd(event) {
  46.  
    that.cfg.posLeft = event.x - that._ui.ddx;
  47.  
    that.cfg.posTop = event.y - that._ui.ddy;
  48.  
    that._ui.onEnd(event.x, event.y);
  49.  
    };
  50.  
     
  51.  
    return this.drag(onMove, onStart, onEnd);
  52.  
    };
  53.  
     
  54.  
    // 每个业务业务流程对应一个 BF 对象
  55.  
    // BF 包含一组静态对象,用于设置节点、连线的样式
  56.  
    // BF 包含一个对象组,包括:大按钮、流程节点(含:链接、分支)、连线、文本;这些对象支持选中、删除、拖动等操作。
  57.  
    BF = {
  58.  
    // 大按钮
  59.  
    ButtonTextStyle: { "font-size": "14pt", "stroke": "#eaeeff", "font-weight": "1", "font-family":"helvetica, arial, verdana, sans-serif"},
  60.  
    ButtonBoxStyle: { "stroke": "#054ea7", "stroke-width": "1", "fill": "#386aa3" },
  61.  
    ButtonLinkStyle: { "font-size": "14pt", "stroke": "#eaeeff", "font-weight": "100", cursor: "pointer" },
  62.  
    ButtonSelectedStyle: { "stroke": "#bd760d", "stroke-width": "2px", "fill": "#bd760d", cursor: "move" },
  63.  
    ButtonProperty: { nodeIdx: 1, nodeType: "button", posLeft: 30, posTop: 30, nodeWidth: 120, nodeHeight: 75, text: "子模块", title: "", jsurl: "" },
  64.  
     
  65.  
    // 流程节点
  66.  
    NodeTextStyle: { "font-size": "12px", "stroke": "#09095a", "font-family":"helvetica, arial, verdana, sans-serif" },
  67.  
    NodeBoxStyle: { "stroke": "#b8b8b8", "stroke-width": 1, "fill": "#e5e9f1" },
  68.  
    NodeSelectedStyle: { "stroke": "#bd760d", "stroke-width": "2px", "fill": "#bd760d", cursor: "move" },
  69.  
    NodeLinkStyle: { "font-size": "12px", "stroke": "#093eec", "text-decoration": "underline", cursor: "pointer" },
  70.  
    NodeProperty: { nodeIdx: 2, nodeType: "node", posLeft: 30, posTop: 100, nodeWidth: 120, nodeHeight: 75, text: "流程节点", title: "", inLine: "", outLine: "", jsurl: "" },
  71.  
    BranchProperty: { nodeIdx: 3, nodeType: "branch", posLeft: 30, posTop: 180, nodeWidth: 120, nodeHeight: 75, text: "流程分支", title: "", inLine: "", outLine: "", jsurl: "" },
  72.  
     
  73.  
    // 连线
  74.  
    LineTextStyle: { "font-size": "12px", "stroke": "#09095a", "font-family":"helvetica, arial, verdana, sans-serif"},
  75.  
    LineStyle: { "arrow-end": "classic-wide-long", "stroke": "#9baaaf", "stroke-width": 2 },
  76.  
    LineSelectedStyle: { "arrow-end": "classic-wide-long", "stroke": "#d2d426", "stroke-width": 2, cursor: "move" },
  77.  
    LineProperty: { nodeIdx: 4, nodeType: "line", posLeft: 30, posTop: 30, endX: 60, endY: 60, text: "", title: "" },
  78.  
     
  79.  
    // 流程备注文本
  80.  
    RemarkBoxStyle: { "stroke": "#cdd0d8", "stroke-width": 1, "fill": "#e5e9f1", "opacity": 30 },
  81.  
    RemarkTextStyle: { "font-size": "12px", "stroke": "#130205", "text-anchor": "start", "font-family":"helvetica, arial, verdana, sans-serif" },
  82.  
    RemarkSelectedStyle: { "font-size": "12px", "stroke": "#bd760d" },
  83.  
    RemarkProperty: { nodeIdx: 5, nodeType: "remark", posLeft: 30, posTop: 270, nodeWidth: 300, nodeHeight: 185, text: "备注:\n这是一段备注文字" },
  84.  
     
  85.  
    // 热区样式
  86.  
    HotPointStyle: { "stroke": "#d1d86f", "stroke-width": 1, "fill": "#f34832" },
  87.  
     
  88.  
    // 复制属性的函数
  89.  
    ocopy: function (o, c) {
  90.  
    if (o && c && typeof c == 'object') {
  91.  
    for (var p in c) {
  92.  
    o[p] = c[p];
  93.  
    }
  94.  
    }
  95.  
    return o;
  96.  
    },
  97.  
     
  98.  
    // 选中节点时的回调函数,调用程序给出,传入选中的图形序号
  99.  
    OnSelectNode: null,
  100.  
     
  101.  
    // 划线状态是否已开启
  102.  
    DrawLineMode: false,
  103.  
     
  104.  
    // 半径 5 像素的圆圈内认为是热点
  105.  
    HotDistance: 5,
  106.  
     
  107.  
    // 执行流程图中点击动作的函数,参数为这里设置的 url
  108.  
    OnClickRun: null,
  109.  
     
  110.  
    // 画布尺寸
  111.  
    PaperWidth: 2000,
  112.  
    PaperHeight: 1800
  113.  
    };
  114.  
     
  115.  
    // 构造一个业务流程图
  116.  
    // 必须参数 canvas, 画布,指定一个 div 的名称
  117.  
    // 必须参数 ploting, true表示绘制,可以增删改图形;false 表示静态展示流程图
  118.  
    // 可选参数 nodes 为流程图节点配置结构,缺失将仅显示开始和结束两个节点,config 的数据结构如下
  119.  
    BF.create = function (canvas, ploting, nodes) {
  120.  
    var bf = {};
  121.  
    // 初始化画布
  122.  
    bf.paper = R(canvas, BF.PaperWidth, BF.PaperHeight);
  123.  
     
  124.  
    // 对象容器,存储绘制的节点 绘制的连线;只包括其配置信息
  125.  
    bf.container = new Array();
  126.  
     
  127.  
    // 上述容器中最后选中的对象的序号,-1 表示没有选中任何对象
  128.  
    bf.lastSelect = -1;
  129.  
     
  130.  
    // 当前未使用的最大节点序号, 1--9999
  131.  
    bf.maxNodeIndex = 2;
  132.  
     
  133.  
    // 判断一条线是否连接在一个图形的热点
  134.  
    bf.ishot = function (lineCfg, boxCfg) {
  135.  
    if (Math.abs(boxCfg.posLeft boxCfg.nodeWidth / 2 - lineCfg.posLeft) Math.abs(boxCfg.posTop - lineCfg.posTop) < 5) { // 线起点 = 上中点
  136.  
    return 1;
  137.  
    } else if (Math.abs(boxCfg.posLeft boxCfg.nodeWidth - lineCfg.posLeft) Math.abs(boxCfg.posTop boxCfg.nodeHeight / 2 - lineCfg.posTop) < 5) { // 线起点 = 右中点
  138.  
    return 2;
  139.  
    } else if (Math.abs(boxCfg.posLeft boxCfg.nodeWidth / 2 - lineCfg.posLeft) Math.abs(boxCfg.posTop boxCfg.nodeHeight - lineCfg.posTop) < 5) { // 线起点 = 下中点
  140.  
    return 3;
  141.  
    } else if (Math.abs(boxCfg.posLeft - lineCfg.posLeft) Math.abs(boxCfg.posTop boxCfg.nodeHeight / 2 - lineCfg.posTop) < 5) { // 线起点 = 左中点
  142.  
    return 4;
  143.  
    } else if (Math.abs(boxCfg.posLeft boxCfg.nodeWidth / 2 - lineCfg.endX) Math.abs(boxCfg.posTop - lineCfg.endY) < 5) { // 线终点 = 上中点
  144.  
    return 5;
  145.  
    } else if (Math.abs(boxCfg.posLeft boxCfg.nodeWidth - lineCfg.endX) Math.abs(boxCfg.posTop boxCfg.nodeHeight / 2 - lineCfg.endY) < 5) { // 线终点 = 右中点
  146.  
    return 6;
  147.  
    } else if (Math.abs(boxCfg.posLeft boxCfg.nodeWidth / 2 - lineCfg.endX) Math.abs(boxCfg.posTop boxCfg.nodeHeight - lineCfg.endY) < 5) { // 线终点 = 下中点
  148.  
    return 7;
  149.  
    } else if (Math.abs(boxCfg.posLeft - lineCfg.endX) Math.abs(boxCfg.posTop boxCfg.nodeHeight / 2 - lineCfg.endY) < 5) { // 线终点 = 左中点
  150.  
    return 8;
  151.  
    } else {
  152.  
    return 0;
  153.  
    }
  154.  
    };
  155.  
     
  156.  
    // 开启连线绘制,显示所有热区点,禁用所有拖动
  157.  
    bf.hotpoints = new Array();
  158.  
    bf.startLine = function () {
  159.  
    for (var z = 0; z < bf.container.length; z ) {
  160.  
    var obj = bf.container[z].img;
  161.  
    if (obj.cfg.nodeType == "button" || obj.cfg.nodeType == "node") {
  162.  
    bf.hotpoints.push(bf.paper.circle(obj.cfg.posLeft obj.cfg.nodeWidth / 2, obj.cfg.posTop, 5).attr(BF.HotPointStyle));
  163.  
    bf.hotpoints.push(bf.paper.circle(obj.cfg.posLeft obj.cfg.nodeWidth, obj.cfg.posTop obj.cfg.nodeHeight / 2, 5).attr(BF.HotPointStyle));
  164.  
    bf.hotpoints.push(bf.paper.circle(obj.cfg.posLeft obj.cfg.nodeWidth / 2, obj.cfg.posTop obj.cfg.nodeHeight, 5).attr(BF.HotPointStyle));
  165.  
    bf.hotpoints.push(bf.paper.circle(obj.cfg.posLeft, obj.cfg.posTop obj.cfg.nodeHeight / 2, 5).attr(BF.HotPointStyle));
  166.  
    } else if (obj.cfg.nodeType == "branch") {
  167.  
    bf.hotpoints.push(bf.paper.circle(obj.cfg.posLeft obj.cfg.nodeWidth / 2, obj.cfg.posTop, 5).attr(BF.HotPointStyle));
  168.  
    bf.hotpoints.push(bf.paper.circle(obj.cfg.posLeft obj.cfg.nodeWidth, obj.cfg.posTop obj.cfg.nodeHeight / 2, 5).attr(BF.HotPointStyle));
  169.  
    bf.hotpoints.push(bf.paper.circle(obj.cfg.posLeft obj.cfg.nodeWidth / 2, obj.cfg.posTop obj.cfg.nodeHeight, 5).attr(BF.HotPointStyle));
  170.  
    bf.hotpoints.push(bf.paper.circle(obj.cfg.posLeft, obj.cfg.posTop obj.cfg.nodeHeight / 2, 5).attr(BF.HotPointStyle));
  171.  
    }
  172.  
    obj.undrag();
  173.  
    }
  174.  
    BF.DrawLineMode = true;
  175.  
     
  176.  
    };
  177.  
     
  178.  
    // 停止划线时,清除所有热点,恢复可以拖动
  179.  
    bf.stopLine = function () {
  180.  
    for (var i = bf.hotpoints.length - 1; i >= 0; i--) {
  181.  
    bf.hotpoints[i].remove();
  182.  
    }
  183.  
    bf.hotpoints = new Array();
  184.  
    for (var z = 0; z < bf.container.length; z ) {
  185.  
    var obj = bf.container[z].img;
  186.  
    obj.draggable();
  187.  
    }
  188.  
    BF.DrawLineMode = false;
  189.  
    };
  190.  
     
  191.  
    // 执行一个JS函数,要求全命名空间且已实例化
  192.  
    bf.runFunc = function (jsurl) {
  193.  
    if (typeof (BF.OnClickRun) == "function") {
  194.  
    BF.OnClickRun(jsurl);
  195.  
    }else{
  196.  
    console.log("尚未指定调用函数 BF.OnClickRun");
  197.  
    }
  198.  
    };
  199.  
     
  200.  
    // 一个绘图对象的绘制
  201.  
    bf.rimg = function (plot, cfg) {
  202.  
    // 属性确定
  203.  
    var imgStyle = { title: cfg.title };
  204.  
    var textStyle = { title: cfg.title };
  205.  
    var selStyle = { title: cfg.title };
  206.  
    if (cfg.nodeType == 'button') {
  207.  
    imgStyle = BF.ocopy(imgStyle, BF.ButtonBoxStyle);
  208.  
    selStyle = BF.ocopy(selStyle, BF.ButtonSelectedStyle);
  209.  
    if (cfg.jsurl != "") {
  210.  
    textStyle = BF.ocopy(textStyle, BF.ButtonLinkStyle);
  211.  
    } else {
  212.  
    textStyle = BF.ocopy(textStyle, BF.ButtonTextStyle);
  213.  
    }
  214.  
    } else if (cfg.nodeType == 'node' || cfg.nodeType == 'branch') {
  215.  
    imgStyle = BF.ocopy(imgStyle, BF.NodeBoxStyle);
  216.  
    if (cfg.jsurl != "") {
  217.  
    textStyle = BF.ocopy(textStyle, BF.NodeLinkStyle);
  218.  
    } else {
  219.  
    textStyle = BF.ocopy(textStyle, BF.NodeTextStyle);
  220.  
    }
  221.  
    selStyle = BF.ocopy(selStyle, BF.NodeSelectedStyle);
  222.  
    } else if (cfg.nodeType == 'line') {
  223.  
    imgStyle = BF.ocopy(imgStyle, BF.LineStyle);
  224.  
    textStyle = BF.ocopy(textStyle, BF.LineTextStyle);
  225.  
    selStyle = BF.ocopy(selStyle, BF.LineSelectedStyle);
  226.  
    } else if (cfg.nodeType == 'remark') {
  227.  
    imgStyle = BF.ocopy(imgStyle, BF.RemarkBoxStyle);
  228.  
    textStyle = BF.ocopy(textStyle, BF.RemarkTextStyle);
  229.  
    selStyle = BF.ocopy(selStyle, BF.RemarkSelectedStyle);
  230.  
    }
  231.  
    // 绘制图形
  232.  
    if (cfg.nodeType == "button" || cfg.nodeType == "node" || cfg.nodeType == "branch") {
  233.  
    if (cfg.nodeType == "branch") {
  234.  
    // 画闭合折线 M130,30 L200,30 L160,90 z
  235.  
    this.img = bf.paper.path("M" cfg.posLeft "," (cfg.posTop cfg.nodeHeight / 2) " L" (cfg.posLeft cfg.nodeWidth / 2) "," cfg.posTop " L" (cfg.posLeft cfg.nodeWidth) "," (cfg.posTop cfg.nodeHeight / 2) " L" (cfg.posLeft cfg.nodeWidth / 2) "," (cfg.posTop cfg.nodeHeight) " z").attr(imgStyle);
  236.  
    } else {
  237.  
    this.img = bf.paper.rect(cfg.posLeft, cfg.posTop, cfg.nodeWidth, cfg.nodeHeight, 0).attr(imgStyle);
  238.  
    }
  239.  
    this.img.labelPoint = { x: cfg.posLeft cfg.nodeWidth / 2, y: cfg.posTop cfg.nodeHeight / 2 };
  240.  
    this.img.label = bf.paper.text(this.img.labelPoint.x, this.img.labelPoint.y, cfg.text).attr(textStyle);
  241.  
    } else if (cfg.nodeType == "line") {
  242.  
    this.img = bf.paper.path("M" cfg.posLeft "," cfg.posTop " L" cfg.endX "," cfg.endY).attr(imgStyle);
  243.  
    if (cfg.text != "") {
  244.  
    if (Math.abs(cfg.endY - cfg.posTop) < 5) { // 视作水平
  245.  
    this.img.labelPoint = { x: (cfg.posLeft cfg.endX) / 2, y: cfg.endY 20 };
  246.  
    this.img.label = bf.paper.text(this.img.labelPoint.x, this.img.labelPoint.y, cfg.text).attr(textStyle);
  247.  
    } else if (Math.abs(cfg.endX - cfg.posLeft) < 5) { // 视作垂直
  248.  
    this.img.labelPoint = { x: cfg.posLeft 20, y: (cfg.posTop cfg.endY) / 2 };
  249.  
    this.img.label = bf.paper.text(this.img.labelPoint.x, this.img.labelPoint.y, cfg.text).attr(textStyle);
  250.  
    }
  251.  
    }
  252.  
    } else if (cfg.nodeType == "remark") {
  253.  
    this.img = bf.paper.rect(cfg.posLeft, cfg.posTop, cfg.nodeWidth, cfg.nodeHeight, 0).attr(imgStyle);
  254.  
    // 文本是居左、居上的
  255.  
    this.img.labelPoint = { x: cfg.posLeft 10, y: cfg.posTop cfg.nodeHeight / 2 };
  256.  
    this.img.label = bf.paper.text(this.img.labelPoint.x, this.img.labelPoint.y, cfg.text).attr(textStyle);
  257.  
    }
  258.  
    // 绑定数据
  259.  
    bf.maxNodeIndex ;
  260.  
    this.img.cfg = BF.ocopy({}, cfg);
  261.  
    this.img.imgStyle = BF.ocopy({}, imgStyle);
  262.  
    this.img.textStyle = BF.ocopy({}, textStyle);
  263.  
    this.img.selStyle = BF.ocopy({}, selStyle);
  264.  
     
  265.  
    // 设计状态下配置拖动绘制对象的整体
  266.  
    _n = this;
  267.  
    if (plot) {
  268.  
    _n.img.attr({ cursor: "move" });
  269.  
    _n.img.draggable();
  270.  
    } else {
  271.  
    _n.img.attr({ cursor: "pointer" });
  272.  
    // 浏览状态下的点击响应
  273.  
    _n.img.click(function (e) {
  274.  
    for (var z = 0; z < bf.container.length; z ) {
  275.  
    var obj = bf.container[z].img;
  276.  
    var srco = bf.paper.getById(e.srcElement.raphaelid);
  277.  
    if (obj.cfg.nodeIdx == srco.cfg.nodeIdx) {
  278.  
    bf.runFunc(obj.cfg.jsurl);
  279.  
    }
  280.  
    }
  281.  
    });
  282.  
    if(_n.img.label){
  283.  
    _n.img.label.attr({ cursor: "pointer" });
  284.  
    _n.img.label.click(function (e) {
  285.  
    for (var z = 0; z < bf.container.length; z ) {
  286.  
    var obj = bf.container[z].img;
  287.  
    var srco = bf.paper.getById(e.srcElement.parentElement==null?e.srcElement.parentNode.raphaelid:e.srcElement.parentElement.raphaelid);
  288.  
    if (obj.label && obj.label.id == srco.id) {
  289.  
    bf.runFunc(obj.cfg.jsurl);
  290.  
    }
  291.  
    }
  292.  
    });
  293.  
    };
  294.  
    }
  295.  
     
  296.  
    // 返回节点
  297.  
    return this;
  298.  
    };
  299.  
     
  300.  
    // 双击取消选中事件
  301.  
    if (ploting) {
  302.  
    // 所有热点可以进行画线
  303.  
    // 1. 鼠标经过图形热点区时,绘制热点提示按下鼠标,按下鼠标时记录热点坐标为直线起点,对象记录流出直线的id;移出热点区域时,删除临时热点
  304.  
    // 2. 鼠标经过图形热点区时,绘制热点提示释放鼠标,释放鼠标时记录热点坐标为直线终点,对象记录流入直线的id;移出热点区域时,删除临时热点
  305.  
    bf.lineCfg = BF.ocopy({}, BF.LineProperty);
  306.  
    bf.tempLine = null;
  307.  
    document.onmousedown = function (event) {
  308.  
    if (BF.DrawLineMode) {
  309.  
    // 查找最近的热点,用热点中心作为起点
  310.  
    for (var h = 0; h < bf.hotpoints.length; h ) {
  311.  
    var hot = bf.hotpoints[h];
  312.  
    if (hot.id == event.srcElement.raphaelid) {
  313.  
    bf.lineCfg.nodeIdx = bf.maxNodeIndex ;
  314.  
    bf.lineCfg.posLeft = hot.attr("cx");
  315.  
    bf.lineCfg.posTop = hot.attr("cy");
  316.  
    bf.lineCfg.endX = isNaN(event.layerX) ? -1 : event.layerX;
  317.  
    bf.lineCfg.endY = isNaN(event.layerY) ? -1 : event.layerY;
  318.  
    if (bf.lineCfg.endX > 0 && bf.lineCfg.endY > 0) {
  319.  
    try {
  320.  
    bf.tempLine = bf.paper.path("M" bf.lineCfg.posLeft "," bf.lineCfg.posTop "L" bf.lineCfg.endX*1 "," bf.lineCfg.endY*1).attr(BF.LineStyle);
  321.  
    } catch (e) {
  322.  
     
  323.  
    }
  324.  
    }
  325.  
    break;
  326.  
    }
  327.  
    }
  328.  
    }
  329.  
    };
  330.  
    document.onmousemove = function (event) {
  331.  
    if (BF.DrawLineMode && bf.tempLine != null) {
  332.  
    // 删除旧线画新线
  333.  
    bf.tempLine.remove();
  334.  
    bf.lineCfg.endX = isNaN(event.layerX) ? -1 : event.layerX;
  335.  
    bf.lineCfg.endY = isNaN(event.layerY) ? -1 : event.layerY;
  336.  
    if (bf.lineCfg.endX > 0 && bf.lineCfg.endY > 0) {
  337.  
    try {
  338.  
    bf.tempLine = bf.paper.path("M" bf.lineCfg.posLeft "," bf.lineCfg.posTop "L" bf.lineCfg.endX*1 "," bf.lineCfg.endY*1).attr(BF.LineStyle);
  339.  
    } catch (e) {
  340.  
     
  341.  
    }
  342.  
    }
  343.  
    }
  344.  
    };
  345.  
    document.onmouseup = function (event) {
  346.  
    if (BF.DrawLineMode && bf.tempLine) {
  347.  
    // 找到最近的热点完成画线;如果未找到最近热点,则画线失败
  348.  
    bf.tempLine.remove();
  349.  
    bf.tempLine = null;
  350.  
    for (var h = 0; h < bf.hotpoints.length; h ) {
  351.  
    var hot = bf.hotpoints[h];
  352.  
    if (hot.id == event.srcElement.raphaelid) {
  353.  
    bf.lineCfg.endX = hot.attr("cx");
  354.  
    bf.lineCfg.endY = hot.attr("cy");
  355.  
    bf.container.push(new bf.rimg(true, bf.lineCfg));
  356.  
    break;
  357.  
    }
  358.  
    }
  359.  
    }
  360.  
    };
  361.  
    document.onclick = function (event, x, y) {
  362.  
    if (!BF.DrawLineMode) {
  363.  
    var imgid = event.srcElement.raphaelid;
  364.  
    var domid = event.srcElement.id;
  365.  
    if (imgid) {
  366.  
    var srco = bf.paper.getById(imgid);
  367.  
    for (var z = 0; z < bf.container.length; z ) {
  368.  
    var obj = bf.container[z].img;
  369.  
    if (obj.cfg.nodeIdx == srco.cfg.nodeIdx) {
  370.  
    obj.attr(obj.selStyle);
  371.  
    bf.lastSelect = z;
  372.  
    bf.runFunc(obj.cfg.jsurl);
  373.  
    } else {
  374.  
    obj.attr(obj.imgStyle);
  375.  
    }
  376.  
    }
  377.  
    if (typeof (BF.OnSelectNode) == "function") {
  378.  
    BF.OnSelectNode(bf.lastSelect);
  379.  
    }
  380.  
    } else if (domid == "") {
  381.  
    // 点击空白区
  382.  
    if (bf.lastSelect >= 0) {
  383.  
    var obj = bf.container[bf.lastSelect].img;
  384.  
    obj.attr(obj.imgStyle);
  385.  
    }
  386.  
    bf.lastSelect = -1;
  387.  
    if (typeof (BF.OnSelectNode) == "function") {
  388.  
    BF.OnSelectNode(bf.lastSelect);
  389.  
    }
  390.  
    }
  391.  
    }
  392.  
    };
  393.  
    };
  394.  
     
  395.  
    // 删除绘图对象,包括节点和连线两种
  396.  
    bf.remove = function () {
  397.  
    if (bf.lastSelect < 0) {
  398.  
    return;
  399.  
    }
  400.  
    var delo = bf.container[bf.lastSelect].img;
  401.  
    if (delo) {
  402.  
    if (delo.label) {
  403.  
    delo.label.remove();
  404.  
    }
  405.  
    delo.remove();
  406.  
    }
  407.  
    bf.container.splice(bf.lastSelect, 1);
  408.  
    // 取消选中
  409.  
    bf.lastSelect = -1;
  410.  
    if (typeof (BF.OnSelectNode) == "function") {
  411.  
    BF.OnSelectNode(bf.lastSelect);
  412.  
    }
  413.  
    };
  414.  
     
  415.  
    // 提取绘制数据
  416.  
    bf.getNodes = function () {
  417.  
    var data = new Array();
  418.  
    for (var i = 0; i < bf.container.length; i ) {
  419.  
    if (bf.container[i].img.cfg.nodeIdx > 0) {
  420.  
    data.push(bf.container[i].img.cfg);
  421.  
    }
  422.  
    }
  423.  
    return data;
  424.  
    };
  425.  
     
  426.  
    // 设置节点属性,需要重绘图像
  427.  
    bf.configNode = function (config) {
  428.  
    if (bf.lastSelect < 0) {
  429.  
    return;
  430.  
    }
  431.  
    // 强制数字转换
  432.  
    config.posLeft = config.posLeft * 1;
  433.  
    config.posTop = config.posTop * 1;
  434.  
    config.nodeWidth = config.nodeWidth * 1;
  435.  
    config.nodeHeight = config.nodeHeight * 1;
  436.  
    if(config.endX && config.endX != ""){
  437.  
    config.endX = config.endX*1;
  438.  
    config.endY = config.endY*1;
  439.  
    }
  440.  
    var obj = bf.container[bf.lastSelect].img;
  441.  
    var cfg = BF.ocopy({}, obj.cfg);
  442.  
    cfg = BF.ocopy(cfg, config);
  443.  
    // 重绘
  444.  
    if (obj.label) {
  445.  
    obj.label.remove();
  446.  
    }
  447.  
    obj.remove();
  448.  
    bf.container.splice(bf.lastSelect, 1);
  449.  
    bf.container.push(new bf.rimg(ploting, cfg));
  450.  
    bf.lastSelect = bf.container.length - 1;
  451.  
    // if (typeof (BF.OnSelectNode) == "function") {
  452.  
    // BF.OnSelectNode(bf.lastSelect);
  453.  
    // }
  454.  
    };
  455.  
     
  456.  
    // 添加任务节点,分大按钮、流程节点、分支、备注文本
  457.  
    bf.addNode = function (node) {
  458.  
    node.nodeIdx = bf.maxNodeIndex ;
  459.  
    bf.container.push(new bf.rimg(ploting, node));
  460.  
    bf.lastSelect = bf.container.length - 1;
  461.  
    if (typeof (BF.OnSelectNode) == "function") {
  462.  
    BF.OnSelectNode(bf.lastSelect);
  463.  
    }
  464.  
    };
  465.  
     
  466.  
    // 初始化时,如果未指定nodes,则画出两个示例块
  467.  
    if (typeof (nodes) == "undefined" || nodes.length == 0) {
  468.  
    nodes = new Array();
  469.  
    }
  470.  
     
  471.  
    // 绘制对象
  472.  
    for (var i = 0; i < nodes.length; i ) {
  473.  
    var node = nodes[i];
  474.  
    if (bf.maxNodeIndex < node.nodeIdx) {
  475.  
    bf.maxNodeIndex = node.nodeIdx;
  476.  
    }
  477.  
    bf.container.push(new bf.rimg(ploting, node));
  478.  
    }
  479.  
     
  480.  
    return bf;
  481.  
    };
  482.  
     
  483.  
    })(Raphael);
学新通

之后再你的组件中将这个文件引入,

import '@/untils/flow.js';

之后就是对 其中的方法进行调用即可,废话不多说,直接上代码

  1.  
    <template>
  2.  
    <div style="width: 100%">
  3.  
    <button @click="btn">点击</button>
  4.  
    <button @click="btns">改变</button>
  5.  
    <button @click="edit">修改</button>
  6.  
    <button @click="addProcess">添加流程</button>
  7.  
    <div style="display: flex'">
  8.  
    <div style="width: 19%; border: 1px solid red">
  9.  
    <a-select
  10.  
    style="width: 300px"
  11.  
    v-model="form.region"
  12.  
    @change="handleChange"
  13.  
    placeholder="please select your zone"
  14.  
    >
  15.  
    <a-select-option value="shanghai"> 上海 </a-select-option>
  16.  
    <a-select-option value="beijing"> 北京 </a-select-option>
  17.  
    </a-select>
  18.  
    </div>
  19.  
    <div id="canvas"></div>
  20.  
    </div>
  21.  
    </div>
  22.  
    </template>
  23.  
     
  24.  
    <script>
  25.  
    var oFlow = null;
  26.  
    import process from '@/apis/commonWorkSetting';
  27.  
    import '@/untils/flow.js';
  28.  
    export default {
  29.  
    data() {
  30.  
    return {
  31.  
    nodes: [],
  32.  
    // oFlow: null,
  33.  
    newValue: [],
  34.  
    wf: {},
  35.  
    labelCol: { span: 4 },
  36.  
    wrapperCol: { span: 14 },
  37.  
    form: {
  38.  
    name: '',
  39.  
    region: undefined,
  40.  
    date1: undefined,
  41.  
    delivery: false,
  42.  
    type: [],
  43.  
    resource: '',
  44.  
    desc: '',
  45.  
    },
  46.  
    };
  47.  
    },
  48.  
    methods: {
  49.  
    addProcess() {
  50.  
    var nodes = oFlow.getNodes();
  51.  
    var values = {
  52.  
    wftId: '',
  53.  
    wftType: '文书档案',
  54.  
    wftTitle: '我是你爸爸',
  55.  
    signMode: 'M2',
  56.  
    wftStatus: 'F',
  57.  
    wftRemark: '你叫我爸爸',
  58.  
    };
  59.  
    nodes[2].checkRange = 'R1';
  60.  
    nodes[3].checkRange = 'R2';
  61.  
    nodes[4].checkRange = 'R3';
  62.  
    // console.log(nodes);
  63.  
    values.nodes = JSON.stringify(nodes);
  64.  
    // console.log(values);
  65.  
    process.addProcess(values).then((res) => {
  66.  
    console.log(res);
  67.  
    });
  68.  
    },
  69.  
    handleChange() {
  70.  
    console.log(this.form.region);
  71.  
    var arrText = new Array();
  72.  
    arrText.push(this.form.region);
  73.  
    this.form.nodeDesc1 = arrText.join('\n');
  74.  
    this.form.nodeDesc2 = arrText.join('\n');
  75.  
    oFlow.configNode(this.form);
  76.  
    },
  77.  
    edit() {
  78.  
    var nodes = oFlow.getNodes();
  79.  
    var values = {
  80.  
    wftId: '8929f3a1018929f5173d4028804a0006',
  81.  
    wftType: '文书档案',
  82.  
    wftTitle: '我是你爸爸',
  83.  
    signMode: 'M2',
  84.  
    wftStatus: 'F',
  85.  
    wftRemark: '你叫我爸爸',
  86.  
    };
  87.  
    nodes[2].checkRange = 'R1';
  88.  
    nodes[3].checkRange = 'R2';
  89.  
    nodes[4].checkRange = 'R3';
  90.  
    // console.log(nodes);
  91.  
    values.nodes = JSON.stringify(nodes);
  92.  
    process.updateProcess(values).then((res) => {
  93.  
    console.log(res);
  94.  
    });
  95.  
    },
  96.  
    btns() {
  97.  
    // this.nodes.nodeDesc1 = ['dkahdja'];
  98.  
    // this.nodes.nodeDesc2 = ['jaghhjkd'];
  99.  
    // this.oFlow.configNode(this.node);
  100.  
    // WF.OnSelectNode(123)
  101.  
    // this.func(1233);
  102.  
    console.log(oFlow.getNodes());
  103.  
    },
  104.  
    btn() {
  105.  
    var node = WF.ocopy({}, WF.TaskNode);
  106.  
    node.nodeDesc1 = '请设置任务节点';
  107.  
    node.nodeDesc2 = '点击任务节点,在左侧属性栏设置任务属性';
  108.  
    oFlow.addNode(node);
  109.  
    // oFlow.validFlow();
  110.  
    },
  111.  
    createBusinessFlow() {
  112.  
    //编辑的时候初始化页面
  113.  
    process
  114.  
    .getProcessNode({ wftId: '8929f3a1018929f5173d4028804a0006' })
  115.  
    .then((res) => {
  116.  
    console.log(res);
  117.  
    oFlow = WF.create(
  118.  
    'canvas',
  119.  
    true,
  120.  
    res.data.workflowTemplate
  121.  
    );
  122.  
    });
  123.  
    // this.nodes.push(WF.ocopy({}, WF.StartNode));
  124.  
    // this.nodes.push(WF.ocopy({}, WF.EndNode));
  125.  
    // this.nodes.push(WF.ocopy({}, WF.TaskNode));
  126.  
    // // 调用WF.create方法创建业务流程图
  127.  
    // oFlow = WF.create('canvas', true, this.nodes);
  128.  
    WF.OnSelectNode = function (index) {
  129.  
    if (index < 0) {
  130.  
    return;
  131.  
    }
  132.  
    var oImg = oFlow.container[index];
  133.  
    if (
  134.  
    oImg.data.nodeType == 'start' ||
  135.  
    oImg.data.nodeType == 'end' ||
  136.  
    typeof oImg.box != 'object' ||
  137.  
    oImg.data.nodeType != 'task'
  138.  
    ) {
  139.  
    return;
  140.  
    }
  141.  
    this.form = oImg.data;
  142.  
    };
  143.  
    //this.oFlow.validFlow() 判断流程图是否存在未连线任务节点
  144.  
    //this.oFlow.getNodes() 获取任务节点的个数[]
  145.  
    //oFlow.getNodes() 获取当前节点的位置信息传给后端
  146.  
    //this.oFlow.configNode(); 更新任务节点上的数据
  147.  
    },
  148.  
    func(index) {
  149.  
    console.log(index);
  150.  
    },
  151.  
    },
  152.  
    mounted() {
  153.  
    this.createBusinessFlow();
  154.  
    },
  155.  
    created() {},
  156.  
    };
  157.  
    </script>
  158.  
     
  159.  
    <style lang="scss" scoped></style>
学新通

当然这是我的练习,方便大家观看,如果有什么问题可以私信我。。。。。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbehbf
系列文章
更多 icon
同类精品
更多 icon
继续加载