mirror of
https://gitee.com/antv/g6.git
synced 2024-12-05 05:09:07 +08:00
feat: support drag group when zoom change
This commit is contained in:
parent
26fda9ba5c
commit
8883dd9966
60
demos/arc-circle.html
Normal file
60
demos/arc-circle.html
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>自定义弧形节点</title>
|
||||||
|
<script src="../build/g6.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="mountNode"></div>
|
||||||
|
<script>
|
||||||
|
G6.registerNode('fannode', {
|
||||||
|
draw(cfg, group) {
|
||||||
|
const keyShape = group.addShape('fan', {
|
||||||
|
attrs: {
|
||||||
|
x: 50,
|
||||||
|
y: 50,
|
||||||
|
re: 40,
|
||||||
|
rs: 30,
|
||||||
|
startAngle: 1/2*Math.PI,
|
||||||
|
endAngle: Math.PI,
|
||||||
|
clockwise: false,
|
||||||
|
fill: '#b7eb8f'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return keyShape
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
nodes: [{
|
||||||
|
id: 'node1',
|
||||||
|
x: 100,
|
||||||
|
y: 200
|
||||||
|
},{
|
||||||
|
id: 'node2',
|
||||||
|
x: 300,
|
||||||
|
y: 200
|
||||||
|
}],
|
||||||
|
edges: [{
|
||||||
|
id: 'edge1',
|
||||||
|
target: 'node2',
|
||||||
|
source: 'node1'
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
const graph = new G6.Graph({
|
||||||
|
container: 'mountNode',
|
||||||
|
width: 500,
|
||||||
|
height: 500,
|
||||||
|
defaultNode: {
|
||||||
|
shape: 'fannode'
|
||||||
|
},
|
||||||
|
defaultEdge: {
|
||||||
|
color: '#91d5ff'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
graph.data(data);
|
||||||
|
graph.render();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
141
demos/collapse-expand-group.html
Normal file
141
demos/collapse-expand-group.html
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>收起/展开群组</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="mountNode"></div>
|
||||||
|
<script src="../build/g6.js"></script>
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* 该案例演示以下功能:
|
||||||
|
* 1、双击收起群组;
|
||||||
|
* 2、双击展开群组。
|
||||||
|
*/
|
||||||
|
G6.registerNode('circleNode', {
|
||||||
|
drawShape(cfg, group) {
|
||||||
|
const keyShape = group.addShape('circle', {
|
||||||
|
attrs: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
r: 30,
|
||||||
|
fill: '#87e8de'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return keyShape;
|
||||||
|
}
|
||||||
|
}, 'circle');
|
||||||
|
|
||||||
|
const graph = new G6.Graph({
|
||||||
|
container: 'mountNode',
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
defaultNode: {
|
||||||
|
shape: 'circleNode'
|
||||||
|
},
|
||||||
|
defaultEdge: {
|
||||||
|
color: '#bae7ff'
|
||||||
|
},
|
||||||
|
modes: {
|
||||||
|
default: [ 'drag-canvas', 'zoom-canvas', 'collapse-expand-group' ]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'node6',
|
||||||
|
groupId: 'group3',
|
||||||
|
label: 'node6-group3',
|
||||||
|
x: 500,
|
||||||
|
y: 400
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node1',
|
||||||
|
label: 'node1-group1',
|
||||||
|
groupId: 'group1',
|
||||||
|
x: 100,
|
||||||
|
y: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node9',
|
||||||
|
label: 'node9-p1',
|
||||||
|
groupId: 'p1',
|
||||||
|
x: 300,
|
||||||
|
y: 210
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node2',
|
||||||
|
label: 'node2-group2',
|
||||||
|
groupId: 'group1',
|
||||||
|
x: 150,
|
||||||
|
y: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node3',
|
||||||
|
label: 'node3-group2',
|
||||||
|
groupId: 'group2',
|
||||||
|
x: 300,
|
||||||
|
y: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node7',
|
||||||
|
groupId: 'p1',
|
||||||
|
label: 'node7-p1',
|
||||||
|
x: 200,
|
||||||
|
y: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node10',
|
||||||
|
label: 'node10-p2',
|
||||||
|
groupId: 'p2',
|
||||||
|
x: 400,
|
||||||
|
y: 410
|
||||||
|
}
|
||||||
|
],
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
source: 'node1',
|
||||||
|
target: 'node2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: 'node2',
|
||||||
|
target: 'node3'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
id: 'group1',
|
||||||
|
title: '1',
|
||||||
|
parentId: 'p1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'group2',
|
||||||
|
title: '2',
|
||||||
|
parentId: 'p1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'group3',
|
||||||
|
title: '2',
|
||||||
|
parentId: 'p2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'p1',
|
||||||
|
title: '3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'p2',
|
||||||
|
title: '3'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
graph.data(data)
|
||||||
|
graph.render()
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
144
demos/drag-group.html
Normal file
144
demos/drag-group.html
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>拖动群组</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="mountNode"></div>
|
||||||
|
<script src="../build/g6.js"></script>
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* 该案例演示以下功能:
|
||||||
|
* 1、渲染群组所需要的数据结构;
|
||||||
|
* 2、如何拖动一个群组;
|
||||||
|
* 3、将节点从群组中拖出;
|
||||||
|
* 4、将节点拖入到某个群组中;
|
||||||
|
* 5、拖出拖入节点后动态改变群组大小。
|
||||||
|
*/
|
||||||
|
G6.registerNode('circleNode', {
|
||||||
|
drawShape(cfg, group) {
|
||||||
|
const keyShape = group.addShape('circle', {
|
||||||
|
attrs: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
r: 30,
|
||||||
|
fill: '#87e8de'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return keyShape;
|
||||||
|
}
|
||||||
|
}, 'circle');
|
||||||
|
|
||||||
|
const graph = new G6.Graph({
|
||||||
|
container: 'mountNode',
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
defaultNode: {
|
||||||
|
shape: 'circleNode'
|
||||||
|
},
|
||||||
|
defaultEdge: {
|
||||||
|
color: '#bae7ff'
|
||||||
|
},
|
||||||
|
modes: {
|
||||||
|
default: [ 'drag-group', 'drag-node-width-group' ]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'node6',
|
||||||
|
groupId: 'group3',
|
||||||
|
label: 'node6-group3',
|
||||||
|
x: 100,
|
||||||
|
y: 300,
|
||||||
|
shape: 'rect'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node1',
|
||||||
|
label: 'node1-group1',
|
||||||
|
groupId: 'group1',
|
||||||
|
x: 100,
|
||||||
|
y: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node9',
|
||||||
|
label: 'node9-p1',
|
||||||
|
groupId: 'p1',
|
||||||
|
x: 300,
|
||||||
|
y: 210
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node2',
|
||||||
|
label: 'node2-group2',
|
||||||
|
groupId: 'group1',
|
||||||
|
x: 150,
|
||||||
|
y: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node3',
|
||||||
|
label: 'node3-group2',
|
||||||
|
groupId: 'group2',
|
||||||
|
x: 300,
|
||||||
|
y: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node7',
|
||||||
|
groupId: 'p1',
|
||||||
|
label: 'node7-p1',
|
||||||
|
x: 200,
|
||||||
|
y: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node10',
|
||||||
|
label: 'node10-p2',
|
||||||
|
groupId: 'p2',
|
||||||
|
x: 300,
|
||||||
|
y: 210
|
||||||
|
}
|
||||||
|
],
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
source: 'node1',
|
||||||
|
target: 'node2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: 'node2',
|
||||||
|
target: 'node3'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
id: 'group1',
|
||||||
|
title: '1',
|
||||||
|
parentId: 'p1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'group2',
|
||||||
|
title: '2',
|
||||||
|
parentId: 'p1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'group3',
|
||||||
|
title: '2',
|
||||||
|
parentId: 'p2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'p1',
|
||||||
|
title: '3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'p2',
|
||||||
|
title: '3'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
graph.data(data)
|
||||||
|
graph.render()
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,10 +1,3 @@
|
|||||||
<!--
|
|
||||||
* @Author: moyee
|
|
||||||
* @Date: 2019-08-20 08:50:04
|
|
||||||
* @LastEditors: moyee
|
|
||||||
* @LastEditTime: 2019-08-20 16:57:14
|
|
||||||
* @Description: file content
|
|
||||||
-->
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
@ -2,11 +2,10 @@
|
|||||||
* @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-22 15:06:01
|
* @LastEditTime: 2019-08-23 11:13:43
|
||||||
* @Description: file content
|
* @Description: file content
|
||||||
*/
|
*/
|
||||||
|
const { merge } = require('lodash');
|
||||||
import { merge } from 'lodash';
|
|
||||||
|
|
||||||
const delegateStyle = {
|
const delegateStyle = {
|
||||||
fill: '#F3F9FF',
|
fill: '#F3F9FF',
|
||||||
@ -119,7 +118,7 @@ module.exports = {
|
|||||||
* @return {boolean} false/true
|
* @return {boolean} false/true
|
||||||
*/
|
*/
|
||||||
updatePosition(evt) {
|
updatePosition(evt) {
|
||||||
if (!this.rectPos || !this.delegateShapeBBox) {
|
if (!this.delegateShapeBBox) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +188,8 @@ module.exports = {
|
|||||||
|
|
||||||
// step 1:先修改groupId中的节点位置
|
// step 1:先修改groupId中的节点位置
|
||||||
const nodeInGroup = groupNodes[groupId];
|
const nodeInGroup = groupNodes[groupId];
|
||||||
|
const groupOriginBBox = customGroupControll.getGroupOriginBBox(groupId);
|
||||||
|
const delegateShapeBBoxs = this.delegateShapeBBoxs[groupId];
|
||||||
const otherGroupId = [];
|
const otherGroupId = [];
|
||||||
nodeInGroup.forEach((nodeId, index) => {
|
nodeInGroup.forEach((nodeId, index) => {
|
||||||
|
|
||||||
@ -205,11 +205,9 @@ module.exports = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupOriginBBox = customGroupControll.getGroupOriginBBox(groupId);
|
|
||||||
|
|
||||||
// 群组拖动后节点的位置:deletateShape的最终位置-群组起始位置+节点位置
|
// 群组拖动后节点的位置:deletateShape的最终位置-群组起始位置+节点位置
|
||||||
const x = this.delegateShapeBBoxs[groupId].x - groupOriginBBox.x + this.nodePoint[index].x;
|
const x = delegateShapeBBoxs.x - groupOriginBBox.x + this.nodePoint[index].x;
|
||||||
const y = this.delegateShapeBBoxs[groupId].y - groupOriginBBox.y + this.nodePoint[index].y;
|
const y = delegateShapeBBoxs.y - groupOriginBBox.y + this.nodePoint[index].y;
|
||||||
|
|
||||||
this.nodePoint[index] = {
|
this.nodePoint[index] = {
|
||||||
x, y
|
x, y
|
||||||
@ -238,7 +236,6 @@ module.exports = {
|
|||||||
const cy = (height + 2 * y) / 2;
|
const cy = (height + 2 * y) / 2;
|
||||||
groupKeyShape.attr('x', cx);
|
groupKeyShape.attr('x', cx);
|
||||||
groupKeyShape.attr('y', cy);
|
groupKeyShape.attr('y', cy);
|
||||||
|
|
||||||
customGroupControll.setGroupOriginBBox(id, groupKeyShape.getBBox());
|
customGroupControll.setGroupOriginBBox(id, groupKeyShape.getBBox());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -288,8 +285,7 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
self.shapeOrigin = { x: attrs.x, y: attrs.y };
|
self.shapeOrigin = { x: attrs.x, y: attrs.y };
|
||||||
}
|
}
|
||||||
delegateShape.set('capture', false);
|
// delegateShape.set('capture', false);
|
||||||
this.rectPos = { ...self.shapeOrigin };
|
|
||||||
self.delegateShapes[groupId] = delegateShape;
|
self.delegateShapes[groupId] = delegateShape;
|
||||||
self.delegateShapeBBoxs[groupId] = delegateShape.getBBox();
|
self.delegateShapeBBoxs[groupId] = delegateShape.getBBox();
|
||||||
} else {
|
} else {
|
||||||
@ -299,9 +295,9 @@ module.exports = {
|
|||||||
const x = deltaX + shapeOrigin.x;
|
const x = deltaX + shapeOrigin.x;
|
||||||
const y = deltaY + shapeOrigin.y;
|
const y = deltaY + shapeOrigin.y;
|
||||||
|
|
||||||
delegateShape.attr({ x, y });
|
// 将Canvas坐标转成视口坐标
|
||||||
this.rectPos = { x, y };
|
const point = graph.getPointByCanvas(x, y);
|
||||||
|
delegateShape.attr({ x: point.x, y: point.y });
|
||||||
self.delegateShapeBBoxs[groupId] = delegateShape.getBBox();
|
self.delegateShapeBBoxs[groupId] = delegateShape.getBBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,9 @@
|
|||||||
* @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-22 18:43:16
|
* @LastEditTime: 2019-08-23 13:54:53
|
||||||
* @Description: file content
|
* @Description: 有group的情况下,拖动节点的Behavior
|
||||||
*/
|
*/
|
||||||
const { mix } = require('../util');
|
|
||||||
const { merge } = require('lodash');
|
const { merge } = require('lodash');
|
||||||
const { delegateStyle } = require('../global');
|
const { delegateStyle } = require('../global');
|
||||||
const body = document.body;
|
const body = document.body;
|
||||||
@ -228,6 +227,8 @@ module.exports = {
|
|||||||
x: cx,
|
x: cx,
|
||||||
y: cy
|
y: cy
|
||||||
});
|
});
|
||||||
|
|
||||||
|
customGroupControll.setGroupOriginBBox(groupId, keyShape.getBBox());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyShape) {
|
if (keyShape) {
|
||||||
@ -344,29 +345,6 @@ module.exports = {
|
|||||||
this.graph.paint();
|
this.graph.paint();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_updateDelegate1(item, x, y) {
|
|
||||||
const self = this;
|
|
||||||
let shape = item.get('delegateShape');
|
|
||||||
const bbox = item.get('keyShape').getBBox();
|
|
||||||
if (!shape) {
|
|
||||||
const parent = self.graph.get('group');
|
|
||||||
const attrs = mix({}, delegateStyle, this.delegateStyle);
|
|
||||||
// model上的x, y是相对于图形中心的,delegateShape是g实例,x,y是绝对坐标
|
|
||||||
shape = parent.addShape('rect', {
|
|
||||||
attrs: {
|
|
||||||
width: bbox.width,
|
|
||||||
height: bbox.height,
|
|
||||||
x: x - bbox.width / 2,
|
|
||||||
y: y - bbox.height / 2,
|
|
||||||
...attrs
|
|
||||||
}
|
|
||||||
});
|
|
||||||
shape.set('capture', false);
|
|
||||||
item.set('delegateShape', shape);
|
|
||||||
}
|
|
||||||
shape.attr({ x: x - bbox.width / 2, y: y - bbox.height / 2 });
|
|
||||||
this.graph.paint();
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* 更新拖动元素时的delegate
|
* 更新拖动元素时的delegate
|
||||||
* @param {Event} e 事件句柄
|
* @param {Event} e 事件句柄
|
||||||
|
@ -19,7 +19,7 @@ const behaviors = {
|
|||||||
'brush-select': require('./brush-select'),
|
'brush-select': require('./brush-select'),
|
||||||
'drag-group': require('./drag-group'),
|
'drag-group': require('./drag-group'),
|
||||||
'drag-node-with-group': require('./drag-node-with-group'),
|
'drag-node-with-group': require('./drag-node-with-group'),
|
||||||
'collspse-expand-group': require('./collapse-expand-group')
|
'collapse-expand-group': require('./collapse-expand-group')
|
||||||
};
|
};
|
||||||
Util.each(behaviors, (behavior, type) => {
|
Util.each(behaviors, (behavior, type) => {
|
||||||
Behavior.registerBehavior(type, behavior);
|
Behavior.registerBehavior(type, behavior);
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
* @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-22 18:41:33
|
* @LastEditTime: 2019-08-23 11:44:32
|
||||||
* @Description: file content
|
* @Description: file content
|
||||||
*/
|
*/
|
||||||
import { merge, isString } from 'lodash';
|
const { merge, isString } = require('lodash');
|
||||||
|
|
||||||
export default class CustomGroup {
|
class CustomGroup {
|
||||||
getDefaultCfg() {
|
getDefaultCfg() {
|
||||||
return {
|
return {
|
||||||
default: {
|
default: {
|
||||||
@ -15,7 +15,7 @@ export default class CustomGroup {
|
|||||||
stroke: '#A3B1BF',
|
stroke: '#A3B1BF',
|
||||||
radius: 10,
|
radius: 10,
|
||||||
lineDash: [ 5, 5 ],
|
lineDash: [ 5, 5 ],
|
||||||
strokeOpacity: 0.92,
|
strokeOpacity: 0.9,
|
||||||
fill: '#F3F9FF',
|
fill: '#F3F9FF',
|
||||||
fillOpacity: 0.8,
|
fillOpacity: 0.8,
|
||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
@ -367,15 +367,22 @@ export default class CustomGroup {
|
|||||||
* @param {string} tmpNodeId 临时节点ID
|
* @param {string} tmpNodeId 临时节点ID
|
||||||
*/
|
*/
|
||||||
setGroupTmpNode(groupId, tmpNodeId) {
|
setGroupTmpNode(groupId, tmpNodeId) {
|
||||||
// TODO 需要调整
|
|
||||||
const graph = this.graph;
|
const graph = this.graph;
|
||||||
const graphNodes = graph.get('groupNodes');
|
const graphNodes = graph.get('groupNodes');
|
||||||
const groups = graph.get('groups');
|
const groups = graph.get('groups');
|
||||||
for (const data of groups) {
|
if (graphNodes[groupId].indexOf(tmpNodeId) < 0) {
|
||||||
if (data.parentId === groupId) {
|
|
||||||
graphNodes[groupId].push(tmpNodeId);
|
graphNodes[groupId].push(tmpNodeId);
|
||||||
this.setGroupTmpNode(data.parentId);
|
|
||||||
}
|
}
|
||||||
|
// 获取groupId的父群组
|
||||||
|
const parentGroup = groups.filter(g => g.id === groupId);
|
||||||
|
let parentId = null;
|
||||||
|
if (parentGroup.length > 0) {
|
||||||
|
parentId = parentGroup[0].parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果存在父群组,则把临时元素也添加到父群组中
|
||||||
|
if (parentId) {
|
||||||
|
this.setGroupTmpNode(parentId, tmpNodeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -385,6 +392,7 @@ export default class CustomGroup {
|
|||||||
* @memberof ItemGroup
|
* @memberof ItemGroup
|
||||||
*/
|
*/
|
||||||
collapseGroup(id) {
|
collapseGroup(id) {
|
||||||
|
const self = this;
|
||||||
const customGroup = this.getDeletageGroupById(id);
|
const customGroup = this.getDeletageGroupById(id);
|
||||||
const { nodeGroup, groupStyle } = customGroup;
|
const { nodeGroup, groupStyle } = customGroup;
|
||||||
|
|
||||||
@ -406,6 +414,9 @@ export default class CustomGroup {
|
|||||||
// 收起群组时候动画
|
// 收起群组时候动画
|
||||||
keyShape.animate({
|
keyShape.animate({
|
||||||
onFrame(ratio) {
|
onFrame(ratio) {
|
||||||
|
if (ratio === 1) {
|
||||||
|
self.setGroupOriginBBox(id, keyShape.getBBox());
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
r: groupStyle.r - ratio * (groupStyle.r - r)
|
r: groupStyle.r - ratio * (groupStyle.r - r)
|
||||||
};
|
};
|
||||||
@ -445,13 +456,12 @@ export default class CustomGroup {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 将临时添加的节点加入到群组中,以便拖动节点时候线跟着拖动
|
// 将临时添加的节点加入到群组中,以便拖动节点时候线跟着拖动
|
||||||
nodesInGroup.push(`${id}-custom-node`);
|
// nodesInGroup.push(`${id}-custom-node`);
|
||||||
// this.setGroupTmpNode(id, `${id}-custom-node`);
|
this.setGroupTmpNode(id, `${id}-custom-node`);
|
||||||
|
|
||||||
this.updateEdgeInGroupLinks(id, sourceOutTargetInEdges, sourceInTargetOutEdges);
|
this.updateEdgeInGroupLinks(id, sourceOutTargetInEdges, sourceInTargetOutEdges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 获取群组中节点之间的所有边
|
// 获取群组中节点之间的所有边
|
||||||
const edgeAllInGroup = edges.filter(edge => {
|
const edgeAllInGroup = edges.filter(edge => {
|
||||||
const model = edge.getModel();
|
const model = edge.getModel();
|
||||||
@ -538,6 +548,7 @@ export default class CustomGroup {
|
|||||||
*/
|
*/
|
||||||
expandGroup(id) {
|
expandGroup(id) {
|
||||||
const graph = this.graph;
|
const graph = this.graph;
|
||||||
|
const self = this;
|
||||||
const autoPaint = graph.get('autoPaint');
|
const autoPaint = graph.get('autoPaint');
|
||||||
graph.setAutoPaint(false);
|
graph.setAutoPaint(false);
|
||||||
|
|
||||||
@ -560,12 +571,16 @@ export default class CustomGroup {
|
|||||||
// keyShape.attr('r', groupStyle.r + nodesInGroup.length * 10);
|
// keyShape.attr('r', groupStyle.r + nodesInGroup.length * 10);
|
||||||
keyShape.animate({
|
keyShape.animate({
|
||||||
onFrame(ratio) {
|
onFrame(ratio) {
|
||||||
|
if (ratio === 1) {
|
||||||
|
self.setGroupOriginBBox(id, keyShape.getBBox());
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
r: 30 + ratio * (groupStyle.r + nodesInGroup.length * 10 - 30)
|
r: 30 + ratio * (groupStyle.r + nodesInGroup.length * 10 - 30)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, 1000, 'easeCubic');
|
}, 1000, 'easeCubic');
|
||||||
|
|
||||||
|
// this.setGroupOriginBBox(id, keyShape.getBBox());
|
||||||
// 群组动画一会后再显示节点和边
|
// 群组动画一会后再显示节点和边
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
nodesInGroup.forEach(nodeId => {
|
nodesInGroup.forEach(nodeId => {
|
||||||
@ -590,7 +605,7 @@ export default class CustomGroup {
|
|||||||
// 获取群组中节点之间的所有边
|
// 获取群组中节点之间的所有边
|
||||||
const edgeAllInGroup = edges.filter(edge => {
|
const edgeAllInGroup = edges.filter(edge => {
|
||||||
const model = edge.getModel();
|
const model = edge.getModel();
|
||||||
return nodesInGroup.includes(model.source) && nodesInGroup.includes(model.target);
|
return nodesInGroup.includes(model.source) || nodesInGroup.includes(model.target);
|
||||||
});
|
});
|
||||||
|
|
||||||
edgeAllInGroup.forEach(edge => {
|
edgeAllInGroup.forEach(edge => {
|
||||||
@ -632,9 +647,8 @@ export default class CustomGroup {
|
|||||||
|
|
||||||
// 删除群组中的临时节点ID
|
// 删除群组中的临时节点ID
|
||||||
const tmpNodeModel = delegateNode.getModel();
|
const tmpNodeModel = delegateNode.getModel();
|
||||||
const index = nodesInGroup.indexOf(tmpNodeModel.id);
|
|
||||||
nodesInGroup.splice(index, 1);
|
|
||||||
|
|
||||||
|
this.deleteTmpNode(id, tmpNodeModel.id);
|
||||||
graph.remove(delegateNode);
|
graph.remove(delegateNode);
|
||||||
delete this.delegateInGroup[id];
|
delete this.delegateInGroup[id];
|
||||||
}
|
}
|
||||||
@ -642,6 +656,27 @@ export default class CustomGroup {
|
|||||||
graph.paint();
|
graph.paint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteTmpNode(groupId, tmpNodeId) {
|
||||||
|
const graph = this.graph;
|
||||||
|
const groups = graph.get('groups');
|
||||||
|
const nodesInGroup = graph.get('groupNodes')[groupId];
|
||||||
|
|
||||||
|
const index = nodesInGroup.indexOf(tmpNodeId);
|
||||||
|
nodesInGroup.splice(index, 1);
|
||||||
|
|
||||||
|
// 获取groupId的父群组
|
||||||
|
const parentGroup = groups.filter(g => g.id === groupId);
|
||||||
|
let parentId = null;
|
||||||
|
if (parentGroup.length > 0) {
|
||||||
|
parentId = parentGroup[0].parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果存在父群组,则把临时元素也添加到父群组中
|
||||||
|
if (parentId) {
|
||||||
|
this.deleteTmpNode(parentId, tmpNodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拆分群组
|
* 拆分群组
|
||||||
*
|
*
|
||||||
@ -687,3 +722,5 @@ export default class CustomGroup {
|
|||||||
this.delegateInGroup = {};
|
this.delegateInGroup = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = CustomGroup;
|
||||||
|
@ -4,5 +4,5 @@ module.exports = {
|
|||||||
Mode: require('./mode'),
|
Mode: require('./mode'),
|
||||||
Item: require('./item'),
|
Item: require('./item'),
|
||||||
State: require('./state'),
|
State: require('./state'),
|
||||||
CustomGroup: require('./customGroup').default
|
CustomGroup: require('./customGroup')
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* @fileOverview graph
|
* @fileOverview graph
|
||||||
* @author huangtonger@aliyun.com
|
* @author huangtonger@aliyun.com
|
||||||
*/
|
*/
|
||||||
import { groupBy } from 'lodash';
|
const { groupBy } = require('lodash');
|
||||||
const G = require('@antv/g/lib');
|
const G = require('@antv/g/lib');
|
||||||
const EventEmitter = G.EventEmitter;
|
const EventEmitter = G.EventEmitter;
|
||||||
const Util = require('../util');
|
const Util = require('../util');
|
||||||
|
@ -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-22 15:47:52
|
* @LastEditTime: 2019-08-23 14:16:27
|
||||||
* @Description: file content
|
* @Description: file content
|
||||||
*/
|
*/
|
||||||
const expect = require('chai').expect;
|
const expect = require('chai').expect;
|
||||||
@ -12,6 +12,21 @@ const div = document.createElement('div');
|
|||||||
div.id = 'graph-group-spec';
|
div.id = 'graph-group-spec';
|
||||||
document.body.appendChild(div);
|
document.body.appendChild(div);
|
||||||
|
|
||||||
|
G6.registerNode('circleNode', {
|
||||||
|
drawShape(cfg, group) {
|
||||||
|
const keyShape = group.addShape('circle', {
|
||||||
|
attrs: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
r: 30,
|
||||||
|
fill: '#87e8de'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return keyShape;
|
||||||
|
}
|
||||||
|
}, 'circle');
|
||||||
|
|
||||||
describe('graph group', () => {
|
describe('graph group', () => {
|
||||||
const graph = new G6.Graph({
|
const graph = new G6.Graph({
|
||||||
container: div,
|
container: div,
|
||||||
@ -19,7 +34,13 @@ describe('graph group', () => {
|
|||||||
height: 1000,
|
height: 1000,
|
||||||
pixelRatio: 2,
|
pixelRatio: 2,
|
||||||
modes: {
|
modes: {
|
||||||
default: [ 'drag-group', 'click-select', 'drag-node-with-group', 'collspse-expand-group' ]
|
default: [ 'zoom-canvas', 'drag-group', 'click-select', 'drag-node-with-group', 'collapse-expand-group' ]
|
||||||
|
},
|
||||||
|
defaultNode: {
|
||||||
|
shape: 'circleNode'
|
||||||
|
},
|
||||||
|
defaultEdge: {
|
||||||
|
color: '#bae7ff'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -87,8 +108,7 @@ describe('graph group', () => {
|
|||||||
groupId: 'group3',
|
groupId: 'group3',
|
||||||
label: 'rect',
|
label: 'rect',
|
||||||
x: 100,
|
x: 100,
|
||||||
y: 300,
|
y: 300
|
||||||
shape: 'rect'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'node1',
|
id: 'node1',
|
||||||
@ -121,6 +141,7 @@ describe('graph group', () => {
|
|||||||
{
|
{
|
||||||
id: 'node7',
|
id: 'node7',
|
||||||
groupId: 'p1',
|
groupId: 'p1',
|
||||||
|
label: 'node7-p1',
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 200
|
y: 200
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user