diff --git a/packages/g6/__tests__/demo/static/node-rect.ts b/packages/g6/__tests__/demo/static/node-rect.ts index e16a73c0a2a..add2d075b31 100644 --- a/packages/g6/__tests__/demo/static/node-rect.ts +++ b/packages/g6/__tests__/demo/static/node-rect.ts @@ -1,162 +1,86 @@ -import { Line } from '../../../src/elements/edges'; -import { Rect } from '../../../src/elements/nodes'; +import { Graph } from '../../../src'; import type { StaticTestCase } from '../types'; export const nodeRect: StaticTestCase = async (context) => { const { canvas } = context; - canvas.appendChild( - new Rect({ - style: { - x: 100, - y: 50, - fill: '#f8f8f8', - stroke: '#8b9baf', - width: 50, - height: 50, - labelText: 'simple', - labelWordWrapWidth: 100, - labelPosition: 'bottom', - }, - }), - ); - - canvas.appendChild( - new Rect({ - style: { - x: 200, - y: 50, - fill: '#f8f8f8', - stroke: '#8b9baf', - width: 50, - height: 20, - iconText: 'Y', - iconFontSize: 14, - iconFill: '#5B8FF9', - iconFontWeight: 800, - labelText: 'this is a looooooooooooooooooooog label', - }, - }), - ); + const data = { + nodes: [ + { id: 'rect' }, + { id: 'rect-halo' }, + { id: 'rect-badges' }, + { id: 'rect-ports' }, + { id: 'rect-active' }, + { id: 'rect-selected' }, + { id: 'rect-highlight' }, + { id: 'rect-inactive' }, + ], + }; - canvas.appendChild( - new Rect({ + const graph = new Graph({ + container: canvas, + data, + node: { style: { - // key - x: 300, - y: 50, - fill: '#f8f8f8', - stroke: '#8b9baf', - width: 50, - height: 70, - // label - label: false, - labelText: 'no-label', - // halo - halo: true, - // ports - ports: [{ position: 'left' }, { position: 'right' }, { position: 'top' }, { position: 'bottom' }], + type: 'rect', // 👈🏻 Node shape type. + radius: 4, // 👈🏻 Set the radius. + width: 40, + height: 40, + fill: '#1783FF', + labelText: (d) => d.id, + iconSrc: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg', + iconWidth: 30, + iconHeight: 30, + halo: (d) => d.id.includes('halo'), + ports: (d) => + d.id.includes('ports') + ? [{ position: 'left' }, { position: 'right' }, { position: 'top' }, { position: 'bottom' }] + : [], portStroke: '#31d0c6', portFill: '#fff', - portR: 4, - // icon - iconSrc: 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ', - // badges - badges: [ - { text: 'A', position: 'right-top', backgroundFill: '#8291b2', padding: [1, 4] }, - { text: 'Important', position: 'right', backgroundFill: '#e66c5b' }, - { text: 'Notice', position: 'right-bottom', backgroundFill: '#e5b95e' }, - ], + portR: 2, + portLineWidth: 1, + badges: (d) => + d.id.includes('badges') + ? [ + { text: 'A', position: 'right-top', backgroundFill: '#8291b2' }, + { text: 'Important', position: 'right', backgroundFill: '#e66c5b' }, + { text: 'Notice', position: 'right-bottom', backgroundFill: '#e5b95e' }, + ] + : [], badgeFill: '#fff', - badgeFontSize: 10, - }, - }), - ); - - const node1 = canvas.appendChild( - new Rect({ - id: 'node1', - style: { - x: 100, - y: 250, - fill: '#f8f8f8', - stroke: '#8b9baf', - // ports - ports: [ - { position: 'left', stroke: '#31d0c6', fill: '#fff' }, - { position: 'right', stroke: '#31d0c6', fill: '#fff' }, - { position: 'top', stroke: '#31d0c6', fill: '#fff' }, - { position: 'bottom', stroke: '#31d0c6', fill: '#fff' }, - ], - portR: 4, - }, - }), - ); - - const node2 = canvas.appendChild( - new Rect({ - id: 'node2', - style: { - x: 200, - y: 175, - fill: '#f8f8f8', - stroke: '#8b9baf', - // ports - ports: [ - { position: [0, 0.2], stroke: '#31d0c6', fill: '#fff' }, - { position: [0, 0.5], stroke: '#31d0c6', fill: '#fff' }, - { position: [0, 0.8], stroke: '#31d0c6', fill: '#fff' }, - ], - portR: 4, + badgeFontSize: 8, + badgePadding: [1, 4], }, - }), - ); - - canvas.appendChild( - new Line({ - id: 'line', - style: { - sourceNode: node1, - targetNode: node2, - stroke: '#1890FF', - endArrow: true, - }, - }), - ); - - const node3 = canvas.appendChild( - new Rect({ - id: 'node3', - style: { - x: 250, - y: 250, - fill: '#f8f8f8', - stroke: '#8b9baf', + state: { + active: { + halo: true, + }, + selected: { + halo: true, + lineWidth: 2, + stroke: '#000', + }, + highlight: { + halo: false, + lineWidth: 2, + stroke: '#000', + }, + inactive: { + opacity: 0.2, + }, }, - }), - ); + }, + layout: { + type: 'grid', + }, + animation: false, + }); - const node4 = canvas.appendChild( - new Rect({ - id: 'node4', - style: { - x: 350, - y: 175, - fill: '#f8f8f8', - stroke: '#8b9baf', - }, - }), - ); + await graph.render(); - canvas.appendChild( - new Line({ - id: 'line', - style: { - sourceNode: node3, - targetNode: node4, - stroke: '#1890FF', - endArrow: true, - }, - }), - ); + graph.setElementState('rect-active', 'active'); + graph.setElementState('rect-selected', 'selected'); + graph.setElementState('rect-highlight', 'highlight'); + graph.setElementState('rect-inactive', 'inactive'); }; diff --git a/packages/g6/__tests__/demo/static/node-triangle.ts b/packages/g6/__tests__/demo/static/node-triangle.ts index b3bf5350109..e7ea0c95743 100644 --- a/packages/g6/__tests__/demo/static/node-triangle.ts +++ b/packages/g6/__tests__/demo/static/node-triangle.ts @@ -1,6 +1,4 @@ -// Change to import { Graph } from '@antv/g6'; if you are using npm -// todo: when test env, use SVG always. -import { Graph } from '../../mock'; +import { Graph } from '../../../src'; import type { StaticTestCase } from '../types'; export const nodeTriangle: StaticTestCase = async (context) => { diff --git a/packages/g6/__tests__/integration/snapshots/static/controller-layout-dagre.svg b/packages/g6/__tests__/integration/snapshots/static/controller-layout-dagre.svg index 5d445a14823..e510e0c783f 100644 --- a/packages/g6/__tests__/integration/snapshots/static/controller-layout-dagre.svg +++ b/packages/g6/__tests__/integration/snapshots/static/controller-layout-dagre.svg @@ -18,11 +18,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -35,11 +35,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -52,11 +52,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -69,11 +69,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -86,11 +86,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -103,11 +103,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -120,11 +120,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -137,11 +137,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -154,11 +154,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -171,11 +171,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -188,11 +188,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + @@ -205,11 +205,11 @@ marker-end="false" transform="matrix(1,0,0,1,0,0)" > - + diff --git a/packages/g6/__tests__/integration/snapshots/static/edge-polyline.svg b/packages/g6/__tests__/integration/snapshots/static/edge-polyline.svg index 6c8d4afa1b4..9943e33c4db 100644 --- a/packages/g6/__tests__/integration/snapshots/static/edge-polyline.svg +++ b/packages/g6/__tests__/integration/snapshots/static/edge-polyline.svg @@ -16,11 +16,14 @@ height="20" transform="matrix(1,0,0,1,50,40)" > - - + @@ -90,11 +93,14 @@ height="20" transform="matrix(1,0,0,1,150,40)" > - - + @@ -168,11 +174,14 @@ height="20" transform="matrix(1,0,0,1,250,40)" > - - + @@ -236,11 +245,14 @@ height="20" transform="matrix(1,0,0,1,50,120)" > - - + @@ -278,11 +290,14 @@ height="20" transform="matrix(1,0,0,1,150,75)" > - - + @@ -336,11 +351,14 @@ height="20" transform="matrix(1,0,0,1,50,220)" > - - + @@ -378,11 +396,14 @@ height="20" transform="matrix(1,0,0,1,150,175)" > - - + @@ -436,11 +457,14 @@ height="20" transform="matrix(1,0,0,1,50,320)" > - - + @@ -478,11 +502,14 @@ height="20" transform="matrix(1,0,0,1,150,275)" > - - + @@ -536,11 +563,14 @@ height="20" transform="matrix(1,0,0,1,50,420)" > - - + @@ -588,11 +618,14 @@ height="20" transform="matrix(1,0,0,1,150,375)" > - - + @@ -646,11 +679,14 @@ height="20" transform="matrix(1,0,0,1,250,420)" > - - + @@ -688,11 +724,14 @@ height="50" transform="matrix(1,0,0,1,350,375)" > - - + diff --git a/packages/g6/__tests__/integration/snapshots/static/node-rect.svg b/packages/g6/__tests__/integration/snapshots/static/node-rect.svg index 3487fd9223d..93927523021 100644 --- a/packages/g6/__tests__/integration/snapshots/static/node-rect.svg +++ b/packages/g6/__tests__/integration/snapshots/static/node-rect.svg @@ -9,489 +9,723 @@ - - - - - - + + + + + - - - simple - + + + + + + + rect + + + + + + + - - - - - - - + + - - this is a looooo... - + + + + + + + + + rect-halo + + + + + + + - - Y - + - - - - - + + + + + + rect-badges + + + + - - - + height="30" + width="30" + transform="matrix(1,0,0,1,0,0)" + > + + + + + + + + + + + + A + + + + + + + + + + + + Important + + + + + + + + + + + + Notice + + + + - - - - - - - - - - - - - - - - - + + - A + rect-ports + + + + + + + + + + + + + + + + + - - - + + + + + + + + + - Important + rect-active + + + + + - - - + + + + + + + + + - Notice + rect-selected - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + height="30" + width="30" + transform="matrix(1,0,0,1,0,0)" + > + + + + + + + - - - - - - - - - - - - - - - + + + + + + rect-highlight + + + + - + height="30" + width="30" + transform="matrix(1,0,0,1,0,0)" + > + + + + + + + + + + + + + + rect-inactive + + + + + + + + diff --git a/packages/g6/__tests__/integration/snapshots/static/node-star.svg b/packages/g6/__tests__/integration/snapshots/static/node-star.svg index a3111a588b6..282e09e6b8a 100644 --- a/packages/g6/__tests__/integration/snapshots/static/node-star.svg +++ b/packages/g6/__tests__/integration/snapshots/static/node-star.svg @@ -370,11 +370,14 @@ height="50" transform="matrix(1,0,0,1,100,250)" > - - + diff --git a/packages/g6/src/elements/nodes/rect.ts b/packages/g6/src/elements/nodes/rect.ts index 0032873c838..3dd90434419 100644 --- a/packages/g6/src/elements/nodes/rect.ts +++ b/packages/g6/src/elements/nodes/rect.ts @@ -1,16 +1,18 @@ -import type { DisplayObjectConfig } from '@antv/g'; +import type { DisplayObjectConfig, RectStyleProps as GRectStyleProps, Group } from '@antv/g'; +import { Rect as GRect } from '@antv/g'; import { deepMix } from '@antv/util'; -import type { Point } from '../../types'; -import { getRectPoints } from '../../utils/element'; -import type { PolygonKeyStyleProps, PolygonStyleProps } from './polygon'; -import { Polygon } from './polygon'; +import type { BaseNodeProps } from '../../types'; +import type { BaseNodeStyleProps } from './base-node'; +import { BaseNode } from './base-node'; -type RectKeyStyleProps = PolygonKeyStyleProps; -export type RectStyleProps = PolygonStyleProps; +export type RectStyleProps = BaseNodeStyleProps; type ParsedRectStyleProps = Required; type RectOptions = DisplayObjectConfig; -export class Rect extends Polygon { +/** + * Draw Rect based on BaseNode, override drawKeyShape. + */ +export class Rect extends BaseNode { static defaultStyleProps: Partial = { width: 100, height: 30, @@ -20,7 +22,14 @@ export class Rect extends Polygon { super(deepMix({}, { style: Rect.defaultStyleProps }, options)); } - protected getPoints(attributes: ParsedRectStyleProps): Point[] { - return getRectPoints(Number(attributes.width), Number(attributes.height)); + protected getKeyStyle(attributes: ParsedRectStyleProps): GRectStyleProps { + return { + ...(super.getKeyStyle(attributes) as GRectStyleProps), + anchor: [0.5, 0.5], // !!! It cannot be set to default values because G.CustomElement cannot handle it properly. + }; + } + + protected drawKeyShape(attributes: ParsedRectStyleProps, container: Group): GRect | undefined { + return this.upsert('key', GRect, this.getKeyStyle(attributes), container); } } diff --git a/packages/g6/src/elements/shapes/base-shape.ts b/packages/g6/src/elements/shapes/base-shape.ts index 7bf067a82c6..cc4d227b625 100644 --- a/packages/g6/src/elements/shapes/base-shape.ts +++ b/packages/g6/src/elements/shapes/base-shape.ts @@ -117,8 +117,8 @@ export abstract class BaseShape extends CustomEle */ public getGraphicStyle>( attributes: T, - ): Omit { - const { x, y, className, transform, transformOrigin, anchor, context, ...style } = attributes; + ): Omit { + const { x, y, className, transform, transformOrigin, context, ...style } = attributes; return style; } diff --git a/packages/site/examples/item/defaultNodes/demo/meta.json b/packages/site/examples/item/defaultNodes/demo/meta.json index 65d4703733d..072bd9c1407 100644 --- a/packages/site/examples/item/defaultNodes/demo/meta.json +++ b/packages/site/examples/item/defaultNodes/demo/meta.json @@ -21,7 +21,7 @@ "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*etLSQYZnJAAAAAAAAAAAAAAADmJ7AQ/original" }, { - "filename": "radiusRect.js", + "filename": "radiusRect.ts", "title": { "zh": "圆角矩形", "en": "Radius Rect" diff --git a/packages/site/examples/item/defaultNodes/demo/radiusRect.js b/packages/site/examples/item/defaultNodes/demo/radiusRect.js deleted file mode 100644 index 3d9bbc3adba..00000000000 --- a/packages/site/examples/item/defaultNodes/demo/radiusRect.js +++ /dev/null @@ -1,136 +0,0 @@ -import { Graph } from '@antv/g6'; - -const data = { - nodes: [ - { - id: 'rect', - data: {}, - }, - { - id: 'rect-active', - data: {}, - }, - { - id: 'rect-selected', - data: {}, - }, - - { - id: 'rect-highlight', - data: {}, - }, - { - id: 'rect-inactive', - data: {}, - }, - { - id: 'rect-badges', - data: {}, - }, - { - id: 'rect-anchorShapes', - data: {}, - }, - ], -}; - -const container = document.getElementById('container'); -const width = container.scrollWidth; -const height = container.scrollHeight || 500; -const graph = new Graph({ - container: 'container', - width, - height, - modes: { - default: ['zoom-canvas', 'drag-canvas', 'drag-node', 'click-select'], - }, - plugins: [ - { - // lod-controller will be automatically assigned to graph with `disableLod: false` to graph if it is not configured as following - type: 'lod-controller', - disableLod: true, - }, - ], - data, - layout: { - type: 'grid', - }, - node: (model) => { - const { id, data } = model; - const config = { - id, - data: { - ...data, - type: 'rect-node', - keyShape: { - radius: 4, - }, - labelShape: { - text: id, - position: 'bottom', - maxWidth: '500%', - }, - labelBackgroundShape: {}, - iconShape: { - img: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg', - }, - animates: { - update: [ - { - fields: ['opacity'], - shapeId: 'haloShape', - states: ['selected', 'active'], - }, - { - fields: ['lineWidth'], - shapeId: 'keyShape', - states: ['selected', 'active'], - }, - ], - }, - }, - }; - if (id.includes('badges')) { - config.data.badgeShapes = [ - { - text: 'A', - position: 'rightTop', - }, - { - text: 'Important', - position: 'right', - }, - { - text: 'Notice', - position: 'rightBottom', - }, - ]; - } - if (id.includes('anchorShapes')) { - config.data.anchorShapes = [ - { - position: [0, 0.5], - }, - { - position: [0.5, 0], - }, - { - position: [0.5, 1], - }, - { - position: [1, 0.5], - }, - ]; - } - return config; - }, -}); - -graph.on('afterrender', (e) => { - graph.setItemState('rect-active', 'active', true); - graph.setItemState('rect-selected', 'selected', true); - graph.setItemState('rect-highlight', 'highlight', true); - graph.setItemState('rect-inactive', 'inactive', true); -}); - -window.graph = graph; diff --git a/packages/site/examples/item/defaultNodes/demo/radiusRect.ts b/packages/site/examples/item/defaultNodes/demo/radiusRect.ts new file mode 100644 index 00000000000..708b376e76e --- /dev/null +++ b/packages/site/examples/item/defaultNodes/demo/radiusRect.ts @@ -0,0 +1,82 @@ +import { Graph } from '@antv/g6'; + +const data = { + nodes: [ + { id: 'rect' }, + { id: 'rect-halo' }, + { id: 'rect-badges' }, + { id: 'rect-ports' }, + { id: 'rect-active' }, + { id: 'rect-selected' }, + { id: 'rect-highlight' }, + { id: 'rect-inactive' }, + ], +}; + +const graph = new Graph({ + container: 'container', + data, + node: { + style: { + type: 'rect', // 👈🏻 Node shape type. + radius: 4, // 👈🏻 Set the radius. + width: 40, + height: 40, + fill: '#1783FF', + labelText: (d) => d.id, + iconSrc: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg', + iconWidth: 30, + iconHeight: 30, + halo: (d) => d.id.includes('halo'), + ports: (d) => + d.id.includes('ports') + ? [{ position: 'left' }, { position: 'right' }, { position: 'top' }, { position: 'bottom' }] + : [], + portStroke: '#31d0c6', + portFill: '#fff', + portR: 2, + portLineWidth: 1, + badges: (d) => + d.id.includes('badges') + ? [ + { text: 'A', position: 'right-top', backgroundFill: '#8291b2' }, + { text: 'Important', position: 'right', backgroundFill: '#e66c5b' }, + { text: 'Notice', position: 'right-bottom', backgroundFill: '#e5b95e' }, + ] + : [], + badgeFill: '#fff', + badgeFontSize: 8, + badgePadding: [1, 4], + }, + state: { + active: { + halo: true, + }, + selected: { + halo: true, + lineWidth: 2, + stroke: '#000', + }, + highlight: { + halo: false, + lineWidth: 2, + stroke: '#000', + }, + inactive: { + opacity: 0.2, + }, + }, + }, + layout: { + type: 'grid', + }, +}); + +graph.render(); + +graph.on('afterrender', () => { + graph.setElementState('rect-active', 'active'); + graph.setElementState('rect-selected', 'selected'); + graph.setElementState('rect-highlight', 'highlight'); + graph.setElementState('rect-inactive', 'inactive'); +});