diff --git a/demos/area-chart-node.html b/demos/area-chart-node.html
new file mode 100644
index 0000000000..ece3ae89ea
--- /dev/null
+++ b/demos/area-chart-node.html
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+ 面积图节点
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/bar-chart-node.html b/demos/bar-chart-node.html
new file mode 100644
index 0000000000..144fc35a28
--- /dev/null
+++ b/demos/bar-chart-node.html
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+ 环形柱状图节点
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/chart-node.html b/demos/chart-node.html
new file mode 100644
index 0000000000..47e2170f27
--- /dev/null
+++ b/demos/chart-node.html
@@ -0,0 +1,936 @@
+
+
+
+
+
+
+ 统计图表节点
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/collapse-expand-group.html b/demos/collapse-expand-group.html
index d3aca772c9..9558df285b 100644
--- a/demos/collapse-expand-group.html
+++ b/demos/collapse-expand-group.html
@@ -40,6 +40,33 @@
},
modes: {
default: [ 'drag-canvas', 'zoom-canvas', 'collapse-expand-group' ]
+ },
+ groupStyle: {
+ default: {
+ lineWidth: 2,
+ stroke: '#A3B1BF',
+ radius: 10,
+ lineDash: [ 5, 5 ],
+ strokeOpacity: 0.9,
+ fill: '#F3F9FF',
+ fillOpacity: 0.8,
+ opacity: 0.8
+ },
+ hover: {
+ stroke: '#faad14',
+ fill: '#ffe58f',
+ fillOpacity: 0.3,
+ opacity: 0.3,
+ lineWidth: 3
+ },
+ // 收起状态样式
+ collapseStyle: {
+ r: 50,
+ // lineDash: [ 5, 5 ],
+ stroke: '#ffa39e',
+ lineWidth: 3,
+ fill: '#ffccc7'
+ }
}
});
diff --git a/demos/custom-tree-interactive.html b/demos/custom-tree-interactive.html
new file mode 100644
index 0000000000..d9ca0c2600
--- /dev/null
+++ b/demos/custom-tree-interactive.html
@@ -0,0 +1,587 @@
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/front-edge.html b/demos/front-edge.html
index f18494a3ca..915f61b226 100644
--- a/demos/front-edge.html
+++ b/demos/front-edge.html
@@ -60,7 +60,6 @@
document.getElementById('changeView').addEventListener('click', (evt) => {
const edge=graph.findById('edge1')
const nodeGroup = graph.get('nodeGroup')
- const edgeGroup = graph.get('edgeGroup')
const edge1G = edge.get('group')
edge1G.toFront()
nodeGroup.toBack();
diff --git a/demos/line-chart-node.html b/demos/line-chart-node.html
new file mode 100644
index 0000000000..398e3f8bda
--- /dev/null
+++ b/demos/line-chart-node.html
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+ 折线图节点
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/point-chart-node.html b/demos/point-chart-node.html
new file mode 100644
index 0000000000..4fc462169c
--- /dev/null
+++ b/demos/point-chart-node.html
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+ 标注图节点
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/stacked-bar-chart-node.html b/demos/stacked-bar-chart-node.html
new file mode 100644
index 0000000000..542d679043
--- /dev/null
+++ b/demos/stacked-bar-chart-node.html
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+ 堆叠柱状图节点
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index a29201b211..e8f38ae3ca 100644
--- a/package.json
+++ b/package.json
@@ -98,7 +98,7 @@
"screenshot": "node ./bin/screenshot.js",
"start": "npm run dev",
"test": "torch --compile --renderer --opts test/mocha.opts --recursive ./test/unit",
- "test-live": "torch --compile --interactive --watch --opts test/mocha.opts --recursive ./test/unit/behavior/drag-group-spec.js",
+ "test-live": "torch --compile --interactive --watch --opts test/mocha.opts --recursive ./test/unit/graph/controller/custom-group-spec.js",
"test-live-tree": "torch --compile --interactive --watch --opts test/mocha.opts --recursive ./test/unit/graph/tree-graph-spec.js",
"test-bugs": "torch --compile --renderer --recursive ./test/bugs",
"test-bugs-live": "torch --compile --interactive --watch --recursive ./test/bugs",
diff --git a/src/behavior/drag-group.js b/src/behavior/drag-group.js
index 512c6cf1ea..d7bade3965 100644
--- a/src/behavior/drag-group.js
+++ b/src/behavior/drag-group.js
@@ -5,7 +5,7 @@
* @LastEditTime: 2019-08-23 11:13:43
* @Description: 拖动群组
*/
-const { merge } = require('lodash');
+const deepMix = require('@antv/util/lib/deep-mix');
const delegateStyle = {
fill: '#F3F9FF',
@@ -275,7 +275,7 @@ module.exports = {
height,
x,
y,
- ...merge({}, delegateStyle, this.delegateStyle)
+ ...deepMix({}, delegateStyle, this.delegateStyle)
};
// 如果delegate是circle
@@ -289,7 +289,7 @@ module.exports = {
x: cx,
y: cy,
r,
- ...merge({}, delegateStyle, this.delegateStyle)
+ ...deepMix({}, delegateStyle, this.delegateStyle)
}
});
self.shapeOrigin = { x: cx, y: cy };
diff --git a/src/behavior/drag-node-with-group.js b/src/behavior/drag-node-with-group.js
index b5a6a6361b..aedcf2fd83 100644
--- a/src/behavior/drag-node-with-group.js
+++ b/src/behavior/drag-node-with-group.js
@@ -5,7 +5,7 @@
* @LastEditTime: 2019-08-23 13:54:53
* @Description: 有group的情况下,拖动节点的Behavior
*/
-const { merge } = require('lodash');
+const deepMix = require('@antv/util/lib/deep-mix');
const { delegateStyle } = require('../global');
const body = document.body;
@@ -15,8 +15,8 @@ module.exports = {
updateEdge: true,
delegate: true,
delegateStyle: {},
- maxMultiple: 1.2,
- minMultiple: 0.8
+ maxMultiple: 0.9,
+ minMultiple: 1
};
},
getEvents() {
@@ -26,12 +26,16 @@ module.exports = {
'node:dragend': 'onDragEnd',
'canvas:mouseleave': 'onOutOfRange',
mouseenter: 'onMouseEnter',
- mouseout: 'onMouseOut'
+ mouseleave: 'onMouseLeave'
};
},
onMouseEnter(evt) {
const { target } = evt;
const groupId = target.get('groupId');
+ const type = target.get('type');
+ if (type !== 'circle') {
+ return;
+ }
if (groupId && this.origin) {
const graph = this.graph;
const customGroupControll = graph.get('customGroupControll');
@@ -47,7 +51,7 @@ module.exports = {
* 拖动节点移除Group时的事件
* @param {Event} evt 事件句柄
*/
- onMouseOut(evt) {
+ onMouseLeave(evt) {
const { target } = evt;
const groupId = target.get('groupId');
if (groupId && this.origin) {
@@ -59,7 +63,10 @@ module.exports = {
customGroupControll.setGroupStyle(keyShape, 'default');
}
- this.inGroupId = null;
+
+ if (!groupId) {
+ this.inGroupId = null;
+ }
},
onDragStart(e) {
if (!this.shouldBegin.call(this, e)) {
@@ -93,6 +100,9 @@ module.exports = {
const customGroup = customGroupControll.customGroup;
const currentGroup = customGroup[groupId].nodeGroup;
customGroupControll.setGroupStyle(currentGroup.get('keyShape'), 'hover');
+
+ // 初始拖动时候,如果是在当前群组中拖动,则赋值为当前groupId
+ this.inGroupId = groupId;
}
} else {
// 拖动多个节点
@@ -137,13 +147,8 @@ module.exports = {
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) {
+ // 当前
+ if (this.inGroupId !== groupId) {
customGroupControll.setGroupStyle(keyShape, 'default');
} else {
customGroupControll.setGroupStyle(keyShape, 'hover');
@@ -224,11 +229,12 @@ module.exports = {
// 检测操作的群组中是否包括子群组
const groups = graph.get('groups');
const hasSubGroup = !!groups.filter(g => g.parentId === groupId).length > 0;
- const r = width > height ? width / 2 : height / 2 + (hasSubGroup ? 20 : 0);
+ const addR = hasSubGroup ? 20 : 10;
+ const r = width > height ? width / 2 : height / 2;
const cx = (width + 2 * x) / 2;
const cy = (height + 2 * y) / 2;
keyShape.attr({
- r: r + groupNodes[groupId].length * 10,
+ r: r + groupNodes[groupId].length * 10 + addR,
x: cx,
y: cy
});
@@ -247,7 +253,6 @@ module.exports = {
// 节点所在的GroupId
const { groupId, id } = model;
- // console.log(groupId, this.inGroupId)
const customGroupControll = graph.get('customGroupControll');
const customGroup = customGroupControll.customGroup;
const groupNodes = graph.get('groupNodes');
@@ -262,7 +267,11 @@ module.exports = {
const { minX, minY, maxX, maxY } = currentGroupBBox;
// 在自己的group中拖动,判断是否拖出了自己的group
- if (!(x < maxX * this.maxMultiple && x > minX * this.minMultiple && y < maxY * this.maxMultiple && y > minY * this.minMultiple)) {
+ // 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
const currentGroupNodes = groupNodes[groupId];
groupNodes[groupId] = currentGroupNodes.filter(node => node !== id);
@@ -274,8 +283,10 @@ module.exports = {
}
// 拖动到其他的group上面
if (this.inGroupId !== groupId) {
+
+ // 拖动新的group后,更新groupNodes及model中的groupId
const nodeInGroup = customGroup[this.inGroupId].nodeGroup;
- const keyShape = nodeInGroup.get('keyShape');
+ const targetKeyShape = nodeInGroup.get('keyShape');
// 将该节点添加到inGroupId中
if (groupNodes[this.inGroupId].indexOf(id) === -1) {
groupNodes[this.inGroupId].push(id);
@@ -284,7 +295,7 @@ module.exports = {
model.groupId = this.inGroupId;
// 拖入节点后,根据最新的节点数量,重新计算群组大小
- this.dynamicChangeGroupSize(evt, nodeInGroup, keyShape);
+ this.dynamicChangeGroupSize(evt, nodeInGroup, targetKeyShape);
}
customGroupControll.setGroupStyle(keyShape, 'default');
} else if (this.inGroupId && !groupId) {
@@ -372,7 +383,7 @@ module.exports = {
if (!this.shape) {
// 拖动多个
const parent = graph.get('group');
- const attrs = merge({}, delegateStyle, this.delegateStyle);
+ const attrs = deepMix({}, delegateStyle, this.delegateStyle);
if (this.targets.length > 0) {
const nodes = graph.findAllByState('node', 'selected');
if (nodes.length === 0) {
diff --git a/src/behavior/drag-node.js b/src/behavior/drag-node.js
index 4496d808f1..f811668d7b 100644
--- a/src/behavior/drag-node.js
+++ b/src/behavior/drag-node.js
@@ -5,7 +5,8 @@
* @LastEditTime: 2019-08-22 18:41:45
* @Description: 拖动节点的Behavior
*/
-const { merge, isString } = require('lodash');
+const isString = require('@antv/util/lib/type/is-string');
+const deepMix = require('@antv/util/lib/deep-mix');
const { delegateStyle } = require('../global');
const body = document.body;
@@ -174,7 +175,7 @@ module.exports = {
if (!this.shape) {
// 拖动多个
const parent = this.graph.get('group');
- const attrs = merge({}, delegateStyle, this.delegateStyle);
+ const attrs = deepMix({}, delegateStyle, this.delegateStyle);
if (this.targets.length > 0) {
const { x, y, width, height, minX, minY } = this.calculationGroupPosition();
this.originPoint = { x, y, width, height, minX, minY };
diff --git a/src/graph/controller/customGroup.js b/src/graph/controller/customGroup.js
index 1586705e6d..9fd14bf129 100644
--- a/src/graph/controller/customGroup.js
+++ b/src/graph/controller/customGroup.js
@@ -5,8 +5,8 @@
* @LastEditTime: 2019-08-23 11:44:32
* @Description: Group Controller
*/
-const { merge, isString } = require('lodash');
-
+const isString = require('@antv/util/lib/type/is-string');
+const deepMix = require('@antv/util/lib/deep-mix');
class CustomGroup {
getDefaultCfg() {
return {
@@ -60,7 +60,8 @@ class CustomGroup {
// const { cfg = {} } = options;
this.graph = graph;
window.graph = graph;
- this.styles = this.getDefaultCfg();
+ const groupStyle = graph.get('groupStyle');
+ this.styles = deepMix({}, this.getDefaultCfg(), groupStyle);
// 创建的群组集合
this.customGroup = {};
// 群组初始位置集合
@@ -154,12 +155,12 @@ class CustomGroup {
const { hover: hoverStyle, default: defaultStyle } = this.styles;
if (isString(style)) {
if (style === 'default') {
- styles = merge({}, defaultStyle);
+ styles = deepMix({}, defaultStyle);
} else if (style === 'hover') {
- styles = merge({}, hoverStyle);
+ styles = deepMix({}, hoverStyle);
}
} else {
- styles = merge({}, defaultStyle, style);
+ styles = deepMix({}, defaultStyle, style);
}
for (const s in styles) {
keyShape.attr(s, styles[s]);
@@ -328,7 +329,7 @@ class CustomGroup {
} else {
// 更新时候merge配置项
const { groupStyle } = customGroupStyle;
- const styles = merge({}, groupStyle, property);
+ const styles = deepMix({}, groupStyle, property);
this.customGroup[groupId] = {
nodeGroup: deletage,
groupStyle: styles
@@ -536,7 +537,7 @@ class CustomGroup {
});
// 缓存群组groupId下的edge和临时生成的node节点
- this.delegateInGroup[groupId] = merge({
+ this.delegateInGroup[groupId] = deepMix({
sourceOutTargetInEdges,
sourceInTargetOutEdges,
edgesOuts,
@@ -571,7 +572,7 @@ class CustomGroup {
const { default: defaultStyle } = this.styles;
- // const styles = merge({}, defaultStyle, { x: cx, y: cy });
+ // const styles = deepMix({}, defaultStyle, { x: cx, y: cy });
for (const style in defaultStyle) {
keyShape.attr(style, defaultStyle[style]);
}
diff --git a/src/graph/graph.js b/src/graph/graph.js
index ec42022b63..c16774d6a0 100755
--- a/src/graph/graph.js
+++ b/src/graph/graph.js
@@ -3,11 +3,7 @@
* @Date: 2019-06-27 18:12:06
* @LastEditors: moyee
* @LastEditTime: 2019-08-22 11:22:16
- * @Description: file content
- */
-/**
- * @fileOverview graph
- * @author huangtonger@aliyun.com
+ * @Description: Graph
*/
const { groupBy } = require('lodash');
const G = require('@antv/g/lib');
@@ -200,7 +196,8 @@ class Graph extends EventEmitter {
/**
* 群组的原始数据
*/
- groups: []
+ groups: [],
+ groupStyle: {}
};
}
diff --git a/test/unit/graph/controller/custom-group-spec.js b/test/unit/graph/controller/custom-group-spec.js
index 3c3b7fb49a..4994490ac8 100644
--- a/test/unit/graph/controller/custom-group-spec.js
+++ b/test/unit/graph/controller/custom-group-spec.js
@@ -594,7 +594,7 @@ describe.only('signle layer group', () => {
expect(isVisible).to.be.true;
}
- expect(keyShape.attr('r')).eql(groupStyle.r);
+ expect(keyShape.attr('r')).eql(30);
expect(keyShape.attr('x')).eql(groupStyle.x);
expect(keyShape.attr('y')).eql(groupStyle.y);