diff --git a/packages/g6/__tests__/demos/element-node-triangle.ts b/packages/g6/__tests__/demos/element-node-triangle.ts index e175e3c0380..af6ab593a77 100644 --- a/packages/g6/__tests__/demos/element-node-triangle.ts +++ b/packages/g6/__tests__/demos/element-node-triangle.ts @@ -9,7 +9,7 @@ export const elementNodeTriangle: TestCase = async (context) => { type: 'triangle', // 👈🏻 Node shape type. style: { size: 40, - direction: (d: any) => (d.id === 'ports' ? 'left' : undefined), + direction: (d: any) => (d.id === 'ports' ? 'left' : 'up'), labelText: (d) => d.id!, iconSrc: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg', ports: (d) => (d.id === 'ports' ? [{ placement: 'left' }, { placement: 'top' }, { placement: 'bottom' }] : []), diff --git a/packages/g6/__tests__/unit/utils/style.spec.ts b/packages/g6/__tests__/unit/utils/style.spec.ts index fcadc9c4cf8..02d32ae8553 100644 --- a/packages/g6/__tests__/unit/utils/style.spec.ts +++ b/packages/g6/__tests__/unit/utils/style.spec.ts @@ -1,4 +1,4 @@ -import { computeElementCallbackStyle, zIndexOf } from '@/src/utils/style'; +import { computeElementCallbackStyle, mergeOptions, zIndexOf } from '@/src/utils/style'; describe('style', () => { it('computeElementCallbackStyle', () => { @@ -45,4 +45,13 @@ describe('style', () => { expect(zIndexOf({ id: 'node-1', style: { zIndex: 1 } })).toBe(1); expect(zIndexOf({ id: 'node-1', style: { zIndex: -1 } })).toBe(-1); }); + + it('mergeOptions', () => { + expect( + mergeOptions( + { style: { a: 1, b: [1, 2], c: { d: 1 } }, id: '1' }, + { style: { a: 2, b: [2, 3], c: { f: 1 } }, id: '2' }, + ), + ).toEqual({ style: { a: 2, b: [2, 3], c: { f: 1 } }, id: '2' }); + }); }); diff --git a/packages/g6/src/elements/combos/base-combo.ts b/packages/g6/src/elements/combos/base-combo.ts index 3db295e7927..4c7ff1509b6 100644 --- a/packages/g6/src/elements/combos/base-combo.ts +++ b/packages/g6/src/elements/combos/base-combo.ts @@ -1,5 +1,5 @@ import { AABB, BaseStyleProps, DisplayObject, DisplayObjectConfig, Group } from '@antv/g'; -import { deepMix, isFunction } from '@antv/util'; +import { isFunction } from '@antv/util'; import { COMBO_KEY } from '../../constants'; import type { CollapsedMarkerStyleProps, @@ -17,6 +17,7 @@ import { parsePadding } from '../../utils/padding'; import { getXYByPlacement, positionOf } from '../../utils/position'; import { subStyleProps } from '../../utils/prefix'; import { parseSize } from '../../utils/size'; +import { mergeOptions } from '../../utils/style'; import { add, divide } from '../../utils/vector'; import type { BaseNodeStyleProps } from '../nodes'; import { BaseNode } from '../nodes'; @@ -99,7 +100,7 @@ export abstract class BaseCombo) { - super(deepMix({}, { style: BaseCombo.defaultStyleProps }, options)); + super(mergeOptions({ style: BaseCombo.defaultStyleProps }, options)); } /** diff --git a/packages/g6/src/elements/edges/base-edge.ts b/packages/g6/src/elements/edges/base-edge.ts index 3a5469bf3c7..2bedee07f42 100644 --- a/packages/g6/src/elements/edges/base-edge.ts +++ b/packages/g6/src/elements/edges/base-edge.ts @@ -8,7 +8,7 @@ import type { } from '@antv/g'; import { Image, Path } from '@antv/g'; import type { PathArray } from '@antv/util'; -import { deepMix, isEmpty, isFunction } from '@antv/util'; +import { isEmpty, isFunction } from '@antv/util'; import type { BaseElementStyleProps, EdgeArrowStyleProps, @@ -26,6 +26,7 @@ import { getCubicLoopPath, getLabelPositionStyle } from '../../utils/edge'; import { findPorts, getConnectionPoint, isSameNode } from '../../utils/element'; import { omitStyleProps, subStyleProps } from '../../utils/prefix'; import { parseSize } from '../../utils/size'; +import { mergeOptions } from '../../utils/style'; import * as Symbol from '../../utils/symbol'; import { getWordWrapWidthByEnds } from '../../utils/text'; import { BaseElement } from '../base-element'; @@ -206,7 +207,7 @@ export abstract class BaseEdge extends BaseElement { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: BaseEdge.defaultStyleProps }, options)); + super(mergeOptions({ style: BaseEdge.defaultStyleProps }, options)); } protected get sourceNode() { diff --git a/packages/g6/src/elements/edges/cubic-horizontal.ts b/packages/g6/src/elements/edges/cubic-horizontal.ts index ef66e4b55d0..b18258b9643 100644 --- a/packages/g6/src/elements/edges/cubic-horizontal.ts +++ b/packages/g6/src/elements/edges/cubic-horizontal.ts @@ -1,6 +1,6 @@ import type { DisplayObjectConfig } from '@antv/g'; -import { deepMix } from '@antv/util'; import type { Point } from '../../types'; +import { mergeOptions } from '../../utils/style'; import type { BaseEdgeStyleProps } from './base-edge'; import { Cubic } from './cubic'; @@ -42,7 +42,7 @@ export class CubicHorizontal extends Cubic { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: CubicHorizontal.defaultStyleProps }, options)); + super(mergeOptions({ style: CubicHorizontal.defaultStyleProps }, options)); } protected getControlPoints( diff --git a/packages/g6/src/elements/edges/cubic-vertical.ts b/packages/g6/src/elements/edges/cubic-vertical.ts index 0480b30e872..0917ede3e37 100644 --- a/packages/g6/src/elements/edges/cubic-vertical.ts +++ b/packages/g6/src/elements/edges/cubic-vertical.ts @@ -1,6 +1,6 @@ import type { DisplayObjectConfig } from '@antv/g'; -import { deepMix } from '@antv/util'; import type { Point } from '../../types'; +import { mergeOptions } from '../../utils/style'; import type { BaseEdgeStyleProps } from './base-edge'; import { Cubic } from './cubic'; @@ -42,7 +42,7 @@ export class CubicVertical extends Cubic { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: CubicVertical.defaultStyleProps }, options)); + super(mergeOptions({ style: CubicVertical.defaultStyleProps }, options)); } protected getControlPoints( diff --git a/packages/g6/src/elements/edges/cubic.ts b/packages/g6/src/elements/edges/cubic.ts index ec65ac1b4d2..73d304d2149 100644 --- a/packages/g6/src/elements/edges/cubic.ts +++ b/packages/g6/src/elements/edges/cubic.ts @@ -1,8 +1,8 @@ import type { DisplayObjectConfig } from '@antv/g'; import type { PathArray } from '@antv/util'; -import { deepMix } from '@antv/util'; import type { Point } from '../../types'; import { getCubicPath, getCurveControlPoint, parseCurveOffset, parseCurvePosition } from '../../utils/edge'; +import { mergeOptions } from '../../utils/style'; import type { BaseEdgeStyleProps } from './base-edge'; import { BaseEdge } from './base-edge'; @@ -48,7 +48,7 @@ export class Cubic extends BaseEdge { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: Cubic.defaultStyleProps }, options)); + super(mergeOptions({ style: Cubic.defaultStyleProps }, options)); } /** diff --git a/packages/g6/src/elements/edges/line.ts b/packages/g6/src/elements/edges/line.ts index c503599ecd6..6486982f146 100644 --- a/packages/g6/src/elements/edges/line.ts +++ b/packages/g6/src/elements/edges/line.ts @@ -1,6 +1,6 @@ import type { DisplayObjectConfig } from '@antv/g'; import type { PathArray } from '@antv/util'; -import { deepMix } from '@antv/util'; +import { mergeOptions } from '../../utils/style'; import type { BaseEdgeStyleProps } from './base-edge'; import { BaseEdge } from './base-edge'; @@ -24,7 +24,7 @@ export class Line extends BaseEdge { static defaultStyleProps: Partial = {}; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: Line.defaultStyleProps }, options)); + super(mergeOptions({ style: Line.defaultStyleProps }, options)); } protected getKeyPath(attributes: ParsedLineStyleProps): PathArray { diff --git a/packages/g6/src/elements/edges/polyline.ts b/packages/g6/src/elements/edges/polyline.ts index 3f05c987a73..38f2e1e73f3 100644 --- a/packages/g6/src/elements/edges/polyline.ts +++ b/packages/g6/src/elements/edges/polyline.ts @@ -1,12 +1,12 @@ import type { DisplayObjectConfig } from '@antv/g'; import type { PathArray } from '@antv/util'; -import { deepMix } from '@antv/util'; import type { LoopStyleProps, Padding, Point, Port } from '../../types'; import { getBBoxHeight, getBBoxWidth, getNodeBBox } from '../../utils/bbox'; import { getPolylineLoopPath, getPolylinePath } from '../../utils/edge'; import { findPorts, getConnectionPoint, getPortPosition } from '../../utils/element'; import { subStyleProps } from '../../utils/prefix'; import { orth } from '../../utils/router/orth'; +import { mergeOptions } from '../../utils/style'; import type { BaseEdgeStyleProps } from './base-edge'; import { BaseEdge } from './base-edge'; @@ -70,7 +70,7 @@ export class Polyline extends BaseEdge { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: Polyline.defaultStyleProps }, options)); + super(mergeOptions({ style: Polyline.defaultStyleProps }, options)); } protected getKeyPath(attributes: ParsedPolylineStyleProps): PathArray { diff --git a/packages/g6/src/elements/edges/quadratic.ts b/packages/g6/src/elements/edges/quadratic.ts index 4a123d87822..dcd48f5d74d 100644 --- a/packages/g6/src/elements/edges/quadratic.ts +++ b/packages/g6/src/elements/edges/quadratic.ts @@ -1,8 +1,8 @@ import type { DisplayObjectConfig } from '@antv/g'; import type { PathArray } from '@antv/util'; -import { deepMix } from '@antv/util'; import type { Point } from '../../types'; import { getCurveControlPoint, getQuadraticPath } from '../../utils/edge'; +import { mergeOptions } from '../../utils/style'; import type { BaseEdgeStyleProps } from './base-edge'; import { BaseEdge } from './base-edge'; @@ -48,7 +48,7 @@ export class Quadratic extends BaseEdge { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: Quadratic.defaultStyleProps }, options)); + super(mergeOptions({ style: Quadratic.defaultStyleProps }, options)); } protected getKeyPath(attributes: ParsedQuadraticStyleProps): PathArray { diff --git a/packages/g6/src/elements/nodes/base-node.ts b/packages/g6/src/elements/nodes/base-node.ts index b6e88a7be15..601be3b472c 100644 --- a/packages/g6/src/elements/nodes/base-node.ts +++ b/packages/g6/src/elements/nodes/base-node.ts @@ -1,6 +1,6 @@ import type { BaseStyleProps, DisplayObject, DisplayObjectConfig, Group } from '@antv/g'; import { Circle as GCircle } from '@antv/g'; -import { deepMix, isEmpty } from '@antv/util'; +import { isEmpty } from '@antv/util'; import type { CategoricalPalette } from '../../palettes/types'; import type { NodeData } from '../../spec'; import type { @@ -22,6 +22,7 @@ import { getRectIntersectPoint } from '../../utils/point'; import { getXYByPlacement } from '../../utils/position'; import { omitStyleProps, subObject, subStyleProps } from '../../utils/prefix'; import { parseSize } from '../../utils/size'; +import { mergeOptions } from '../../utils/style'; import { getWordWrapWidthByBox } from '../../utils/text'; import { replaceTranslateInTransform } from '../../utils/transform'; import { BaseElement } from '../base-element'; @@ -218,7 +219,7 @@ export abstract class BaseNode) { - super(deepMix({}, { style: BaseNode.defaultStyleProps }, options)); + super(mergeOptions({ style: BaseNode.defaultStyleProps }, options)); } protected getSize(attributes = this.attributes) { diff --git a/packages/g6/src/elements/nodes/circle.ts b/packages/g6/src/elements/nodes/circle.ts index 04f5b088e1b..ed712f2a487 100644 --- a/packages/g6/src/elements/nodes/circle.ts +++ b/packages/g6/src/elements/nodes/circle.ts @@ -1,9 +1,9 @@ import type { DisplayObjectConfig, CircleStyleProps as GCircleStyleProps, Group } from '@antv/g'; import { Circle as GCircle } from '@antv/g'; -import { deepMix } from '@antv/util'; import { ICON_SIZE_RATIO } from '../../constants/element'; import type { Point } from '../../types'; import { getEllipseIntersectPoint } from '../../utils/point'; +import { mergeOptions } from '../../utils/style'; import type { IconStyleProps } from '../shapes'; import type { BaseNodeStyleProps } from './base-node'; import { BaseNode } from './base-node'; @@ -26,7 +26,7 @@ export class Circle extends BaseNode { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: Circle.defaultStyleProps }, options)); + super(mergeOptions({ style: Circle.defaultStyleProps }, options)); } protected drawKeyShape(attributes: Required, container: Group) { diff --git a/packages/g6/src/elements/nodes/donut.ts b/packages/g6/src/elements/nodes/donut.ts index ddc056eb99a..436a9b5328d 100644 --- a/packages/g6/src/elements/nodes/donut.ts +++ b/packages/g6/src/elements/nodes/donut.ts @@ -1,5 +1,5 @@ import { Path } from '@antv/g'; -import { deepMix, isNumber, isString } from '@antv/util'; +import { isNumber, isString } from '@antv/util'; import { getPaletteColors } from '../../utils/palette'; import { subStyleProps } from '../../utils/prefix'; import { parseSize } from '../../utils/size'; @@ -8,6 +8,7 @@ import { Circle } from './circle'; import type { BaseStyleProps, DisplayObjectConfig, Group } from '@antv/g'; import type { CategoricalPalette } from '../../palettes/types'; import type { DonutRound, Prefix } from '../../types'; +import { mergeOptions } from '../../utils/style'; import type { CircleStyleProps } from './circle'; /** @@ -51,7 +52,7 @@ export class Donut extends Circle { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: Donut.defaultStyleProps }, options)); + super(mergeOptions({ style: Donut.defaultStyleProps }, options)); } private parseOuterR() { diff --git a/packages/g6/src/elements/nodes/ellipse.ts b/packages/g6/src/elements/nodes/ellipse.ts index 649b483a63e..b0ce241806a 100644 --- a/packages/g6/src/elements/nodes/ellipse.ts +++ b/packages/g6/src/elements/nodes/ellipse.ts @@ -1,9 +1,9 @@ import type { DisplayObjectConfig, EllipseStyleProps as GEllipseStyleProps, Group } from '@antv/g'; import { Ellipse as GEllipse } from '@antv/g'; -import { deepMix } from '@antv/util'; import { ICON_SIZE_RATIO } from '../../constants/element'; import type { Point } from '../../types'; import { getEllipseIntersectPoint } from '../../utils/point'; +import { mergeOptions } from '../../utils/style'; import type { IconStyleProps } from '../shapes'; import type { BaseNodeStyleProps } from './base-node'; import { BaseNode } from './base-node'; @@ -26,7 +26,7 @@ export class Ellipse extends BaseNode { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: Ellipse.defaultStyleProps }, options)); + super(mergeOptions({ style: Ellipse.defaultStyleProps }, options)); } protected drawKeyShape(attributes: Required, container: Group) { diff --git a/packages/g6/src/elements/nodes/image.ts b/packages/g6/src/elements/nodes/image.ts index 115ce5aaa2e..1bca3999158 100644 --- a/packages/g6/src/elements/nodes/image.ts +++ b/packages/g6/src/elements/nodes/image.ts @@ -1,8 +1,8 @@ import type { DisplayObjectConfig, RectStyleProps as GRectStyleProps, Group } from '@antv/g'; import { Image as GImage, ImageStyleProps as GImageStyleProps, Rect as GRect } from '@antv/g'; -import { deepMix } from '@antv/util'; import { ICON_SIZE_RATIO } from '../../constants/element'; import { subStyleProps } from '../../utils/prefix'; +import { mergeOptions } from '../../utils/style'; import { add } from '../../utils/vector'; import type { IconStyleProps } from '../shapes'; import type { BaseNodeStyleProps } from './base-node'; @@ -39,7 +39,7 @@ export class Image extends BaseNode { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: Image.defaultStyleProps }, options)); + super(mergeOptions({ style: Image.defaultStyleProps }, options)); } protected getKeyStyle(attributes: Required): GImageStyleProps { diff --git a/packages/g6/src/elements/nodes/rect.ts b/packages/g6/src/elements/nodes/rect.ts index ce1c0376f75..ce7bda61b95 100644 --- a/packages/g6/src/elements/nodes/rect.ts +++ b/packages/g6/src/elements/nodes/rect.ts @@ -1,7 +1,7 @@ import type { DisplayObjectConfig, RectStyleProps as GRectStyleProps, Group } from '@antv/g'; import { Rect as GRect } from '@antv/g'; -import { deepMix } from '@antv/util'; import { ICON_SIZE_RATIO } from '../../constants/element'; +import { mergeOptions } from '../../utils/style'; import type { IconStyleProps } from '../shapes'; import type { BaseNodeStyleProps } from './base-node'; import { BaseNode } from './base-node'; @@ -25,7 +25,7 @@ export class Rect extends BaseNode { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: Rect.defaultStyleProps }, options)); + super(mergeOptions({ style: Rect.defaultStyleProps }, options)); } protected getKeyStyle(attributes: ParsedRectStyleProps): GRectStyleProps { diff --git a/packages/g6/src/elements/nodes/triangle.ts b/packages/g6/src/elements/nodes/triangle.ts index 4d10ba32bf9..93b2bd40fc8 100644 --- a/packages/g6/src/elements/nodes/triangle.ts +++ b/packages/g6/src/elements/nodes/triangle.ts @@ -1,10 +1,11 @@ import type { DisplayObjectConfig } from '@antv/g'; -import { deepMix, isEmpty } from '@antv/util'; +import { isEmpty } from '@antv/util'; import { ICON_SIZE_RATIO } from '../../constants/element'; import type { NodePortStyleProps, Point, TriangleDirection, TrianglePortPlacement } from '../../types'; import { getIncircleRadius, getTriangleCenter } from '../../utils/bbox'; import { getPortXYByPlacement, getTrianglePoints, getTrianglePorts } from '../../utils/element'; import { subStyleProps } from '../../utils/prefix'; +import { mergeOptions } from '../../utils/style'; import type { PolygonStyleProps } from '../shapes'; import { IconStyleProps } from '../shapes'; import { Polygon } from '../shapes/polygon'; @@ -36,7 +37,7 @@ export class Triangle extends Polygon { }; constructor(options: DisplayObjectConfig) { - super(deepMix({}, { style: Triangle.defaultStyleProps }, options)); + super(mergeOptions({ style: Triangle.defaultStyleProps }, options)); } protected getPoints(attributes: Required): Point[] { diff --git a/packages/g6/src/elements/shapes/badge.ts b/packages/g6/src/elements/shapes/badge.ts index 5f22f2a6d93..a4271ad2180 100644 --- a/packages/g6/src/elements/shapes/badge.ts +++ b/packages/g6/src/elements/shapes/badge.ts @@ -1,5 +1,5 @@ import type { DisplayObjectConfig, Group } from '@antv/g'; -import { deepMix } from '@antv/util'; +import { mergeOptions } from '../../utils/style'; import { BaseShape } from './base-shape'; import type { LabelStyleProps } from './label'; import { Label } from './label'; @@ -18,7 +18,7 @@ export class Badge extends BaseShape { }; constructor(options: BadgeOptions) { - super(deepMix({}, { style: Badge.defaultStyleProps }, options)); + super(mergeOptions({ style: Badge.defaultStyleProps }, options)); } protected getBadgeStyle(attributes: ParsedBadgeStyleProps) { diff --git a/packages/g6/src/elements/shapes/contour.ts b/packages/g6/src/elements/shapes/contour.ts index ab9e585cf21..f90150449c4 100644 --- a/packages/g6/src/elements/shapes/contour.ts +++ b/packages/g6/src/elements/shapes/contour.ts @@ -1,9 +1,9 @@ import type { DisplayObjectConfig, Group, PathStyleProps } from '@antv/g'; import { Path } from '@antv/g'; -import { deepMix } from '@antv/util'; import type { CardinalPlacement, Prefix } from '../../types'; import { getPolygonTextStyleByPlacement } from '../../utils/polygon'; import { subStyleProps } from '../../utils/prefix'; +import { mergeOptions } from '../../utils/style'; import { getWordWrapWidthByBox } from '../../utils/text'; import type { LabelStyleProps } from '../shapes'; import { BaseShape } from './base-shape'; @@ -76,7 +76,7 @@ export class Contour extends BaseShape { }; constructor(options: ContourOptions) { - super(deepMix({}, { style: Contour.defaultStyleProps }, options)); + super(mergeOptions({ style: Contour.defaultStyleProps }, options)); } protected getLabelStyle(attributes: ParsedContourStyleProps): LabelStyleProps | false { diff --git a/packages/g6/src/elements/shapes/label.ts b/packages/g6/src/elements/shapes/label.ts index e6ac6cea661..b72fa229479 100644 --- a/packages/g6/src/elements/shapes/label.ts +++ b/packages/g6/src/elements/shapes/label.ts @@ -1,9 +1,9 @@ import { DisplayObjectConfig, Group, Rect, RectStyleProps, Text, TextStyleProps } from '@antv/g'; -import { deepMix } from '@antv/util'; import type { Padding } from '../../types/padding'; import type { Prefix } from '../../types/prefix'; import { parsePadding } from '../../utils/padding'; import { omitStyleProps, startsWith, subStyleProps } from '../../utils/prefix'; +import { mergeOptions } from '../../utils/style'; import { BaseShape } from './base-shape'; export interface LabelStyleProps extends TextStyleProps, Prefix<'background', RectStyleProps> { @@ -39,7 +39,7 @@ export class Label extends BaseShape { }; constructor(options: LabelOptions) { - super(deepMix({}, { style: Label.defaultStyleProps }, options)); + super(mergeOptions({ style: Label.defaultStyleProps }, options)); } protected isTextStyle(key: string) { diff --git a/packages/g6/src/runtime/data.ts b/packages/g6/src/runtime/data.ts index c09780fd345..1f3a199670c 100644 --- a/packages/g6/src/runtime/data.ts +++ b/packages/g6/src/runtime/data.ts @@ -143,6 +143,10 @@ export class DataController { }, [] as NodeData[]); } + public getEdgeDatum(id: ID) { + return toG6Data(this.model.getEdge(id)); + } + public getEdgeData(ids?: ID[]) { return this.model.getAllEdges().reduce((acc, edge) => { const data = toG6Data(edge); @@ -224,9 +228,20 @@ export class DataController { */ public getElementDataById(id: ID): ElementDatum { const type = this.getElementType(id); - if (type === 'node') return this.getNodeData([id])[0]; - else if (type === 'edge') return this.getEdgeData([id])[0]; - return this.getComboData([id])[0]; + if (type === 'edge') return this.getEdgeDatum(id); + return this.getNodeLikeDatum(id); + } + + /** + * 获取节点的数据 + * + * Get node data + * @param id - 节点 ID | node ID + * @returns 节点数据 | node data + */ + public getNodeLikeDatum(id: ID) { + const data = this.model.getNode(id); + return toG6Data(data); } /** @@ -496,7 +511,7 @@ export class DataController { */ public setParent(id: ID, parent: ID | undefined, hierarchyKey: HierarchyKey, update: boolean = true) { if (id === parent) return; - const originalParentId = parentIdOf(this.getNodeLikeData([id])[0]); + const originalParentId = parentIdOf(this.getNodeLikeDatum(id)); // Sync data if (originalParentId !== parent && hierarchyKey === COMBO_KEY) { @@ -681,7 +696,7 @@ export class DataController { */ protected removeNodeLikeHierarchy(id: ID) { if (this.model.hasTreeStructure(COMBO_KEY)) { - const grandParent = parentIdOf(this.getNodeLikeData([id])[0]); + const grandParent = parentIdOf(this.getNodeLikeDatum(id)); // 从父节点的 children 列表中移除 // remove from its parent's children list diff --git a/packages/g6/src/runtime/element.ts b/packages/g6/src/runtime/element.ts index a28caee60b1..fd8a031a3d1 100644 --- a/packages/g6/src/runtime/element.ts +++ b/packages/g6/src/runtime/element.ts @@ -141,11 +141,13 @@ export class ElementController { private computeElementsDefaultStyle(ids?: ID[]) { this.forEachElementData((elementType, elementData) => { - elementData - .filter((datum) => ids === undefined || ids.includes(idOf(datum))) - .forEach((datum) => { + const length = elementData.length; + for (let i = 0; i < length; i++) { + const datum = elementData[i]; + if (ids === undefined || ids.includes(idOf(datum))) { this.computeElementDefaultStyle(elementType, { datum }); - }); + } + } }); } @@ -195,12 +197,14 @@ export class ElementController { */ private computeElementsStatesStyle(ids?: ID[]) { this.forEachElementData((elementType, elementData) => { - elementData - .filter((datum) => ids === undefined || ids.includes(idOf(datum))) - .forEach((datum) => { + const length = elementData.length; + for (let i = 0; i < length; i++) { + const datum = elementData[i]; + if (ids === undefined || ids.includes(idOf(datum))) { const states = this.getElementState(idOf(datum)); this.computeElementStatesStyle(elementType, states, { datum }); - }); + } + } }); } diff --git a/packages/g6/src/utils/id.ts b/packages/g6/src/utils/id.ts index e437fc81573..66a2712aef0 100644 --- a/packages/g6/src/utils/id.ts +++ b/packages/g6/src/utils/id.ts @@ -1,7 +1,5 @@ -import { isNumber, isString } from '@antv/util'; import type { ComboData, EdgeData, GraphData, NodeData } from '../spec'; import type { DataID, ID } from '../types'; -import { isEdgeData } from './is'; /** * 获取节点/边/Combo 的 ID @@ -11,8 +9,8 @@ import { isEdgeData } from './is'; * @returns 节点/边/Combo 的 ID | ID of node/edge/combo */ export function idOf(data: Partial): ID { - if (isString(data.id) || isNumber(data.id)) return data.id; - if (isEdgeData(data)) return `${data.source}-${data.target}`; + if (data.id !== undefined) return data.id; + if (data.source !== undefined && data.target !== undefined) return `${data.source}-${data.target}`; throw new Error('The data does not have available id.'); } diff --git a/packages/g6/src/utils/style.ts b/packages/g6/src/utils/style.ts index fd034d8d8dd..e5d6a8cd287 100644 --- a/packages/g6/src/utils/style.ts +++ b/packages/g6/src/utils/style.ts @@ -1,3 +1,4 @@ +import type { DisplayObjectConfig } from '@antv/g'; import { isFunction } from '@antv/util'; import type { CallableObject, ElementDatum, StyleIterationContext } from '../types'; import { inferDefaultValue } from './animation'; @@ -36,3 +37,20 @@ export function computeElementCallbackStyle( export function zIndexOf(datum: ElementDatum) { return datum.style?.zIndex ?? (inferDefaultValue('zIndex') as number) ?? 0; } + +/** + * 合并图形配置项 + * + * Merge graphic configuration + * @param options - 图形配置项数组 | graphic configuration array + * @returns 合并后的配置项 | merged configuration + */ +export function mergeOptions(...options: DisplayObjectConfig[]): DisplayObjectConfig { + const option = { style: {} }; + for (const opt of options) { + const { style, ..._ } = opt; + Object.assign(option.style, style); + Object.assign(option, _); + } + return option; +}