feat: group support drag node in group

This commit is contained in:
zhanning.bzn 2019-08-21 19:36:34 +08:00
parent 2d8f190a70
commit 18fdd3798e
5 changed files with 142 additions and 26 deletions

View File

@ -2,7 +2,7 @@
* @Author: moyee * @Author: moyee
* @Date: 2019-07-31 14:36:15 * @Date: 2019-07-31 14:36:15
* @LastEditors: moyee * @LastEditors: moyee
* @LastEditTime: 2019-08-20 17:12:19 * @LastEditTime: 2019-08-20 21:11:30
* @Description: file content * @Description: file content
*/ */
@ -195,7 +195,7 @@ module.exports = {
const node = graph.findById(nodeId); const node = graph.findById(nodeId);
const model = node.getModel(); const model = node.getModel();
if (!otherGroupId.includes(model.groupId)) { if (model.groupId && !otherGroupId.includes(model.groupId)) {
otherGroupId.push(model.groupId); otherGroupId.push(model.groupId);
} }
if (!this.nodePoint[index]) { if (!this.nodePoint[index]) {
@ -221,12 +221,19 @@ module.exports = {
// 更新完群组位置后,重新设置群组起始位置 // 更新完群组位置后,重新设置群组起始位置
const customGroups = customGroupControll.customGroup; const customGroups = customGroupControll.customGroup;
// otherGroupId中是否包括当前groupId如果不包括则添加进去
if (!otherGroupId.includes(groupId)) {
otherGroupId.push(groupId);
}
otherGroupId.forEach(id => { otherGroupId.forEach(id => {
// 更新除过groupID外的其他群组位置 // 更新群组位置
const { nodeGroup } = customGroups[id]; const { nodeGroup, groupStyle } = customGroups[id];
const groupKeyShape = nodeGroup.get('keyShape'); const groupKeyShape = nodeGroup.get('keyShape');
const { x, y, width, height } = customGroupControll.calculationGroupPosition(groupNodes[id]); const { width, height } = groupStyle;
const { x, y } = customGroupControll.calculationGroupPosition(groupNodes[id]);
const cx = (width + 2 * x) / 2; const cx = (width + 2 * x) / 2;
const cy = (height + 2 * y) / 2; const cy = (height + 2 * y) / 2;
groupKeyShape.attr('x', cx); groupKeyShape.attr('x', cx);

View File

@ -2,7 +2,7 @@
* @Author: moyee * @Author: moyee
* @Date: 2019-06-27 18:12:06 * @Date: 2019-06-27 18:12:06
* @LastEditors: moyee * @LastEditors: moyee
* @LastEditTime: 2019-08-15 11:34:04 * @LastEditTime: 2019-08-21 19:36:12
* @Description: file content * @Description: file content
*/ */
const { mix } = require('../util'); const { mix } = require('../util');
@ -23,9 +23,43 @@ module.exports = {
'node:dragstart': 'onDragStart', 'node:dragstart': 'onDragStart',
'node:drag': 'onDrag', 'node:drag': 'onDrag',
'node:dragend': 'onDragEnd', 'node:dragend': 'onDragEnd',
'canvas:mouseleave': 'onOutOfRange' 'canvas:mouseleave': 'onOutOfRange',
mouseenter: 'onMouseEnter',
mouseout: 'onMouseOut'
}; };
}, },
onMouseEnter(evt) {
const { target } = evt;
const groupId = target.get('groupId');
if (groupId && this.origin) {
const graph = this.graph;
const customGroupControll = graph.get('customGroupControll');
const customGroup = customGroupControll.customGroup;
const currentGroup = customGroup[groupId].nodeGroup;
const keyShape = currentGroup.get('keyShape');
this.inGroupId = groupId;
customGroupControll.setGroupStyle(keyShape, 'hover');
}
},
/**
* 拖动节点移除Group时的事件
* @param {Event} evt 事件句柄
*/
onMouseOut(evt) {
const { target } = evt;
const groupId = target.get('groupId');
if (groupId && this.origin) {
const graph = this.graph;
const customGroupControll = graph.get('customGroupControll');
const customGroup = customGroupControll.customGroup;
const currentGroup = customGroup[groupId].nodeGroup;
const keyShape = currentGroup.get('keyShape');
customGroupControll.setGroupStyle(keyShape, 'default');
}
this.inGroupId = null;
},
onDragStart(e) { onDragStart(e) {
if (!this.shouldBegin.call(this, e)) { if (!this.shouldBegin.call(this, e)) {
return; return;
@ -50,6 +84,15 @@ module.exports = {
// 只拖动当前节点 // 只拖动当前节点
if (dragNodes.length === 0) { if (dragNodes.length === 0) {
this.target = item; this.target = item;
// 拖动节点时如果在Group中则Group高亮
const model = item.getModel();
const { groupId } = model;
if (groupId) {
const customGroupControll = graph.get('customGroupControll');
const customGroup = customGroupControll.customGroup;
const currentGroup = customGroup[groupId].nodeGroup;
customGroupControll.setGroupStyle(currentGroup.get('keyShape'), 'hover');
}
} else { } else {
// 拖动多个节点 // 拖动多个节点
if (nodes.length > 1) { if (nodes.length > 1) {
@ -83,6 +126,28 @@ module.exports = {
} else { } else {
// 只拖动单个元素 // 只拖动单个元素
this._update(this.target, e, true); this._update(this.target, e, true);
const { item } = e;
const graph = this.graph;
const model = item.getModel();
const { groupId } = model;
if (groupId) {
const customGroupControll = graph.get('customGroupControll');
const customGroup = customGroupControll.customGroup;
const currentGroup = customGroup[groupId].nodeGroup;
const keyShape = currentGroup.get('keyShape');
const currentGroupBBox = keyShape.getBBox();
const delegateShape = this.target.get('delegateShape');
const { x, y } = delegateShape.getBBox();
const { minX, minY, maxX, maxY } = currentGroupBBox;
if (x > maxX || x < minX || y > maxY || y < minY) {
customGroupControll.setGroupStyle(keyShape, 'default');
} else {
customGroupControll.setGroupStyle(keyShape, 'hover');
}
}
} }
}, },
onDragEnd(e) { onDragEnd(e) {
@ -121,6 +186,47 @@ module.exports = {
body.removeEventListener('mouseup', fn, false); body.removeEventListener('mouseup', fn, false);
this.fn = null; this.fn = null;
} }
this.setCurrentGroupStyle(e);
},
setCurrentGroupStyle(evt) {
const { item } = evt;
const graph = this.graph;
const model = item.getModel();
// 节点所在的GroupId
const { groupId } = model;
// 拖动到的group上面
if (this.inGroupId && this.inGroupId !== groupId) {
// 将该节点添加到inGroupId中
}
if (groupId) {
const customGroupControll = graph.get('customGroupControll');
const customGroup = customGroupControll.customGroup;
const currentGroup = customGroup[groupId].nodeGroup;
const keyShape = currentGroup.get('keyShape');
const itemBBox = item.getBBox();
const currentGroupBBox = keyShape.getBBox();
const { x, y } = itemBBox;
const { minX, minY, maxX, maxY } = currentGroupBBox;
if (!(x < maxX && x > minX && y < maxY && y > minY)) {
// 拖出了group则删除item中的groupId字段同时删除group中的nodeID
const groupNodes = graph.get('groupNodes');
const currentGroupNodes = groupNodes[groupId];
groupNodes[groupId] = currentGroupNodes.filter(node => node !== model.id);
// 同时删除groupID中的节点
delete model.groupId;
}
customGroupControll.setGroupStyle(keyShape, 'default');
}
this.inGroupId = null;
}, },
// 若在拖拽时,鼠标移出画布区域,此时放开鼠标无法终止 drag 行为。在画布外监听 mouseup 事件,放开则终止 // 若在拖拽时,鼠标移出画布区域,此时放开鼠标无法终止 drag 行为。在画布外监听 mouseup 事件,放开则终止
onOutOfRange(e) { onOutOfRange(e) {

View File

@ -2,7 +2,7 @@
* @Author: moyee * @Author: moyee
* @Date: 2019-07-30 12:10:26 * @Date: 2019-07-30 12:10:26
* @LastEditors: moyee * @LastEditors: moyee
* @LastEditTime: 2019-08-20 17:16:58 * @LastEditTime: 2019-08-20 19:50:50
* @Description: file content * @Description: file content
*/ */
import { merge, isString } from 'lodash'; import { merge, isString } from 'lodash';
@ -135,7 +135,6 @@ export default class CustomGroup {
this.setGroupOriginBBox(groupId, keyShape.getBBox()); this.setGroupOriginBBox(groupId, keyShape.getBBox());
nodeGroup.sort();
graph.setAutoPaint(autoPaint); graph.setAutoPaint(autoPaint);
graph.paint(); graph.paint();
} }

View File

@ -2,7 +2,7 @@
* @Author: moyee * @Author: moyee
* @Date: 2019-06-27 18:12:06 * @Date: 2019-06-27 18:12:06
* @LastEditors: moyee * @LastEditors: moyee
* @LastEditTime: 2019-08-20 17:05:04 * @LastEditTime: 2019-08-20 19:53:44
* @Description: file content * @Description: file content
*/ */
/** /**
@ -540,6 +540,10 @@ class Graph extends EventEmitter {
this.get('customGroupControll').create(groupId, tmpNodes, groupType, groupIndex); this.get('customGroupControll').create(groupId, tmpNodes, groupType, groupIndex);
groupIndex--; groupIndex--;
} }
// 对所有Group排序
const customGroup = this.get('customGroup');
customGroup.sort();
} }
} }

View File

@ -2,7 +2,7 @@
* @Author: moyee * @Author: moyee
* @Date: 2019-07-31 11:54:41 * @Date: 2019-07-31 11:54:41
* @LastEditors: moyee * @LastEditors: moyee
* @LastEditTime: 2019-08-20 17:17:52 * @LastEditTime: 2019-08-20 19:54:32
* @Description: file content * @Description: file content
*/ */
const expect = require('chai').expect; const expect = require('chai').expect;
@ -82,6 +82,14 @@ describe('graph group', () => {
it.only('nesting group test', () => { it.only('nesting group test', () => {
const data = { const data = {
nodes: [ nodes: [
{
id: 'node6',
groupId: 'group3',
label: 'rect',
x: 100,
y: 300,
shape: 'rect'
},
{ {
id: 'node1', id: 'node1',
label: 'fck', label: 'fck',
@ -89,6 +97,13 @@ describe('graph group', () => {
x: 100, x: 100,
y: 100 y: 100
}, },
{
id: 'node9',
label: 'noGroup1',
groupId: 'p1',
x: 300,
y: 210
},
{ {
id: 'node2', id: 'node2',
label: 'node2', label: 'node2',
@ -109,21 +124,6 @@ describe('graph group', () => {
x: 200, x: 200,
y: 200 y: 200
}, },
{
id: 'node6',
groupId: 'group3',
label: 'rect',
x: 100,
y: 300,
shape: 'rect'
},
{
id: 'node9',
label: 'noGroup1',
groupId: 'p1',
x: 300,
y: 210
},
{ {
id: 'node10', id: 'node10',
label: 'noGroup', label: 'noGroup',