1.安装并引入joint
使用jquery情况下,引入jquery,loadsh,backbone以及这三个js,之后是jointjs,且顺序不能乱;
使用框架的情况下,npm install jointjs --save;然后在使用的页面上 import * as joint from 'jointjs';
2.创建graph对象和paper容器
this_.graph = new joint.dia.Graph;
3.设置连线
方式一 let link = new joint.shapes.standard.Link({ //这样设置的连线不会直接产生线的移除的标识
source:{id:id},//源id
target:{id:id}, //目标id
label: [{ position: 0.5, attrs: { text: { text: "ceshi" || '', 'font-weight': 'bold','font-size': '12px' } } }], //设置线上的label的样式设置
attrs:{
line: {
}
});
方式二 //这样设置的连线会直接产生线的移除的标识 ,点击黑色的圆点,移除当前的线条
let link = new joint.dia.Link ({
//手动设置线条的拐点
//设置线条之间不叠压的样式
4.关于连接点(锚点)
5.实现锚点的高亮 -- 鼠标移上去的时候
首先是自定义的锚点
1 export const portConfig = (type)=> {
2 let returnObj={
3 groups: {
4 'in': {
5 position: 'left',
6 attrs: {
7 circle: {
8 magnet: true,
9 stroke: '#5cc05c',
10 fill: '#5cc05c',
11 r:(type=='TASK'||type=='FILTER')?10:12,
12 "ref-y":type=='TASK'?14:0,
13 "stroke-opacity": 0.5
14 },
15 },
16 z: -1 //层级设置
17 },
18 "out": {
19 position: 'right',
20 attrs: { //这里如果不写入stroke以及stroke-opacity的话,不会出现高亮的效果
21 'circle': {
22 magnet: true, //控制改锚点是否可以被连接
23 stroke: '#5cc05c', //锚点的边的填充
24 fill: '#5cc05c',
25 r: (type=='TASK'||type=='FILTER')?10:12,
26 "ref-y":type=='TASK'?14:0,
27 "stroke-opacity": 0.5 //高亮的时候,边的颜色
28 }
29 },
30 z: -1
31 }
32 },
33 items: []
34 };
35 let outObj= {
36 group: 'out',
37 attrs: {
38 text: { text: '' }
39 }
40 },
41 inObj={
42 group: 'in',
43 attrs: {
44 text: { text: '' }
45 }
46 };
47 if(type=="START"){
48 returnObj.items.push(outObj);
49 }else if(type == "END"){
50 returnObj.items.push(inObj);
51 }else{
52 returnObj.items.push(inObj);
53 returnObj.items.push(outObj);
54 }
55 return returnObj;
56 };
57
58 使用
59 export const cEnd = cBase.extend(
60 Object.assign({},{
61 defaults: joint.util.deepSupplement(
62 {
63 type: "coa.End",
64 size: { width: 80, height: 54 },
65 inPorts: [],
66 outPorts: [],
67 attrs: attrConfig({text:"END",content:"ddfdg"}),
68 ports: portConfig("END"),
69 },joint.shapes.basic.Rect.prototype.defaults),
70 markup: cStartHtml,
71 initialize: function() {
72 joint.dia.Element.prototype.initialize.apply(this, arguments);
73 }
74 })
75 );
6.关于什么时候可以用attr,什么时候不可以用 (获取的是元素可以直接attr改变属性,获取的是元素的视图就需要进一步获取model,在paper的on事件中,获取到的都是元素的视图)
var elements = this.paper.model.getElements();获取当前paper上所有的元素
for (var i = 0, ii = elements.length; i < ii; i++) {
var currentElement = elements[i];
var type = currentElement.attributes["type"];
currentElement.attr('.background/stroke', '#3C444D');
currentElement.attr('.background/height', 100);
currentElement.attr("text.message/opacity",0);
currentElement.attr(".status/opacity",0);
};
}
这个currentElement 代表的就是右侧的child
在child-》attributes-》attrs 中的是自定义的元素的classname或者是元素的tagname,这里边的可以对使用attr进行重置,一般是用来改变样式
若想获取type,只能是attribute来获取,如上
但是在
paper.on(‘pointerclick’,function(cellView){
cellView是获取的是当前的cell的view
想要进行改变样式,要获取到
var cell = cellview.model;
cell.attr(".background/height",120);
如上;
})
7.如何移除没有终点的连线
var links = this.paper.model.getLinks(); //判断没有结束点的link,移除 for (var j = 0, jj = links.length; j < jj; j++) { var currentLink = links[j]; //判断当前link的target是否有id var hasTarget = currentLink.attributes.target.id?true:false; //如果没有 if(!hasTarget){ //移除当前的线 this.graph.removeCells(currentLink) } //下面是设置样式 // currentLink.attr('line/stroke', 'black'); // currentLink.label(0, { // attrs: { // body: { // stroke: 'black' // } // } // }) } 这是自己写的方法
后来发现在 dia.Paper.prototype.options.linkPinning = false的时候,表示当在空白处结束时,将返回原位置
8.页面的放大缩小
9.实现页面的拖拽和各种点击事件
1 // 事件 - 注意,这里的this指向是this.paper this_ 是我之前定义的,指向的是vue
2 this.paper.on({
3 // 点击label事件
4 'link:pointerclick': function(linkView){
5 this_.resetAll();
6 let labelModel = linkView.model;
7 // 更新line的样式
8 labelModel.attr("line/stroke","red");
9 // 更新label的样式
10 labelModel.label(0, {
11 attrs: {
12 labelBody: {
13 stroke: 'orange'
14 },
15 labelText:{
16 text:"包含",
17 }
18 }
19 });27 },
28 // 元素的点击
29 'element:pointerdown':function(cellView){
30 var cell = cellView.model;
31 console.log("点击节点")
32 // 更新元素的样式
33 // cell.attr("body/stroke","red");
34 },
35 // 点击空白处或者点击元素的时候,清空点击过的样式
36 'blank:pointerdown element:pointerdown': function(){
37 this_.resetAll();
38 },
39 //实现画布拖拽
40 'blank:pointerdown': function(evt, x, y){
41 this.startX = x;
42 this.startY = y;
43 this.origin = this_.paper.options.origin;
44 this.startMove = true;
45 },
46 'blank:pointermove': function(evt, x, y) {
47 if (this.startMove) {
48 var diffX = x - this.startX + this.origin.x;
49 var diffY = y - this.startY + this.origin.y;
50 this_.paper.translate(diffX, diffY);
51 }
52 },
53 'blank:pointerup': function(evt, x, y) {
54 this.startMove = false;
55 },
56 })
10.动态的增加节点,动态的给节点设置内容等
前提是先定义新的类型对象,使用原有的也可以 joint.shapes.coa = {}; 在一个页面定义 自定义的节点类型
这是一个公共的shape扩展 export const cBase = joint.shapes.basic.Generic.extend( Object.assign({}, joint.shapes.basic.PortsViewInterface, { baseEvents: { }, extraEvents: {}, initialize: function() { joint.dia.ElementView.prototype.initialize.apply(this, arguments); joint.shapes.basic.PortsViewInterface.initialize.apply(this, arguments); } )
//定义 export const cAPI = cBase.extend( Object.assign({},{ markup: cApiHtml, defaults:joint.util.deepSupplement( { type: "coa.API", // state: "api", // name: "call api", // show_number: !1, // message: "", color: "", // size: { width: 180, height: 100 }, inPorts: ['in'], outPorts: ["out"], minWidth: 180, attrs: attrConfig({text:"API",content:"API"}), ports: portConfig("API"), content:"API" }, joint.shapes.devs.Model.prototype.defaults ), initialize: function() { joint.shapes.basic.Generic.prototype.initialize.apply(this, arguments); console.log(this) 指代当前的cell //修改内容 this.attr('text.api/text', this.get('content'), { silent: true }); } }) ); joint.shapes.coa.API = cAPI; 定义调用的方式 export const createApi=(data)=>{ return new joint.shapes.coa.API({ position: { x:data.posX, y:data.posY } , size: { width: 120, height: 100 }, content:data["text.content"] 这里加入我们想要修改的属性 }); } 调用的位置直接 var block = createApi(data); block.addTo(this.graph);