fix use addItem group not add data to groups

This commit is contained in:
baizn 2019-10-17 14:12:47 +08:00
parent b8ee0d0d5a
commit f08f37a270
7 changed files with 325 additions and 26 deletions

177
demos/create-group.html Normal file
View File

@ -0,0 +1,177 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rect节点分组</title>
</head>
<body>
<div id="mountNode"></div>
<button id='createGroup'>手动创建 Group</button>
<script src="../build/g6.js"></script>
<script>
/**
* 该案例演示以下功能:
* 1、渲染群组所需要的数据结构
* 2、如何拖动一个群组
* 3、将节点从群组中拖出
* 4、将节点拖入到某个群组中
* 5、拖出拖入节点后动态改变群组大小。
*/
G6.registerNode('rectNode', {
draw(cfg, group) {
const keyShape = group.addShape('rect', {
attrs: {
x: 0,
y: 0,
width: 80,
height: 50,
fill: '#87e8de'
}
});
const text = group.addShape('text', {
attrs: {
x: 35,
y: 25,
textAlign: 'center',
fill: 'blue',
text: cfg.label
}
})
return keyShape;
}
});
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultNode: {
shape: 'rectNode',
labelCfg: {
position: 'center'
}
},
defaultEdge: {
color: '#bae7ff',
style: {
endArrow: true
}
},
modes: {
default: [ 'drag-group', 'drag-node-with-group', 'collapse-expand-group' ]
},
groupType: 'rect'
});
const data = {
nodes: [
{
id: 'node6',
groupId: 'group3',
label: 'node6-group3',
x: 100,
y: 300,
},
{
id: 'node1',
label: 'node1-group1',
groupId: 'group1',
x: 100,
y: 100
},
{
id: 'node2',
label: 'node2-group2',
groupId: 'p2',
x: 150,
y: 200
},
{
id: 'node3',
label: 'node3-group2',
x: 300,
y: 100
},
{
id: 'node4',
label: 'node6-group5',
groupId: 'group5',
x: 450,
y: 200
},
{
id: 'node8',
label: 'node8-group5',
x: 400,
y: 100
},
],
edges: [
{
source: 'node1',
target: 'node2'
},
{
source: 'node2',
target: 'node3'
},
{
source: 'node1',
target: 'node3'
},
{
source: 'node6',
target: 'node1'
}
],
groups: [
{
id: 'group3',
parentId: 'p2',
title: {
text: '我的第一个群组',
// stroke: '#444',
offsetX: 0,
offsetY: 0
},
},
{
id: 'p2',
title: {
text: '我的第一个群组',
stroke: 'red',
offsetX: 0,
offsetY: 0
},
},
{
id: 'group5'
},
{
id: 'group1'
}
]
};
graph.data(data)
graph.render()
console.log(graph.save())
document.getElementById('createGroup').addEventListener('click', evt => {
graph.addItem('group', {
groupId: 'p212',
nodes: ['node3', 'node8'],
type: 'rect',
title: '自定义分组'
} )
console.log(graph.save())
})
</script>
</body>
</html>

View File

@ -1,6 +1,6 @@
{
"name": "@antv/g6",
"version": "3.1.2",
"version": "3.1.3",
"description": "graph visualization frame work",
"main": "build/g6.js",
"homepage": "https://github.com/antvis/g6",
@ -44,7 +44,6 @@
"babel-loader": "^8.0.0",
"babel-plugin-module-resolver": "^3.1.1",
"babel-plugin-transform-remove-strict-mode": "~0.0.2",
"babel-polyfill": "^6.26.0",
"body-parser": "~1.18.2",
"chai": "~4.1.2",
"chai-almost": "^1.0.1",
@ -128,4 +127,4 @@
"engines": {
"node": ">=8.9.0"
}
}
}

View File

@ -3,7 +3,7 @@
*/
module.exports = {
version: '3.1.2',
version: '3.1.3',
rootContainerClassName: 'root-container',
nodeContainerClassName: 'node-container',
edgeContainerClassName: 'edge-container',

View File

@ -77,11 +77,18 @@ class CustomGroup {
* @param {string} type 群组类型默认为circle支持rect
* @param {number} zIndex 群组层级默认为0
* @param {boolean} updateDataModel 是否更新节点数据默认为false只有当手动创建group时才为true
* @param {object} title 分组标题配置
* @memberof ItemGroup
* @return {object} null
*/
create(groupId, nodes, type = 'circle', zIndex = 0, updateDataModel = false) {
create(groupId, nodes, type = 'circle', zIndex = 0, updateDataModel = false, title = {}) {
const graph = this.graph;
const customGroup = graph.get('customGroup');
const hasGroupIds = customGroup.get('children').map(data => data.get('id'));
if (hasGroupIds.indexOf(groupId) > -1) {
return console.warn(`已经存在ID为 ${groupId} 的分组请重新设置分组ID`);
}
const nodeGroup = customGroup.addGroup({
id: groupId,
zIndex
@ -101,6 +108,30 @@ class CustomGroup {
// 根据groupId获取group数据判断是否需要添加title
let groupTitle = null;
// 只有手动创建group时执行以下逻辑
if (updateDataModel) {
const groups = graph.get('groups');
// 如果是手动创建group则原始数据中是没有groupId信息的需要将groupId添加到node中
nodes.forEach(nodeId => {
const node = graph.findById(nodeId);
const model = node.getModel();
if (!model.groupId) {
model.groupId = groupId;
}
});
// 如果是手动创建 group则将 group 也添加到 groups 中
if (!groups.find(data => data.id === groupId)) {
groups.push({
id: groupId,
title
});
graph.set({
groups
});
}
}
const groupData = graph.get('groups').filter(data => data.id === groupId);
if (groupData && groupData.length > 0) {
@ -169,6 +200,7 @@ class CustomGroup {
const textShape = nodeGroup.addShape('text', {
attrs: {
text,
stroke: '#444',
x: titleX + offsetX,
y: titleY + offsetY,
...titleStyle
@ -183,18 +215,6 @@ class CustomGroup {
// 设置graph中groupNodes的值
graph.get('groupNodes')[groupId] = nodes;
// 只有手动创建group时执行以下逻辑
if (updateDataModel) {
// 如果是手动创建group则原始数据中是没有groupId信息的需要将groupId添加到node中
nodes.forEach(nodeId => {
const node = graph.findById(nodeId);
const model = node.getModel();
if (!model.groupId) {
model.groupId = groupId;
}
});
}
graph.setAutoPaint(autoPaint);
graph.paint();
}
@ -1007,7 +1027,6 @@ class CustomGroup {
}
groupKeyShape.attr(keyshapePosition);
}
// 如果存在标题,则更新标题位置
this.updateGroupTitle(nodeGroup, id, titleX, titleY);
});
@ -1033,8 +1052,8 @@ class CustomGroup {
let offsetX = 0;
let offsetY = 0;
if (titleConfig) {
offsetX = titleConfig.offsetX;
offsetY = titleConfig.offsetY;
offsetX = titleConfig.offsetX || 0;
offsetY = titleConfig.offsetY || 0;
}
groupTitleShape.attr({
x: x + offsetX,

View File

@ -5,7 +5,7 @@
* @LastEditTime: 2019-08-22 11:22:16
* @Description: Graph
*/
const { groupBy } = require('lodash');
const { groupBy, isString } = require('lodash');
const G = require('@antv/g/lib');
const EventEmitter = G.EventEmitter;
const Util = require('../util');
@ -359,8 +359,14 @@ class Graph extends EventEmitter {
*/
addItem(type, model) {
if (type === 'group') {
const { groupId, nodes, type, zIndex } = model;
return this.get('customGroupControll').create(groupId, nodes, type, zIndex, true);
const { groupId, nodes, type, zIndex, title } = model;
let groupTitle = title;
if (isString(title)) {
groupTitle = {
text: title
};
}
return this.get('customGroupControll').create(groupId, nodes, type, zIndex, true, groupTitle);
}
return this.get('itemController').addItem(type, model);
}
@ -546,14 +552,25 @@ class Graph extends EventEmitter {
// 存在单个群组
// 获取所有有groupID的node
const nodeInGroup = nodes.filter(node => node.groupId);
const groupsArr = [];
// 根据groupID分组
const groupIds = groupBy(nodeInGroup, 'groupId');
for (const groupId in groupIds) {
const nodeIds = groupIds[groupId].map(node => node.id);
this.get('customGroupControll').create(groupId, nodeIds, groupType, groupIndex);
groupIndex--;
// 获取所有不重复的 groupId
if (!groupsArr.find(data => data.id === groupId)) {
groupsArr.push({
id: groupId
});
}
}
this.set({
groups: groupsArr
});
} else {
// 将groups的数据存到groups中
this.set({ groups });

View File

@ -7,7 +7,6 @@ const G = require('@antv/g/lib');
const Shape = require('./shape');
const Layout = require('./layout');
const Behaviors = require('./behavior');
require('babel-polyfill');
const G6 = {
Graph: require('./graph/graph'),

View File

@ -609,7 +609,7 @@ describe.only('signle layer group', () => {
expect(groupNodes.p1.length).eql(1);
const groups = graph.get('groups');
expect(groups.length).eql(0);
expect(groups.length).eql(4);
// 删除group1
const customGroup = graph.get('customGroupControll');
@ -945,3 +945,91 @@ describe.only('nesting layer group', () => {
expect(graph.destroyed).to.be.true;
});
});
// 手动创建分子
describe.only('create node group', () => {
it('use addItem create group', () => {
const data = {
nodes: [
{
id: 'node1',
label: 'fck',
groupId: 'group1',
x: 100,
y: 100
},
{
id: 'node2',
label: 'node2',
x: 150,
y: 200
},
{
id: 'node3',
label: 'node3',
x: 300,
y: 100
}
],
edges: [
{
source: 'node1',
target: 'node2'
},
{
source: 'node2',
target: 'node3'
}
],
groups: [
{
id: 'group1',
title: '1'
}
]
};
const graph = new G6.Graph({
container: div,
width: 1500,
height: 1000,
pixelRatio: 2,
modes: {
default: [ 'drag-group' ]
},
defaultNode: {
shape: 'circleNode'
},
defaultEdge: {
color: '#bae7ff'
}
});
graph.data(data);
graph.render();
graph.data(data);
graph.render();
let { groups } = graph.save();
expect(groups.length).equal(1);
graph.addItem('group', {
groupId: 'xxx',
nodes: [ 'node2', 'node3' ],
type: 'rect',
title: '自定义'
});
groups = graph.save().groups;
expect(groups.length).eql(2);
const customGroup = graph.get('customGroup');
const children = customGroup.get('children');
expect(children.length).eql(2);
const { nodes } = graph.save();
const groupNodes = nodes.filter(node => node.groupId === 'xxx');
expect(groupNodes.length).eql(2);
});
});