mirror of
https://gitee.com/antv/g6.git
synced 2024-12-03 04:08:32 +08:00
fix use addItem group not add data to groups
This commit is contained in:
parent
b8ee0d0d5a
commit
f08f37a270
177
demos/create-group.html
Normal file
177
demos/create-group.html
Normal 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>
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@antv/g6",
|
"name": "@antv/g6",
|
||||||
"version": "3.1.2",
|
"version": "3.1.3",
|
||||||
"description": "graph visualization frame work",
|
"description": "graph visualization frame work",
|
||||||
"main": "build/g6.js",
|
"main": "build/g6.js",
|
||||||
"homepage": "https://github.com/antvis/g6",
|
"homepage": "https://github.com/antvis/g6",
|
||||||
@ -44,7 +44,6 @@
|
|||||||
"babel-loader": "^8.0.0",
|
"babel-loader": "^8.0.0",
|
||||||
"babel-plugin-module-resolver": "^3.1.1",
|
"babel-plugin-module-resolver": "^3.1.1",
|
||||||
"babel-plugin-transform-remove-strict-mode": "~0.0.2",
|
"babel-plugin-transform-remove-strict-mode": "~0.0.2",
|
||||||
"babel-polyfill": "^6.26.0",
|
|
||||||
"body-parser": "~1.18.2",
|
"body-parser": "~1.18.2",
|
||||||
"chai": "~4.1.2",
|
"chai": "~4.1.2",
|
||||||
"chai-almost": "^1.0.1",
|
"chai-almost": "^1.0.1",
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
version: '3.1.2',
|
version: '3.1.3',
|
||||||
rootContainerClassName: 'root-container',
|
rootContainerClassName: 'root-container',
|
||||||
nodeContainerClassName: 'node-container',
|
nodeContainerClassName: 'node-container',
|
||||||
edgeContainerClassName: 'edge-container',
|
edgeContainerClassName: 'edge-container',
|
||||||
|
@ -77,11 +77,18 @@ class CustomGroup {
|
|||||||
* @param {string} type 群组类型,默认为circle,支持rect
|
* @param {string} type 群组类型,默认为circle,支持rect
|
||||||
* @param {number} zIndex 群组层级,默认为0
|
* @param {number} zIndex 群组层级,默认为0
|
||||||
* @param {boolean} updateDataModel 是否更新节点数据,默认为false,只有当手动创建group时才为true
|
* @param {boolean} updateDataModel 是否更新节点数据,默认为false,只有当手动创建group时才为true
|
||||||
|
* @param {object} title 分组标题配置
|
||||||
* @memberof ItemGroup
|
* @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 graph = this.graph;
|
||||||
const customGroup = graph.get('customGroup');
|
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({
|
const nodeGroup = customGroup.addGroup({
|
||||||
id: groupId,
|
id: groupId,
|
||||||
zIndex
|
zIndex
|
||||||
@ -101,6 +108,30 @@ class CustomGroup {
|
|||||||
|
|
||||||
// 根据groupId获取group数据,判断是否需要添加title
|
// 根据groupId获取group数据,判断是否需要添加title
|
||||||
let groupTitle = null;
|
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);
|
const groupData = graph.get('groups').filter(data => data.id === groupId);
|
||||||
|
|
||||||
if (groupData && groupData.length > 0) {
|
if (groupData && groupData.length > 0) {
|
||||||
@ -169,6 +200,7 @@ class CustomGroup {
|
|||||||
const textShape = nodeGroup.addShape('text', {
|
const textShape = nodeGroup.addShape('text', {
|
||||||
attrs: {
|
attrs: {
|
||||||
text,
|
text,
|
||||||
|
stroke: '#444',
|
||||||
x: titleX + offsetX,
|
x: titleX + offsetX,
|
||||||
y: titleY + offsetY,
|
y: titleY + offsetY,
|
||||||
...titleStyle
|
...titleStyle
|
||||||
@ -183,18 +215,6 @@ class CustomGroup {
|
|||||||
// 设置graph中groupNodes的值
|
// 设置graph中groupNodes的值
|
||||||
graph.get('groupNodes')[groupId] = nodes;
|
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.setAutoPaint(autoPaint);
|
||||||
graph.paint();
|
graph.paint();
|
||||||
}
|
}
|
||||||
@ -1007,7 +1027,6 @@ class CustomGroup {
|
|||||||
}
|
}
|
||||||
groupKeyShape.attr(keyshapePosition);
|
groupKeyShape.attr(keyshapePosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果存在标题,则更新标题位置
|
// 如果存在标题,则更新标题位置
|
||||||
this.updateGroupTitle(nodeGroup, id, titleX, titleY);
|
this.updateGroupTitle(nodeGroup, id, titleX, titleY);
|
||||||
});
|
});
|
||||||
@ -1033,8 +1052,8 @@ class CustomGroup {
|
|||||||
let offsetX = 0;
|
let offsetX = 0;
|
||||||
let offsetY = 0;
|
let offsetY = 0;
|
||||||
if (titleConfig) {
|
if (titleConfig) {
|
||||||
offsetX = titleConfig.offsetX;
|
offsetX = titleConfig.offsetX || 0;
|
||||||
offsetY = titleConfig.offsetY;
|
offsetY = titleConfig.offsetY || 0;
|
||||||
}
|
}
|
||||||
groupTitleShape.attr({
|
groupTitleShape.attr({
|
||||||
x: x + offsetX,
|
x: x + offsetX,
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* @LastEditTime: 2019-08-22 11:22:16
|
* @LastEditTime: 2019-08-22 11:22:16
|
||||||
* @Description: Graph
|
* @Description: Graph
|
||||||
*/
|
*/
|
||||||
const { groupBy } = require('lodash');
|
const { groupBy, isString } = 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');
|
||||||
@ -359,8 +359,14 @@ class Graph extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
addItem(type, model) {
|
addItem(type, model) {
|
||||||
if (type === 'group') {
|
if (type === 'group') {
|
||||||
const { groupId, nodes, type, zIndex } = model;
|
const { groupId, nodes, type, zIndex, title } = model;
|
||||||
return this.get('customGroupControll').create(groupId, nodes, type, zIndex, true);
|
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);
|
return this.get('itemController').addItem(type, model);
|
||||||
}
|
}
|
||||||
@ -546,14 +552,25 @@ class Graph extends EventEmitter {
|
|||||||
// 存在单个群组
|
// 存在单个群组
|
||||||
// 获取所有有groupID的node
|
// 获取所有有groupID的node
|
||||||
const nodeInGroup = nodes.filter(node => node.groupId);
|
const nodeInGroup = nodes.filter(node => node.groupId);
|
||||||
|
const groupsArr = [];
|
||||||
// 根据groupID分组
|
// 根据groupID分组
|
||||||
const groupIds = groupBy(nodeInGroup, 'groupId');
|
const groupIds = groupBy(nodeInGroup, 'groupId');
|
||||||
for (const groupId in groupIds) {
|
for (const groupId in groupIds) {
|
||||||
const nodeIds = groupIds[groupId].map(node => node.id);
|
const nodeIds = groupIds[groupId].map(node => node.id);
|
||||||
this.get('customGroupControll').create(groupId, nodeIds, groupType, groupIndex);
|
this.get('customGroupControll').create(groupId, nodeIds, groupType, groupIndex);
|
||||||
groupIndex--;
|
groupIndex--;
|
||||||
|
// 获取所有不重复的 groupId
|
||||||
|
if (!groupsArr.find(data => data.id === groupId)) {
|
||||||
|
groupsArr.push({
|
||||||
|
id: groupId
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set({
|
||||||
|
groups: groupsArr
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 将groups的数据存到groups中
|
// 将groups的数据存到groups中
|
||||||
this.set({ groups });
|
this.set({ groups });
|
||||||
|
@ -7,7 +7,6 @@ const G = require('@antv/g/lib');
|
|||||||
const Shape = require('./shape');
|
const Shape = require('./shape');
|
||||||
const Layout = require('./layout');
|
const Layout = require('./layout');
|
||||||
const Behaviors = require('./behavior');
|
const Behaviors = require('./behavior');
|
||||||
require('babel-polyfill');
|
|
||||||
|
|
||||||
const G6 = {
|
const G6 = {
|
||||||
Graph: require('./graph/graph'),
|
Graph: require('./graph/graph'),
|
||||||
|
@ -609,7 +609,7 @@ describe.only('signle layer group', () => {
|
|||||||
expect(groupNodes.p1.length).eql(1);
|
expect(groupNodes.p1.length).eql(1);
|
||||||
|
|
||||||
const groups = graph.get('groups');
|
const groups = graph.get('groups');
|
||||||
expect(groups.length).eql(0);
|
expect(groups.length).eql(4);
|
||||||
|
|
||||||
// 删除group1
|
// 删除group1
|
||||||
const customGroup = graph.get('customGroupControll');
|
const customGroup = graph.get('customGroupControll');
|
||||||
@ -945,3 +945,91 @@ describe.only('nesting layer group', () => {
|
|||||||
expect(graph.destroyed).to.be.true;
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user