diff --git a/demos/defaultNode2.html b/demos/defaultNode2.html
index 39b5d9eadd..bee9d7e96c 100644
--- a/demos/defaultNode2.html
+++ b/demos/defaultNode2.html
@@ -206,6 +206,106 @@
}
}
}, 'modelRect')
+
+ G6.registerNode('star1', {
+ labelPosition: 'bottom',
+ getCustomConfig() {
+ return {
+ default: {
+ fill: '#ff4d4f',
+ stroke: '#ffa39e',
+ icon: {
+ show: true
+ },
+ labelCfg: {
+ style: {
+ fontSize: 16,
+ fill: '#ff7875'
+ },
+ offset: 20
+ }
+ }
+ }
+ }
+ }, 'star')
+
+ G6.registerNode('star2', {
+ labelPosition: 'bottom',
+ getCustomConfig() {
+ return {
+ default: {
+ fill: '#bae637',
+ stroke: '#eaff8f',
+ icon: {
+ show: true,
+ width: 25,
+ height: 25,
+ img: 'https://gw.alipayobjects.com/zos/basement_prod/300a2523-67e0-4cbf-9d4a-67c077b40395.svg'
+ },
+ linkPoints: {
+ top: true
+ }
+ }
+ }
+ }
+ }, 'star')
+
+ G6.registerNode('star3', {
+ labelPosition: 'top',
+ getCustomConfig() {
+ return {
+ default: {
+ fill: '#73d13d',
+ stroke: '#b7eb8f',
+ icon: {
+ show: true,
+ width: 25,
+ height: 25
+ },
+ labelCfg: {
+ offset: 35
+ },
+ linkPoints: {
+ top: true,
+ left: true,
+ right: true,
+ leftBottom: true,
+ rightBottom: true,
+ fill: '#ff85c0',
+ size: 5
+ }
+ }
+ }
+ }
+ }, 'star')
+
+ G6.registerNode('star4', {
+ labelPosition: 'bottom',
+ getCustomConfig() {
+ return {
+ default: {
+ outerR: 100,
+ innerR: 30,
+ fill: '#ffc53d',
+ stroke: '#ffe58f',
+ icon: {
+ show: true,
+ width: 35,
+ height: 35
+ },
+ labelCfg: {
+ offset: 40
+ },
+ linkPoints: {
+ leftBottom: true,
+ rightBottom: true,
+ fill: '#40a9ff',
+ size: 6
+ }
+ }
+ }
+ }
+ }, 'star')
const data = {
nodes: [
@@ -290,6 +390,40 @@
x: 630,
y: 280,
shape: 'modelRect5'
+ },
+ {
+ id: 'star',
+ label: '逻辑回归',
+ x: 150,
+ y: 450,
+ shape: 'star'
+ },
+ {
+ id: 'star1',
+ label: '二次元逻辑',
+ x: 300,
+ y: 450,
+ shape: 'star1'
+ },
+ {
+ id: 'star2',
+ x: 450,
+ y: 450,
+ shape: 'star2'
+ },
+ {
+ id: 'star3',
+ label: '逻辑回归二次元逻辑回归二次元',
+ x: 600,
+ y: 450,
+ shape: 'star3'
+ },
+ {
+ id: 'star4',
+ label: '逻辑回归二次元逻辑回归二次元',
+ x: 800,
+ y: 450,
+ shape: 'star4'
}
]
}
diff --git a/src/shape/nodes/circle.js b/src/shape/nodes/circle.js
index 600711bd8d..59b2cccdec 100644
--- a/src/shape/nodes/circle.js
+++ b/src/shape/nodes/circle.js
@@ -35,7 +35,7 @@ Shape.registerNode('circle', {
icon: {
// 是否显示icon,值为 false 则不渲染icon
show: false,
- // icon的地址,可以是字符串或Image
+ // icon的地址,字符串类型
img: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg',
width: 16,
height: 16
diff --git a/src/shape/nodes/diamond.js b/src/shape/nodes/diamond.js
index ec00953669..5186aeb61c 100644
--- a/src/shape/nodes/diamond.js
+++ b/src/shape/nodes/diamond.js
@@ -34,7 +34,7 @@ Shape.registerNode('diamond', {
icon: {
// 是否显示icon,值为 false 则不渲染icon
show: false,
- // icon的地址,可以是字符串或Image
+ // icon的地址,字符串类型
img: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg',
width: 16,
height: 16
diff --git a/src/shape/nodes/ellipse.js b/src/shape/nodes/ellipse.js
index 0e6deff74c..24f4de9085 100644
--- a/src/shape/nodes/ellipse.js
+++ b/src/shape/nodes/ellipse.js
@@ -26,7 +26,7 @@ Shape.registerNode('ellipse', {
icon: {
// 是否显示icon,值为 false 则不渲染icon
show: false,
- // icon的地址,可以是字符串或Image
+ // icon的地址,字符串类型
img: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg',
width: 36,
height: 36
diff --git a/src/shape/nodes/index.js b/src/shape/nodes/index.js
index e6a4192320..7c4d2dfbd7 100644
--- a/src/shape/nodes/index.js
+++ b/src/shape/nodes/index.js
@@ -4,4 +4,4 @@ require('./ellipse');
require('./diamond');
require('./triangle');
require('./modelRect');
-
+require('./star');
diff --git a/src/shape/nodes/modelRect.js b/src/shape/nodes/modelRect.js
index 16907a9742..8ba450a741 100644
--- a/src/shape/nodes/modelRect.js
+++ b/src/shape/nodes/modelRect.js
@@ -48,7 +48,7 @@ Shape.registerNode('modelRect', {
show: true,
x: 0,
y: 0,
- // icon的地址,可以是字符串或Image
+ // icon的地址,字符串类型
img: 'https://gw.alipayobjects.com/zos/basement_prod/4f81893c-1806-4de4-aff3-9a6b266bc8a2.svg',
width: 16,
height: 16
@@ -57,7 +57,7 @@ Shape.registerNode('modelRect', {
stateIcon: {
// 是否显示icon,值为 false 则不渲染icon
show: true,
- // icon的地址,可以是字符串或Image
+ // icon的地址,字符串类型
img: 'https://gw.alipayobjects.com/zos/basement_prod/300a2523-67e0-4cbf-9d4a-67c077b40395.svg',
width: 16,
height: 16
diff --git a/src/shape/nodes/star.js b/src/shape/nodes/star.js
new file mode 100644
index 0000000000..1dd00d93ba
--- /dev/null
+++ b/src/shape/nodes/star.js
@@ -0,0 +1,349 @@
+const Shape = require('../shape');
+const deepMix = require('@antv/util/lib/deep-mix');
+
+// 菱形shape
+Shape.registerNode('star', {
+ // 自定义节点时的配置
+ options: {
+ // 默认配置
+ default: {
+ outerR: 60,
+ innerR: 20,
+ stroke: '#69c0ff',
+ fill: '#e6f7ff',
+ lineWidth: 1,
+ // 文本样式配置
+ labelCfg: {
+ style: {
+ fill: '#595959'
+ },
+ offset: 0
+ },
+ // 节点上左右上下四个方向上的链接circle配置
+ linkPoints: {
+ top: false,
+ right: false,
+ left: false,
+ leftBottom: false,
+ rightBottom: false,
+ // circle的大小
+ size: 3,
+ lineWidth: 1,
+ fill: '#fff',
+ stroke: '#72CC4A'
+ },
+ // 节点中icon配置
+ icon: {
+ // 是否显示icon,值为 false 则不渲染icon
+ show: false,
+ // icon的地址,字符串类型
+ img: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg',
+ width: 16,
+ height: 16
+ }
+ },
+ // 鼠标hover状态下的配置
+ hover: {
+ lineWidth: 3
+ },
+ // 选中节点状态下的配置
+ select: {
+ lineWidth: 5
+ }
+ },
+ shapeType: 'star',
+ // 文本位置
+ labelPosition: 'center',
+ drawShape(cfg, group) {
+ const customStyle = this.getCustomConfig(cfg) || {};
+ const defaultConfig = customStyle.default;
+ const style = deepMix({}, this.options.default, defaultConfig, cfg.style);
+ const { icon, linkPoints, outerR, ...starStyle } = style;
+ const path = this.getPath(cfg);
+ const keyShape = group.addShape('path', {
+ attrs: {
+ path,
+ ...starStyle
+ }
+ });
+
+ const { width: w, height: h, show } = icon;
+ if (show) {
+ const image = group.addShape('image', {
+ attrs: {
+ x: -w / 2,
+ y: -h / 2,
+ ...icon
+ },
+ className: 'star-icon'
+ });
+
+ image.set('capture', false);
+ }
+
+ const { top, left, right, leftBottom, rightBottom, size,
+ fill: anchorFill, stroke: anchorStroke, lineWidth: borderWidth } = linkPoints;
+
+ if (right) {
+ // right circle
+ // up down left right 四个方向的坐标均不相同
+ const x1 = Math.cos((18 + 72 * 0) / 180 * Math.PI) * outerR;
+ const y1 = Math.sin((18 + 72 * 0) / 180 * Math.PI) * outerR;
+
+ group.addShape('circle', {
+ attrs: {
+ x: x1,
+ y: -y1,
+ r: size,
+ fill: anchorFill,
+ stroke: anchorStroke,
+ lineWidth: borderWidth
+ },
+ className: 'star-anchor-right'
+ });
+ }
+
+ if (top) {
+ // up down left right 四个方向的坐标均不相同
+ const x1 = Math.cos((18 + 72 * 1) / 180 * Math.PI) * outerR;
+ const y1 = Math.sin((18 + 72 * 1) / 180 * Math.PI) * outerR;
+
+ // top circle
+ group.addShape('circle', {
+ attrs: {
+ x: x1,
+ y: -y1,
+ r: size,
+ fill: anchorFill,
+ stroke: anchorStroke,
+ lineWidth: borderWidth
+ },
+ className: 'star-anchor-top'
+ });
+ }
+
+ if (left) {
+ // up down left right 四个方向的坐标均不相同
+ const x1 = Math.cos((18 + 72 * 2) / 180 * Math.PI) * outerR;
+ const y1 = Math.sin((18 + 72 * 2) / 180 * Math.PI) * outerR;
+
+ // left circle
+ group.addShape('circle', {
+ attrs: {
+ x: x1,
+ y: -y1,
+ r: size,
+ fill: anchorFill,
+ stroke: anchorStroke,
+ lineWidth: borderWidth
+ },
+ className: 'star-anchor-left'
+ });
+ }
+
+ if (leftBottom) {
+ // up down left right 四个方向的坐标均不相同
+ const x1 = Math.cos((18 + 72 * 3) / 180 * Math.PI) * outerR;
+ const y1 = Math.sin((18 + 72 * 3) / 180 * Math.PI) * outerR;
+
+ // left bottom circle
+ group.addShape('circle', {
+ attrs: {
+ x: x1,
+ y: -y1,
+ r: size,
+ fill: anchorFill,
+ stroke: anchorStroke,
+ lineWidth: borderWidth
+ },
+ className: 'star-anchor-left-bottom'
+ });
+ }
+
+ if (rightBottom) {
+ // up down left right 四个方向的坐标均不相同
+ const x1 = Math.cos((18 + 72 * 4) / 180 * Math.PI) * outerR;
+ const y1 = Math.sin((18 + 72 * 4) / 180 * Math.PI) * outerR;
+
+ // left bottom circle
+ group.addShape('circle', {
+ attrs: {
+ x: x1,
+ y: -y1,
+ r: size,
+ fill: anchorFill,
+ stroke: anchorStroke,
+ lineWidth: borderWidth
+ },
+ className: 'star-anchor-right-bottom'
+ });
+ }
+
+ return keyShape;
+ },
+ shouldUpdate() {
+ return false;
+ },
+ getPath(cfg) {
+ const customStyle = this.getCustomConfig(cfg) || {};
+ const defaultConfig = customStyle.default;
+ const style = deepMix({}, this.options.default, defaultConfig, cfg.style);
+ const { outerR, innerR } = style;
+ const path = [];
+ for (let i = 0; i < 5; i++) {
+ const x1 = Math.cos((18 + 72 * i) / 180 * Math.PI) * outerR;
+ const y1 = Math.sin((18 + 72 * i) / 180 * Math.PI) * outerR;
+ const x2 = Math.cos((54 + 72 * i) / 180 * Math.PI) * innerR;
+ const y2 = Math.sin((54 + 72 * i) / 180 * Math.PI) * innerR;
+
+ if (i === 0) {
+ path.push([
+ 'M', x1, -y1
+ ]);
+ } else {
+ path.push([
+ 'L', x1, -y1
+ ]);
+ }
+ path.push([
+ 'L', x2, -y2
+ ]);
+ }
+
+ path.push([
+ 'Z'
+ ]);
+
+ return path;
+ },
+ /**
+ * 获取节点宽高
+ * @internal 返回节点的大小,以 [width, height] 的方式维护
+ * @param {Object} cfg 节点的配置项
+ * @return {Array} 宽高
+ */
+ getSize(cfg) {
+ const customStyle = this.getCustomConfig(cfg) || {};
+ const defaultConfig = customStyle.default;
+ const style = deepMix({}, this.options.default, defaultConfig, cfg.style);
+ const { outerR } = style;
+
+ return [ outerR, outerR ];
+ },
+ update(cfg, item) {
+ const group = item.getContainer();
+ const customStyle = this.getCustomConfig(cfg) || {};
+ const defaultConfig = customStyle.default || {};
+ const style = deepMix({}, this.options.default, defaultConfig, cfg.style);
+
+ const { icon, linkPoints, outerR,
+ labelCfg: defaultLabelCfg, ...starStyle } = style;
+ const keyShape = item.get('keyShape');
+ const path = this.getPath(cfg);
+ keyShape.attr({
+ path,
+ ...starStyle
+ });
+
+ const labelCfg = deepMix({}, defaultLabelCfg, cfg.labelCfg);
+ const labelStyle = this.getLabelStyle(cfg, labelCfg, group);
+
+ const text = group.findByClassName('node-label');
+ if (text) {
+ text.attr({
+ ...labelStyle
+ });
+ }
+
+ const starIcon = group.findByClassName('star-icon');
+ if (starIcon) {
+ const { width: w, height: h } = icon;
+ starIcon.attr({
+ x: -w / 2,
+ y: -h / 2,
+ ...icon
+ });
+ }
+
+ const { size, fill: anchorFill, stroke: anchorStroke, lineWidth: borderWidth } = linkPoints;
+
+ const anchorRight = group.findByClassName('star-anchor-right');
+ if (anchorRight) {
+ const x = Math.cos((18 + 72 * 0) / 180 * Math.PI) * outerR;
+ const y = Math.sin((18 + 72 * 0) / 180 * Math.PI) * outerR;
+
+ anchorRight.attr({
+ x,
+ y: -y,
+ r: size,
+ fill: anchorFill,
+ stroke: anchorStroke,
+ lineWidth: borderWidth
+ });
+ }
+
+ const anchorTop = group.findByClassName('star-anchor-top');
+ if (anchorTop) {
+ const x = Math.cos((18 + 72 * 1) / 180 * Math.PI) * outerR;
+ const y = Math.sin((18 + 72 * 1) / 180 * Math.PI) * outerR;
+
+ // top circle
+ anchorTop.attr({
+ x,
+ y: -y,
+ r: size,
+ fill: anchorFill,
+ stroke: anchorStroke,
+ lineWidth: borderWidth
+ });
+ }
+
+ const anchorLeft = group.findByClassName('star-anchor-left');
+ if (anchorLeft) {
+ const x = Math.cos((18 + 72 * 2) / 180 * Math.PI) * outerR;
+ const y = Math.sin((18 + 72 * 2) / 180 * Math.PI) * outerR;
+
+ // left circle
+ anchorLeft.attr({
+ x,
+ y: -y,
+ r: size,
+ fill: anchorFill,
+ stroke: anchorStroke,
+ lineWidth: borderWidth
+ });
+ }
+
+ const anchorLeftBottom = group.findByClassName('star-anchor-left-bottom');
+ if (anchorLeftBottom) {
+ const x = Math.cos((18 + 72 * 3) / 180 * Math.PI) * outerR;
+ const y = Math.sin((18 + 72 * 3) / 180 * Math.PI) * outerR;
+
+ // bottom circle
+ anchorLeftBottom.attr({
+ x,
+ y: -y,
+ r: size,
+ fill: anchorFill,
+ stroke: anchorStroke,
+ lineWidth: borderWidth
+ });
+ }
+
+ const anchorRightBottom = group.findByClassName('star-anchor-right-bottom');
+ if (anchorRightBottom) {
+ const x = Math.cos((18 + 72 * 4) / 180 * Math.PI) * outerR;
+ const y = Math.sin((18 + 72 * 4) / 180 * Math.PI) * outerR;
+
+ // bottom circle
+ anchorRightBottom.attr({
+ x,
+ y: -y,
+ r: size,
+ fill: anchorFill,
+ stroke: anchorStroke,
+ lineWidth: borderWidth
+ });
+ }
+ }
+}, 'single-shape');
diff --git a/src/shape/nodes/triangle.js b/src/shape/nodes/triangle.js
index 22c7973efb..1d3881efca 100644
--- a/src/shape/nodes/triangle.js
+++ b/src/shape/nodes/triangle.js
@@ -15,7 +15,7 @@ Shape.registerNode('triangle', {
// 文本样式配置
labelCfg: {
style: {
- fill: '#000'
+ fill: '#595959'
},
offset: 15
},
@@ -35,7 +35,7 @@ Shape.registerNode('triangle', {
icon: {
// 是否显示icon,值为 false 则不渲染icon
show: false,
- // icon的地址,可以是字符串或Image
+ // icon的地址,字符串类型
img: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg',
width: 16,
height: 16,
diff --git a/src/shape/single-shape-mixin.js b/src/shape/single-shape-mixin.js
index d82da7c102..a7a792c627 100644
--- a/src/shape/single-shape-mixin.js
+++ b/src/shape/single-shape-mixin.js
@@ -40,13 +40,6 @@ const SingleShape = {
},
drawLabel(cfg, group) {
- // const labelCfg = cfg.labelCfg || {};
- // const labelStyle = this.getLabelStyle(cfg, labelCfg, group);
- // const label = group.addShape('text', {
- // attrs: labelStyle
- // });
- // return label;
-
const customStyle = this.getCustomConfig(cfg) || {};
const defaultConfig = customStyle.default;
const style = merge({}, this.options.default, defaultConfig);