@antv/g6
Version:
graph visualization frame work
442 lines (366 loc) • 13.4 kB
JavaScript
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
/*
* @Author: moyee
* @Date: 2019-06-27 18:12:06
* @LastEditors: moyee
* @LastEditTime: 2019-08-23 13:54:53
* @Description: 有group的情况下,拖动节点的Behavior
*/
var deepMix = require('@antv/util/lib/deep-mix');
var _require = require('../global'),
delegateStyle = _require.delegateStyle;
var body = document.body;
module.exports = {
getDefaultCfg: function getDefaultCfg() {
return {
updateEdge: true,
delegate: true,
delegateStyle: {},
maxMultiple: 1.1,
minMultiple: 1
};
},
getEvents: function getEvents() {
return {
'node:dragstart': 'onDragStart',
'node:drag': 'onDrag',
'node:dragend': 'onDragEnd',
'canvas:mouseleave': 'onOutOfRange',
mouseenter: 'onMouseEnter',
mouseleave: 'onMouseLeave'
};
},
onMouseEnter: function onMouseEnter(evt) {
var target = evt.target;
var groupId = target.get('groupId');
if (groupId && this.origin) {
var graph = this.graph;
var customGroupControll = graph.get('customGroupControll');
var customGroup = customGroupControll.getDeletageGroupById(groupId);
if (customGroup) {
var currentGroup = customGroup.nodeGroup;
var keyShape = currentGroup.get('keyShape');
this.inGroupId = groupId;
customGroupControll.setGroupStyle(keyShape, 'hover');
}
}
},
/**
* 拖动节点移除Group时的事件
* @param {Event} evt 事件句柄
*/
onMouseLeave: function onMouseLeave(evt) {
var target = evt.target;
var groupId = target.get('groupId');
if (groupId && this.origin) {
var graph = this.graph;
var customGroupControll = graph.get('customGroupControll');
var customGroup = customGroupControll.getDeletageGroupById(groupId);
if (customGroup) {
var currentGroup = customGroup.nodeGroup;
var keyShape = currentGroup.get('keyShape');
customGroupControll.setGroupStyle(keyShape, 'default');
}
}
if (!groupId) {
this.inGroupId = null;
}
},
onDragStart: function onDragStart(e) {
var _this = this;
if (!this.shouldBegin.call(this, e)) {
return;
}
var item = e.item;
var graph = this.graph;
this.targets = []; // 获取所有选中的元素
var nodes = graph.findAllByState('node', 'selected');
var currentNodeId = item.get('id'); // 当前拖动的节点是否是选中的节点
var dragNodes = nodes.filter(function (node) {
var nodeId = node.get('id');
return currentNodeId === nodeId;
}); // 只拖动当前节点
if (dragNodes.length === 0) {
this.target = item; // 拖动节点时,如果在Group中,则Group高亮
var model = item.getModel();
var groupId = model.groupId;
if (groupId) {
var customGroupControll = graph.get('customGroupControll');
var customGroup = customGroupControll.getDeletageGroupById(groupId);
if (customGroup) {
var currentGroup = customGroup.nodeGroup;
var keyShape = currentGroup.get('keyShape');
customGroupControll.setGroupStyle(keyShape, 'hover'); // 初始拖动时候,如果是在当前群组中拖动,则赋值为当前groupId
this.inGroupId = groupId;
}
}
} else {
// 拖动多个节点
if (nodes.length > 1) {
nodes.forEach(function (node) {
_this.targets.push(node);
});
} else {
this.targets.push(item);
}
}
this.origin = {
x: e.x,
y: e.y
};
this.point = {};
this.originPoint = {};
},
onDrag: function onDrag(e) {
if (!this.origin) {
return;
}
if (!this.get('shouldUpdate').call(this, e)) {
return;
} // 当targets中元素时,则说明拖动的是多个选中的元素
if (this.targets.length > 0) {
this._updateDelegate(e);
} else {
// 只拖动单个元素
this._update(this.target, e, true);
var item = e.item;
var graph = this.graph;
var model = item.getModel();
var groupId = model.groupId;
if (groupId) {
var customGroupControll = graph.get('customGroupControll');
var customGroup = customGroupControll.getDeletageGroupById(groupId);
if (customGroup) {
var currentGroup = customGroup.nodeGroup;
var keyShape = currentGroup.get('keyShape'); // 当前
if (this.inGroupId !== groupId) {
customGroupControll.setGroupStyle(keyShape, 'default');
} else {
customGroupControll.setGroupStyle(keyShape, 'hover');
}
}
}
}
},
onDragEnd: function onDragEnd(e) {
var _this2 = this;
if (!this.origin || !this.shouldEnd.call(this, e)) {
return;
}
if (this.shape) {
this.shape.remove();
this.shape = null;
}
if (this.target) {
var delegateShape = this.target.get('delegateShape');
if (delegateShape) {
delegateShape.remove();
this.target.set('delegateShape', null);
}
}
if (this.targets.length > 0) {
// 获取所有已经选中的节点
this.targets.forEach(function (node) {
return _this2._update(node, e);
});
} else if (this.target) {
this._update(this.target, e);
}
this.point = {};
this.origin = null;
this.originPoint = {};
this.targets.length = 0;
this.target = null; // 终止时需要判断此时是否在监听画布外的 mouseup 事件,若有则解绑
var fn = this.fn;
if (fn) {
body.removeEventListener('mouseup', fn, false);
this.fn = null;
}
this.setCurrentGroupStyle(e);
},
setCurrentGroupStyle: function setCurrentGroupStyle(evt) {
var item = evt.item;
var graph = this.graph;
var autoPaint = graph.get('autoPaint');
graph.setAutoPaint(false);
var model = item.getModel(); // 节点所在的GroupId
var groupId = model.groupId,
id = model.id;
var customGroupControll = graph.get('customGroupControll');
var customGroup = customGroupControll.customGroup;
var groupNodes = graph.get('groupNodes');
if (this.inGroupId && groupId) {
var currentGroup = customGroup[groupId].nodeGroup;
var keyShape = currentGroup.get('keyShape');
var itemBBox = item.getBBox();
var currentGroupBBox = keyShape.getBBox();
var x = itemBBox.x,
y = itemBBox.y;
var minX = currentGroupBBox.minX,
minY = currentGroupBBox.minY,
maxX = currentGroupBBox.maxX,
maxY = currentGroupBBox.maxY; // 在自己的group中拖动,判断是否拖出了自己的group
// this.inGroupId !== groupId,则说明拖出了原来的group,拖到了其他group上面,
// 则删除item中的groupId字段,同时删除group中的nodeID
if (!(x < maxX * this.maxMultiple && x > minX * this.minMultiple && y < maxY * this.maxMultiple && y > minY * this.minMultiple) || this.inGroupId !== groupId) {
// 拖出了group,则删除item中的groupId字段,同时删除group中的nodeID
var currentGroupNodes = groupNodes[groupId];
groupNodes[groupId] = currentGroupNodes.filter(function (node) {
return node !== id;
});
customGroupControll.dynamicChangeGroupSize(evt, currentGroup, keyShape); // 同时删除groupID中的节点
delete model.groupId;
} // 拖动到其他的group上面
if (this.inGroupId !== groupId) {
// 拖动新的group后,更新groupNodes及model中的groupId
var nodeInGroup = customGroup[this.inGroupId].nodeGroup;
var targetKeyShape = nodeInGroup.get('keyShape'); // 将该节点添加到inGroupId中
if (groupNodes[this.inGroupId].indexOf(id) === -1) {
groupNodes[this.inGroupId].push(id);
} // 更新节点的groupId为拖动上去的group Id
model.groupId = this.inGroupId; // 拖入节点后,根据最新的节点数量,重新计算群组大小
customGroupControll.dynamicChangeGroupSize(evt, nodeInGroup, targetKeyShape);
}
customGroupControll.setGroupStyle(keyShape, 'default');
} else if (this.inGroupId && !groupId) {
// 将节点拖动到群组中
var _nodeInGroup = customGroup[this.inGroupId].nodeGroup;
var _keyShape = _nodeInGroup.get('keyShape'); // 将该节点添加到inGroupId中
if (groupNodes[this.inGroupId].indexOf(id) === -1) {
groupNodes[this.inGroupId].push(id);
} // 更新节点的groupId为拖动上去的group Id
model.groupId = this.inGroupId; // 拖入节点后,根据最新的节点数量,重新计算群组大小
customGroupControll.dynamicChangeGroupSize(evt, _nodeInGroup, _keyShape);
} else if (!this.inGroupId && groupId) {
// 拖出到群组之外了,则删除数据中的groupId
for (var gnode in groupNodes) {
var _currentGroupNodes = groupNodes[gnode];
groupNodes[gnode] = _currentGroupNodes.filter(function (node) {
return node !== id;
});
}
var _currentGroup = customGroup[groupId].nodeGroup;
var _keyShape2 = _currentGroup.get('keyShape');
customGroupControll.dynamicChangeGroupSize(evt, _currentGroup, _keyShape2);
delete model.groupId;
}
this.inGroupId = null;
graph.paint();
graph.setAutoPaint(autoPaint);
},
// 若在拖拽时,鼠标移出画布区域,此时放开鼠标无法终止 drag 行为。在画布外监听 mouseup 事件,放开则终止
onOutOfRange: function onOutOfRange(e) {
var self = this;
if (this.origin) {
var canvasElement = self.graph.get('canvas').get('el');
var fn = function fn(ev) {
if (ev.target !== canvasElement) {
self.onDragEnd(e);
}
};
this.fn = fn;
body.addEventListener('mouseup', fn, false);
}
},
_update: function _update(item, e, force) {
var origin = this.origin;
var model = item.get('model');
var nodeId = item.get('id');
if (!this.point[nodeId]) {
this.point[nodeId] = {
x: model.x,
y: model.y
};
}
var x = e.x - origin.x + this.point[nodeId].x;
var y = e.y - origin.y + this.point[nodeId].y; // 拖动单个未选中元素
if (force) {
this._updateDelegate(e, x, y);
return;
}
var pos = {
x: x,
y: y
};
if (this.get('updateEdge')) {
this.graph.updateItem(item, pos);
} else {
item.updatePosition(pos);
this.graph.paint();
}
},
/**
* 更新拖动元素时的delegate
* @param {Event} e 事件句柄
* @param {number} x 拖动单个元素时候的x坐标
* @param {number} y 拖动单个元素时候的y坐标
*/
_updateDelegate: function _updateDelegate(e, x, y) {
var item = e.item;
var graph = this.graph;
var groupType = graph.get('groupType');
var bbox = item.get('keyShape').getBBox();
if (!this.shape) {
var parent = graph.get('group');
var attrs = deepMix({}, delegateStyle, this.delegateStyle); // 拖动多个
if (this.targets.length > 0) {
var nodes = graph.findAllByState('node', 'selected');
if (nodes.length === 0) {
nodes.push(item);
}
var customGroupControll = graph.get('customGroupControll');
var _customGroupControll$ = customGroupControll.calculationGroupPosition(nodes),
_x = _customGroupControll$.x,
_y = _customGroupControll$.y,
width = _customGroupControll$.width,
height = _customGroupControll$.height;
this.originPoint = {
x: _x,
y: _y,
width: width,
height: height
}; // model上的x, y是相对于图形中心的,delegateShape是g实例,x,y是绝对坐标
this.shape = parent.addShape('rect', {
attrs: _extends({
width: width,
height: height,
x: _x,
y: _y
}, attrs)
});
} else if (this.target) {
this.shape = parent.addShape('rect', {
attrs: _extends({
width: bbox.width,
height: bbox.height,
x: x - bbox.width / 2,
y: y - bbox.height / 2
}, attrs)
});
this.target.set('delegateShape', this.shape);
}
this.shape.set('capture', false);
}
if (this.targets.length > 0) {
var clientX = e.x - this.origin.x + this.originPoint.minX;
var clientY = e.y - this.origin.y + this.originPoint.minY;
this.shape.attr({
x: clientX,
y: clientY
});
} else if (this.target) {
if (groupType === 'circle') {
this.shape.attr({
x: x - bbox.width / 2,
y: y - bbox.height / 2
});
} else if (groupType === 'rect') {
this.shape.attr({
x: x,
y: y
});
}
}
this.graph.paint();
}
};