vue使用jointJs,vue流程图、旅程图

效果图

在这里插入图片描述

安装

npm install --save jointjs

使用

// 引入jointjs和jointjs样式
import 'jointjs/dist/joint.css'
import * as joint from 'jointjs';

组件中加入

<div
  ref="myholder"
  id="paper"
  @drop="drop"
  @dragover="allowDrop"
></div>

script

创建画版

let graph = new joint.dia.Graph;  

实例化画布,把画布挂载到dom

     this.paper = new joint.dia.Paper({
        el: this.$refs.myholder, //绑定节点
        model: this.graph, // 定义的画布
        width: 3000, // 画布宽度
        height: 2000,// 画布高度
        gridSize: 10, //栅格点间距,元素拖动会捕捉栅格点
        snapLinks: {
          radius: 60 // 距离元素连接点60像素时自动连接上
        },
        interactive: function() {
          if (self.form.status == 'PROCESSING' || self.form.status == 'STOP') {
            return false;
          }
          return true;
        }, // 元素是否可以拖动
        linkPinning: false, // 不想让用户拖动链接并将其放置在空白纸张区域的某个位置,请将其设置为false
        // perpendicularLinks: true, //如果为true,链接将倾向于与关联对象垂直
        multiLinks: false, // 一个元素与同一源元素和目标元素的链接不得超过一个
        restrictTranslate: true, //设定元素不能拖出画布
        //默认链接线的样式
        defaultLink: new CustomLink({ 
          attrs: {
            path: { stroke: 'green' },
            '.marker-target': {
              d: 'M 10 0 L 0 5 L 10 10 z',
              stroke: 'green',
              fill: 'green'
            }
          },
          labels: [
            {
              attrs: {
                '.label': {
                  text: '1..n'
                }
              },
              position: {
                distance: 49, // individual absolute positioning
                offset: null, // remove default offset
                args: {
                  absoluteOffset: null // disable absolute offset when moving
                }
              }
            }
          ]
        }),
        // 决定是允许还是禁止源视图/磁体 ( ) 和目标视图/磁体 ( )之间的连接
        validateConnection: function(
          sourceView,
          sourceMagnet,
          targetView,
          targetMagnet
        ) {
          if (sourceView.model == targetView.model) {
            return false;
          }
          if (targetView.model.attributes.type == 'TriggerModel') {
            return false;
          }
          let targetlinks = self.graph.getConnectedLinks(targetView.model);
          for (let index = 0; index < targetlinks.length; index++) {
            const element = targetlinks[index];
            if (element.attributes.target.id == targetView.model.id) {
              return false;
            }
          }
          return true;
        }
      });

添加元素


    allowDrop(ev) {
      ev.preventDefault();
    },
   drop(evt) {
      const position = {
        x: evt.layerX - 50,
        y: evt.layerY - 50
      };
      let d0 = new shapesCricle({
          event: this.dragValue.event,
          title: this.dragValue.title,
          position: position,
          size: { width: 150, height: 150 },
          attrs: {
            '.label': {
              text: this.dragValue.label
            },
            '.label1': {
              text: this.dragValue.label1
            },
            '.setting': {
              fill: '#fa8c16'
            }
          }
        });
      
      this.graph.addCell(d0);
    }

自定义元素

var shapesRect = joint.shapes.basic.Generic.extend({
  defaults: joint.util.defaultsDeep(
    {
    // 提供自定义链接标记
      markup: [
        '<rect class="rectitem"/>',
        '<g>',
        '<g>',
        
        '<rect class="rectborder"/>',
        '<image class="reimage"/>',
        '<image class="setimage"/>',
        '<image class="linkimage"/>',
        '<text class="label"></text>',
        '<text class="label1"></text>',
        '<rect class="setting"/>',
        "</g>",
        "</g>"
      ].join(""),
      // 类型
      type: "ActionModel",
      // 工作流类型
      workflowType:"ActionModel",
      // 标记样式,位置,属性
      attrs: {
        '.reimage': {
          width: 0,
          height: 0,
          x: 108,
          y: 70,
          event: 'click:remove',
          cursor: 'pointer',
          "xlink:href":
            "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABsUlEQVRIS+2WPU/CUBSG33OrEcpvMMFSEhcqicZVHfyYTXSR0cWPxU1YrIu6OaGTGy6aOPsxyGw0QVhMLNXE30DBaO8xIBjbRIUSEwfP2nPf57z3nntPCb8c1I5+TR+OMV7mJdBXzxfAM6H3KGTdlH9a3xbAiSXumaF/FiOCpZZL8bYBFc1YIuJd5vcqgwYRnplpLWIX9+saHw4czcgyeDmosMcdRFa1b1c9ADZNUc2djBJEqBsIQ9bCqdkrMk3pAbREq4PJKF4RDQTpwWP4rvDodeNTquiGCckbgQCCNiNW0fxbAAIkCA/MiPnatAzGADeuRTMCORC0ErGKe46WOGJgrnlwx6pdmq/oxjIkZ7sCCKFMhK1C3nM2zUqrenJcSvfyH/C/Rd4767/JihAzIev2zNES2wysN9t0R7VL6Zo+NO1KedpVFxEhTyQOmOUWM/obAMITkcgwy0VmjHUEqOpGWkreCvIWCUGZsFXc/vYtqsWTk67rngcBKIoyFbovXHwLqH90tESOgYVOIAQcqnYp5V/z5UyuO2GWI61B/xWs8QNA4tpfeSu/raHfiRN/7huWhjEoFaxUoQAAAABJRU5ErkJggg==",
        },
        '.setimage': {
          width: 0,
          height: 0,
          x: 30,
          y: 70,
          event: 'click:set',
          cursor: 'pointer',
          "xlink:href":
            "data:image/webp;base64,UklGRuoAAABXRUJQVlA4TN0AAAAvF8AFEJ9gIG2b7vev4RavYLWBqG0buUzGn979L/OvJgCQNs0Gt55+UsIAuBv/5AYH7LSCfMrcgDICmk8eqHNCmgioCgaNJCnqZ8b2b/bu/8BBRP8Vtm3bON3TTnIFAAAAAAAAAEA3xXtTlxsNp3cP/e05pLGoz3G86pLGqqqqa7I2VwpX87+xrKEmy7p8Lpyqml44gVZLSgfT/eOwj+P+o3BHJ/bvt0YtoURP9Z+Dx4fEGCmMHwoHFSif1Bzpyh5qi/1Z7v/CeCUDuSXjm8+H9zgedS7Pn9J8q85LAAA=",
        },
        '.linkimage': {
          width: 0,
          height: 0,
          x: 128,
          y: 70,
          magnet: true,
          "xlink:href":
            "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAMCAYAAABBV8wuAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAABqADAAQAAAABAAAADAAAAAAhICUEAAAATklEQVQYGWMQ6P/fwIAFMP1n+F+PTZIJpBibJFgCmyRcAl2SBSSADKDGMqDoQFaAIcHIwNj4oZCxAUUCJgjSCZdAFoRLoAuC7cLma5AEADeGJG76kS/8AAAAAElFTkSuQmCC",
        },
        '.rectborder': {
          width: 100,
          height: 100,
          stroke: '#C8ECB7',
          strokeWidth: 2,
          fill: "#EDF9E8",
          x: 25,
          y: 25,
          rx: 16,
          ry: 16,
          event: 'click:rectbg'
        },
        '.rectitem': {
          width: 150,
          height: 150,
          fill: "rgba(0,0,0,0)",
        },
        ".label": {
          fill: "#333333",
          fontSize: 18,
          textAnchor: "middle",
          x: 75,
          y: 65
        },
        ".label1": {
          fill: "#333333",
          fontSize: 18,
          textAnchor: "middle",
          x: 75,
          y: 90
        },
        ".setting": {
          width: 6,
          height: 6,
          fill: "#52C41C",
          x: 73,
          y: 105,
          rx: 3,
          ry: 3
        },
        text: {
          fill: "black"
        }
      }
    },
    joint.shapes.basic.Generic.prototype.defaults
  )
});

事件交互

例子

// 元素点击事件
this.paper.on('cell:pointerclick', function(e, d) {});

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值