From a0c131b0a7a203315f079e44bab333e92ee8df07 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 16 Mar 2024 00:39:25 +0800 Subject: [PATCH] feat: adapt combo, add drag-element / collapse-expand behaviors (#5543) * refactor(runtime): merge into getChildrenData, getComboData, add get getAncestorsData * refactor(runtime): move translate logic from graph to data controller * feat(utils): add positionOf util * refactor(runtime): adjust the order of drawing combos * refactor(elements): sync combo position to model, adjust combo size calc * refactor(utils): dfs provide depth info * refactor(elements): combo sync position and zIndex * feat(utils): add zIndexOf util * refactor(runtime): refactor data/element controller to fit combo update * test: assign graph into window.graph * refactor(elements): combo use childrenData to get marker text * refactor(elements): filter zIndex from graphicStyle * feat(utils): add getSubgraphRelatedEdges util * refactor(animation): add combo-collapse-expand animation * refactor(runtime): add combo collapse and expand flow * fix: fix issue in data controller and base-combo * test: update test case and snapshots * feat(behaviors): support click collapse-expand, drag-combo * refactor: merge drag node and drag combo into drag element * fix(behaviors): fix issue drag element between combo wont update * test(behaviors): add drag-element test case and snapshots * test: fix snapshot * test: update test case and snapshots * fix: fix format and types * chore: adjust drag-node to drag element --- ...-drag-node.ts => behavior-drag-element.ts} | 4 +- .../demo/case/combo-expand-collapse.ts | 81 ++++ packages/g6/__tests__/demo/case/combo.ts | 7 +- .../g6/__tests__/demo/case/edge-polyline.ts | 2 +- .../demo/case/element-position-combo.ts | 39 ++ .../g6/__tests__/demo/case/element-z-index.ts | 45 ++ packages/g6/__tests__/demo/case/index.ts | 5 +- ...layout-circular-configuration-translate.ts | 2 +- .../demo/case/layout-combo-combined.ts | 2 +- .../demo/case/layout-compact-box-basic.ts | 2 +- .../case/layout-compact-box-left-align.ts | 2 +- .../case/layout-compact-box-top-to-bottom.ts | 2 +- .../__tests__/demo/case/layout-concentric.ts | 2 +- .../demo/case/layout-dagre-flow-combo.ts | 2 +- .../__tests__/demo/case/layout-dagre-flow.ts | 2 +- .../demo/case/layout-dendrogram-basic.ts | 2 +- .../demo/case/layout-dendrogram-tb.ts | 2 +- .../g6/__tests__/demo/case/layout-force.ts | 2 +- .../demo/case/layout-fruchterman-basic.ts | 2 +- .../demo/case/layout-fruchterman-cluster.ts | 2 +- .../demo/case/layout-fruchterman-fix.ts | 2 +- .../g6/__tests__/demo/case/layout-grid.ts | 2 +- packages/g6/__tests__/demo/case/layout-mds.ts | 2 +- .../demo/case/layout-radial-basic.ts | 2 +- .../layout-radial-configuration-translate.ts | 2 +- .../layout-radial-prevent-overlap-unstrict.ts | 2 +- .../case/layout-radial-prevent-overlap.ts | 2 +- .../__tests__/demo/case/layout-radial-sort.ts | 2 +- .../demo/static/controller-element-z-index.ts | 2 - .../demo/static/element-label-background.ts | 2 +- .../demo/static/element-label-oversized.ts | 2 +- packages/g6/__tests__/main.ts | 2 + .../collapse-combo-2.svg | 64 +++ .../behavior-collapse-expand/default.svg | 161 +++++++ .../expand-combo-1.svg | 234 ++++++++++ .../behavior-drag-element-combo/default.svg | 234 ++++++++++ .../drag-combo-1-after-drop-move.svg | 234 ++++++++++ .../drag-combo-1-after-drop-out.svg | 238 ++++++++++ .../drag-combo-1-before-drop-move.svg | 238 ++++++++++ .../drag-combo-1-before-drop-out.svg | 234 ++++++++++ .../drag-combo-2-after-drop-into.svg | 234 ++++++++++ .../drag-combo-2-before-drop-into.svg | 238 ++++++++++ .../drag-node-1-after-drop-into.svg | 234 ++++++++++ .../drag-node-1-after-drop-move.svg | 238 ++++++++++ .../drag-node-1-after-drop-out.svg | 234 ++++++++++ .../drag-node-1-before-drop-into.svg | 234 ++++++++++ .../drag-node-1-before-drop-move.svg | 234 ++++++++++ .../drag-node-1-before-drop-out.svg | 234 ++++++++++ .../drag-node-2-after-drop-out.svg | 234 ++++++++++ .../drag-node-2-before-drop-out.svg | 234 ++++++++++ .../after-drag.svg | 16 +- .../default.svg | 16 +- .../drag-combo-shadow-after-drag.svg | 333 ++++++++++++++ .../drag-combo-shadow.svg | 333 ++++++++++++++ .../behavior-drag-element/drag-combo.svg | 333 ++++++++++++++ .../hideEdges-both.svg | 16 +- .../hideEdges-in.svg | 20 +- .../hideEdges-out.svg | 20 +- .../shadow-after-drag.svg | 16 +- .../shadow.svg | 16 +- .../elements/combo/circle-collapse-bottom.svg | 201 +-------- .../combo/circle-collapse-bottomLeft.svg | 201 +-------- .../combo/circle-collapse-bottomRight.svg | 201 +-------- .../elements/combo/circle-collapse-center.svg | 205 +-------- .../elements/combo/circle-collapse-left.svg | 205 +-------- .../elements/combo/circle-collapse-right.svg | 205 +-------- .../elements/combo/circle-collapse-top.svg | 201 +-------- .../combo/circle-collapse-topLeft.svg | 201 +-------- .../combo/circle-collapse-topRight.svg | 201 +-------- .../combo/circle-marker-childCount.svg | 201 +-------- .../elements/combo/circle-marker-custom.svg | 201 +-------- .../combo/circle-marker-descendantCount.svg | 201 +-------- .../combo/circle-marker-nodeCount.svg | 201 +-------- .../elements/combo/rect-collapse-bottom.svg | 120 +----- .../combo/rect-collapse-bottomLeft.svg | 120 +----- .../combo/rect-collapse-bottomRight.svg | 120 +----- .../elements/combo/rect-collapse-center.svg | 120 +----- .../elements/combo/rect-collapse-left.svg | 120 +----- .../elements/combo/rect-collapse-right.svg | 120 +----- .../elements/combo/rect-collapse-top.svg | 116 +---- .../elements/combo/rect-collapse-topLeft.svg | 116 +---- .../elements/combo/rect-collapse-topRight.svg | 116 +---- .../elements/position-combo/default.svg | 239 +++++++++++ .../snapshots/elements/z-index/default.svg | 328 ++++++++++++++ .../elements/z-index/drag-combo-1.svg | 328 ++++++++++++++ .../elements/z-index/drag-combo-2.svg | 328 ++++++++++++++ .../elements/z-index/drag-combo-3.svg | 328 ++++++++++++++ .../elements/z-index/drag-overlap-combo-3.svg | 328 ++++++++++++++ .../z-index/drag-overlap-combo-4(1).svg | 328 ++++++++++++++ .../z-index/drag-overlap-combo-4(2).svg | 328 ++++++++++++++ .../z-index/drag-overlap-combo-4(3).svg | 328 ++++++++++++++ .../elements/z-index/drag-overlap-node-1.svg | 328 ++++++++++++++ .../elements/z-index/drag-overlap-node-2.svg | 328 ++++++++++++++ .../elements/z-index/drag-overlap-node-3.svg | 328 ++++++++++++++ .../layouts/dagre-flow/flow-combo.svg | 58 +-- .../behavior-collapse-expand.spec.ts | 29 ++ .../behavior-drag-element-combo.spec.ts | 73 ++++ ....spec.ts => behavior-drag-element.spec.ts} | 39 +- .../g6/__tests__/unit/elements/combo.spec.ts | 107 +++-- .../unit/elements/position-combo.spec.ts | 15 + .../__tests__/unit/elements/z-index.spec.ts | 69 +++ .../unit/layouts/radial-layout.spec.ts | 2 +- .../g6/__tests__/unit/runtime/data.spec.ts | 83 ++-- .../g6/__tests__/unit/runtime/element.spec.ts | 53 +-- .../unit/runtime/element/z-index.spec.ts | 6 - .../unit/runtime/graph/graph.spec.ts | 4 +- packages/g6/__tests__/unit/spec/index.spec.ts | 2 +- .../g6/__tests__/unit/utils/combo.spec.ts | 23 +- packages/g6/__tests__/unit/utils/edge.spec.ts | 62 +++ .../g6/__tests__/unit/utils/extension.spec.ts | 4 +- .../g6/__tests__/unit/utils/position.spec.ts | 9 +- .../g6/__tests__/unit/utils/style.spec.ts | 9 +- .../g6/__tests__/unit/utils/traverse.spec.ts | 30 ++ packages/g6/src/animations/index.ts | 2 + packages/g6/src/behaviors/collapse-expand.ts | 91 ++++ .../{drag-node.ts => drag-element.ts} | 115 ++++- packages/g6/src/behaviors/index.ts | 6 +- packages/g6/src/elements/combos/base-combo.ts | 94 ++-- packages/g6/src/elements/combos/rect.ts | 3 +- packages/g6/src/elements/index.ts | 6 +- packages/g6/src/elements/nodes/base-node.ts | 2 +- packages/g6/src/elements/shapes/base-shape.ts | 4 +- packages/g6/src/registry/build-in.ts | 8 +- packages/g6/src/runtime/behavior.ts | 6 +- packages/g6/src/runtime/data.ts | 405 ++++++++++++------ packages/g6/src/runtime/element.ts | 210 ++++++--- packages/g6/src/runtime/graph.ts | 154 ++++--- packages/g6/src/spec/element/animation.ts | 2 +- packages/g6/src/themes/base.ts | 3 +- packages/g6/src/types/element.ts | 19 +- packages/g6/src/utils/combo.ts | 47 +- packages/g6/src/utils/edge.ts | 27 ++ packages/g6/src/utils/element.ts | 16 +- packages/g6/src/utils/event/index.ts | 5 +- packages/g6/src/utils/id.ts | 3 +- packages/g6/src/utils/position.ts | 14 +- packages/g6/src/utils/style.ts | 12 + packages/g6/src/utils/traverse.ts | 16 +- .../item/defaultEdges/demo/polyline.ts | 2 +- .../item/defaultEdges/demo/polylineOrth.ts | 2 +- .../defaultEdges/demo/polylineOrthHasCPs.ts | 2 +- .../examples/item/label/demo/copyLabel.ts | 2 +- .../site/examples/item/label/demo/labelLen.ts | 2 +- .../examples/item/label/demo/labelLen1.ts | 2 +- .../item/labelBg/demo/label-background.ts | 2 +- .../site/examples/net/circular/demo/basic.ts | 2 +- .../circular/demo/configurationTranslate.ts | 2 +- .../site/examples/net/circular/demo/degree.ts | 2 +- .../examples/net/circular/demo/division.ts | 2 +- .../site/examples/net/circular/demo/spiral.ts | 2 +- .../net/comboLayout/demo/comboCombined.ts | 4 +- .../net/compactBox/demo/basicCompactBox.ts | 2 +- .../compactBox/demo/compactBoxLeftAlign.ts | 2 +- .../compactBox/demo/topToBottomCompactBox.ts | 2 +- .../concentricLayout/demo/basicConcentric.ts | 2 +- .../site/examples/net/dagreFlow/demo/dagre.ts | 2 +- .../examples/net/dagreFlow/demo/dagreCombo.ts | 2 +- .../net/dendrogram/demo/basicDendrogram.ts | 2 +- .../net/dendrogram/demo/tbDendrogram.ts | 2 +- .../demo/basicFruchterman.ts | 2 +- .../demo/fruchtermanCluster.ts | 2 +- .../fruchtermanLayout/demo/fruchtermanFix.ts | 2 +- .../demo/fruchtermanWebWorker.ts | 2 +- .../net/gpuLayout/demo/basicFruchterman.ts | 2 +- .../gpuLayout/demo/fruchtermanComplexData.ts | 2 +- .../site/examples/net/gridLayout/demo/grid.ts | 2 +- .../examples/net/mdsLayout/demo/basicMDS.ts | 2 +- .../examples/net/radialLayout/demo/basic.ts | 2 +- .../demo/configurationTranslate.ts | 2 +- .../net/radialLayout/demo/preventOverlap.ts | 2 +- .../demo/preventOverlapUnstrict.ts | 2 +- .../examples/net/radialLayout/demo/sort.ts | 2 +- .../examples/performance/perf/demo/eva.ts | 4 +- .../performance/perf/demo/evaWebGL.ts | 4 +- .../performance/perf/demo/netscience.ts | 4 +- .../performance/perf/demo/netscienceWebGL.ts | 4 +- .../tool/contextMenu/demo/contextMenu.ts | 7 +- .../site/examples/tool/grid/demo/default.ts | 4 +- .../site/examples/tool/legend/demo/legend.ts | 2 +- .../tool/legend/demo/legendCustomMarker.ts | 2 +- .../examples/tool/legend/demo/legendSVG.ts | 2 +- .../examples/tool/minimap/demo/minimap-api.ts | 2 +- .../examples/tool/minimap/demo/minimap.ts | 2 +- .../examples/tool/overview/demo/default.ts | 2 +- .../examples/tool/snapline/demo/snapline.ts | 4 +- .../tool/timebar/demo/timebar-chart.ts | 4 +- .../tool/timebar/demo/timebar-time.ts | 4 +- .../tool/toolbar/demo/self-toolbar.ts | 2 +- .../examples/tool/toolbar/demo/toolbar.ts | 2 +- .../tool/tooltip/demo/tooltipClick.ts | 2 +- .../tool/tooltip/demo/tooltipPlugin.ts | 2 +- .../tool/watermarker/demo/imgWaterMarker.ts | 4 +- .../tool/watermarker/demo/textWaterMarker.ts | 4 +- 193 files changed, 10776 insertions(+), 4185 deletions(-) rename packages/g6/__tests__/demo/case/{behavior-drag-node.ts => behavior-drag-element.ts} (92%) create mode 100644 packages/g6/__tests__/demo/case/combo-expand-collapse.ts create mode 100644 packages/g6/__tests__/demo/case/element-position-combo.ts create mode 100644 packages/g6/__tests__/demo/case/element-z-index.ts create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/collapse-combo-2.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/default.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/expand-combo-1.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/default.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-after-drop-move.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-after-drop-out.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-before-drop-move.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-before-drop-out.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-2-after-drop-into.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-2-before-drop-into.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-into.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-move.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-out.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-into.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-move.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-out.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-2-after-drop-out.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-2-before-drop-out.svg rename packages/g6/__tests__/snapshots/behaviors/{behavior-drag-node => behavior-drag-element}/after-drag.svg (97%) rename packages/g6/__tests__/snapshots/behaviors/{behavior-drag-node => behavior-drag-element}/default.svg (97%) create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/drag-combo-shadow-after-drag.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/drag-combo-shadow.svg create mode 100644 packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/drag-combo.svg rename packages/g6/__tests__/snapshots/behaviors/{behavior-drag-node => behavior-drag-element}/hideEdges-both.svg (97%) rename packages/g6/__tests__/snapshots/behaviors/{behavior-drag-node => behavior-drag-element}/hideEdges-in.svg (97%) rename packages/g6/__tests__/snapshots/behaviors/{behavior-drag-node => behavior-drag-element}/hideEdges-out.svg (97%) rename packages/g6/__tests__/snapshots/behaviors/{behavior-drag-node => behavior-drag-element}/shadow-after-drag.svg (97%) rename packages/g6/__tests__/snapshots/behaviors/{behavior-drag-node => behavior-drag-element}/shadow.svg (97%) create mode 100644 packages/g6/__tests__/snapshots/elements/position-combo/default.svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/default.svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/drag-combo-1.svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/drag-combo-2.svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/drag-combo-3.svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-3.svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(1).svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(2).svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(3).svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-1.svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-2.svg create mode 100644 packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-3.svg create mode 100644 packages/g6/__tests__/unit/behaviors/behavior-collapse-expand.spec.ts create mode 100644 packages/g6/__tests__/unit/behaviors/behavior-drag-element-combo.spec.ts rename packages/g6/__tests__/unit/behaviors/{behavior-drag-node.spec.ts => behavior-drag-element.spec.ts} (53%) create mode 100644 packages/g6/__tests__/unit/elements/position-combo.spec.ts create mode 100644 packages/g6/__tests__/unit/elements/z-index.spec.ts create mode 100644 packages/g6/src/behaviors/collapse-expand.ts rename packages/g6/src/behaviors/{drag-node.ts => drag-element.ts} (59%) diff --git a/packages/g6/__tests__/demo/case/behavior-drag-node.ts b/packages/g6/__tests__/demo/case/behavior-drag-element.ts similarity index 92% rename from packages/g6/__tests__/demo/case/behavior-drag-node.ts rename to packages/g6/__tests__/demo/case/behavior-drag-element.ts index d27f025901e..67ed9751ffb 100644 --- a/packages/g6/__tests__/demo/case/behavior-drag-node.ts +++ b/packages/g6/__tests__/demo/case/behavior-drag-element.ts @@ -23,7 +23,7 @@ export const behaviorDragNode: STDTestCase = async (context) => { edge: { style: { endArrow: true }, }, - behaviors: [{ type: 'drag-node' }], + behaviors: [{ type: 'drag-element' }], }); await graph.render(); @@ -35,7 +35,7 @@ export const behaviorDragNode: STDTestCase = async (context) => { shadow: false, }; const handleChange = () => { - graph.setBehaviors([{ type: 'drag-node', ...config }]); + graph.setBehaviors([{ type: 'drag-element', ...config }]); }; return [ panel.add(config, 'enable').onChange(handleChange), diff --git a/packages/g6/__tests__/demo/case/combo-expand-collapse.ts b/packages/g6/__tests__/demo/case/combo-expand-collapse.ts new file mode 100644 index 00000000000..2a851e213b7 --- /dev/null +++ b/packages/g6/__tests__/demo/case/combo-expand-collapse.ts @@ -0,0 +1,81 @@ +import { Graph } from '@/src'; +import { isObject } from '@antv/util'; +import type { STDTestCase } from '../types'; + +export const comboExpandCollapse: STDTestCase = async (context) => { + const graph = new Graph({ + ...context, + data: { + nodes: [ + { id: 'node-1', style: { parentId: 'combo-2', x: 120, y: 100 } }, + { id: 'node-2', style: { parentId: 'combo-1', x: 300, y: 200 } }, + { id: 'node-3', style: { parentId: 'combo-1', x: 200, y: 300 } }, + ], + edges: [ + { id: 'edge-1', source: 'node-1', target: 'node-2' }, + { id: 'edge-2', source: 'node-2', target: 'node-3' }, + ], + combos: [ + { + id: 'combo-1', + style: { type: 'rect', parentId: 'combo-2', collapsed: true }, + }, + { id: 'combo-2' }, + ], + }, + node: { + style: { + labelText: (d) => d.id, + }, + }, + combo: { + style: { + labelText: (d) => d.id, + lineDash: 0, + collapsedLineDash: [5, 5], + }, + }, + behaviors: [{ type: 'drag-element' }, 'collapse-expand'], + }); + + await graph.render(); + + comboExpandCollapse.form = (panel) => { + const config = { + element: 'combo-1', + dropEffect: 'move', + collapse: () => graph.collapse(config.element), + expand: () => graph.expand(config.element), + }; + + return [ + panel + .add(config, 'element', { + 'combo-1': 'combo-1', + 'combo-2': 'combo-2', + 'combo-3': 'combo-3', + 'combo-4': 'combo-4', + }) + .name('Combo'), + panel.add(config, 'collapse').name('Collapse'), + panel.add(config, 'expand').name('Expand'), + panel.add(config, 'dropEffect', ['link', 'move', 'none']).onChange((value: string) => { + graph.setBehaviors((behaviors) => { + return behaviors.map((behavior) => { + if (isObject(behavior) && behavior.type === 'drag-element') { + return { + ...behavior, + dropEffect: value, + }; + } + return behavior; + }); + }); + }), + ]; + }; + + Object.assign(window, { graph }); + + return graph; +}; diff --git a/packages/g6/__tests__/demo/case/combo.ts b/packages/g6/__tests__/demo/case/combo.ts index 09bea3763bf..0edcfe6aafb 100644 --- a/packages/g6/__tests__/demo/case/combo.ts +++ b/packages/g6/__tests__/demo/case/combo.ts @@ -19,9 +19,6 @@ export const combo: STDTestCase = async (context) => { }, { id: 'combo-2', - style: { - zIndex: -10, // TODO: zIndex? - }, }, ], }; @@ -41,6 +38,7 @@ export const combo: STDTestCase = async (context) => { collapsedLineDash: [5, 5], }, }, + behaviors: ['drag-element'], }); await graph.render(); @@ -96,8 +94,7 @@ export const combo: STDTestCase = async (context) => { graph.render(); }, collapseCombo2: () => { - graph.updateComboData((data) => [ - ...data, + graph.updateComboData([ { id: 'combo-2', style: { diff --git a/packages/g6/__tests__/demo/case/edge-polyline.ts b/packages/g6/__tests__/demo/case/edge-polyline.ts index 8db44a881ff..379216dd216 100644 --- a/packages/g6/__tests__/demo/case/edge-polyline.ts +++ b/packages/g6/__tests__/demo/case/edge-polyline.ts @@ -18,7 +18,7 @@ export const edgePolyline: STDTestCase = async (context) => { type: 'polyline', }, }, - behaviors: [{ type: 'drag-node' }], + behaviors: [{ type: 'drag-element' }], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/element-position-combo.ts b/packages/g6/__tests__/demo/case/element-position-combo.ts new file mode 100644 index 00000000000..26f9aecb7a6 --- /dev/null +++ b/packages/g6/__tests__/demo/case/element-position-combo.ts @@ -0,0 +1,39 @@ +import { Graph } from '@/src'; +import type { STDTestCase } from '../types'; + +export const elementPositionCombo: STDTestCase = async (context) => { + const graph = new Graph({ + ...context, + data: { + nodes: [ + { id: 'node-1', style: { x: 100, y: 150, parentId: 'combo-1' } }, + { id: 'node-2', style: { x: 200, y: 150, parentId: 'combo-1' } }, + { id: 'node-3', style: { x: 400, y: 200, parentId: 'combo-2' } }, + { id: 'node-4', style: { x: 150, y: 300, parentId: 'combo-3' } }, + ], + combos: [ + { id: 'combo-1', style: { parentId: 'combo-2' } }, + { id: 'combo-2' }, + { id: 'combo-3', style: { parentId: 'combo-1' } }, + ], + }, + node: { + style: { + size: 20, + labelWordWrapWidth: 200, + labelText: (d) => d.id, + }, + }, + combo: { + style: { + labelText: (d) => d.id, + }, + }, + padding: 20, + autoFit: 'view', + }); + + await graph.render(); + + return graph; +}; diff --git a/packages/g6/__tests__/demo/case/element-z-index.ts b/packages/g6/__tests__/demo/case/element-z-index.ts new file mode 100644 index 00000000000..f45385322f9 --- /dev/null +++ b/packages/g6/__tests__/demo/case/element-z-index.ts @@ -0,0 +1,45 @@ +import { Graph } from '@/src'; +import type { STDTestCase } from '../types'; + +export const elementZIndex: STDTestCase = async (context) => { + const graph = new Graph({ + ...context, + data: { + nodes: [ + { id: 'node-1', style: { x: 50, y: 50 } }, + { id: 'node-2', style: { x: 200, y: 50 } }, + { id: 'node-3', style: { x: 125, y: 150 } }, + ], + edges: [ + { id: 'edge-1', source: 'node-1', target: 'node-2' }, + { id: 'edge-2', source: 'node-2', target: 'node-3' }, + { id: 'edge-3', source: 'node-3', target: 'node-1' }, + ], + combos: [ + { id: 'combo-1', style: { x: 50, y: 250 } }, + { id: 'combo-2', style: { x: 50, y: 250, parentId: 'combo-1' } }, + { id: 'combo-3', style: { x: 150, y: 250, parentId: 'combo-2' } }, + { id: 'combo-4', style: { x: 350, y: 250 } }, + ], + }, + node: { + style: { + size: 40, + labelText: (d) => d.id, + labelWordWrapWidth: 200, + color: (d, index) => ['red', 'green', 'blue'][index], + }, + }, + combo: { + style: { + labelText: (d) => d.id, + color: (d, index: number) => ['pink', 'cyan', 'purple', 'orange'][index], + }, + }, + behaviors: ['drag-element'], + }); + + await graph.render(); + + return graph; +}; diff --git a/packages/g6/__tests__/demo/case/index.ts b/packages/g6/__tests__/demo/case/index.ts index e152b94299b..b4edf0cb217 100644 --- a/packages/g6/__tests__/demo/case/index.ts +++ b/packages/g6/__tests__/demo/case/index.ts @@ -1,14 +1,17 @@ export * from './behavior-drag-canvas'; -export * from './behavior-drag-node'; +export * from './behavior-drag-element'; export * from './behavior-zoom-canvas'; export * from './combo'; +export * from './combo-expand-collapse'; export * from './common-graph'; export * from './edge-polyline'; export * from './element-change-type'; export * from './element-port'; export * from './element-position'; +export * from './element-position-combo'; export * from './element-state'; export * from './element-visibility'; +export * from './element-z-index'; export * from './graph-event'; export * from './layout-circular-basic'; export * from './layout-circular-configuration-translate'; diff --git a/packages/g6/__tests__/demo/case/layout-circular-configuration-translate.ts b/packages/g6/__tests__/demo/case/layout-circular-configuration-translate.ts index 5fea2abe963..1740703bc0e 100644 --- a/packages/g6/__tests__/demo/case/layout-circular-configuration-translate.ts +++ b/packages/g6/__tests__/demo/case/layout-circular-configuration-translate.ts @@ -16,7 +16,7 @@ export const layoutCircularConfigurationTranslate: STDTestCase = async (context) layout: { type: 'circular', }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-combo-combined.ts b/packages/g6/__tests__/demo/case/layout-combo-combined.ts index 88a68fc4b57..720b5de1155 100644 --- a/packages/g6/__tests__/demo/case/layout-combo-combined.ts +++ b/packages/g6/__tests__/demo/case/layout-combo-combined.ts @@ -22,7 +22,7 @@ export const layoutComboCombined: STDTestCase = async (context) => { return { stroke: color || '#99ADD1', lineWidth: size || 1 }; }, }, - behaviors: ['drag-combo', 'drag-node', 'drag-canvas', 'zoom-canvas'], + behaviors: ['drag-element', 'drag-canvas', 'zoom-canvas'], autoFit: 'view', }); diff --git a/packages/g6/__tests__/demo/case/layout-compact-box-basic.ts b/packages/g6/__tests__/demo/case/layout-compact-box-basic.ts index 0264ff25c0a..ea0fa670baf 100644 --- a/packages/g6/__tests__/demo/case/layout-compact-box-basic.ts +++ b/packages/g6/__tests__/demo/case/layout-compact-box-basic.ts @@ -7,7 +7,7 @@ export const layoutCompactBoxBasic: STDTestCase = async (context) => { ...context, autoFit: 'view', data: Utils.treeToGraphData(data), - behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'], node: { style: { labelText: (data) => data.id, diff --git a/packages/g6/__tests__/demo/case/layout-compact-box-left-align.ts b/packages/g6/__tests__/demo/case/layout-compact-box-left-align.ts index 89c89a04a47..80bfbef4a2b 100644 --- a/packages/g6/__tests__/demo/case/layout-compact-box-left-align.ts +++ b/packages/g6/__tests__/demo/case/layout-compact-box-left-align.ts @@ -8,7 +8,7 @@ export const layoutCompactBoxTopToBottom: STDTestCase = async (context) => { ...context, autoFit: 'view', data: Utils.treeToGraphData(data), - behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'], node: { style: { labelText: (data) => data.id, diff --git a/packages/g6/__tests__/demo/case/layout-compact-box-top-to-bottom.ts b/packages/g6/__tests__/demo/case/layout-compact-box-top-to-bottom.ts index 3cf2c46689c..fd387292c88 100644 --- a/packages/g6/__tests__/demo/case/layout-compact-box-top-to-bottom.ts +++ b/packages/g6/__tests__/demo/case/layout-compact-box-top-to-bottom.ts @@ -45,7 +45,7 @@ export const layoutCompactBoxLeftAlign: STDTestCase = async (context) => { return 20; }, }, - behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'], animation: false, }); diff --git a/packages/g6/__tests__/demo/case/layout-concentric.ts b/packages/g6/__tests__/demo/case/layout-concentric.ts index ef78653e781..87381cf7b37 100644 --- a/packages/g6/__tests__/demo/case/layout-concentric.ts +++ b/packages/g6/__tests__/demo/case/layout-concentric.ts @@ -12,7 +12,7 @@ export const layoutConcentric: STDTestCase = async (context) => { maxLevelDiff: 0.5, preventOverlap: true, }, - behaviors: ['zoom-canvas', 'drag-canvas', 'drag-node'], + behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element'], animation: false, }); diff --git a/packages/g6/__tests__/demo/case/layout-dagre-flow-combo.ts b/packages/g6/__tests__/demo/case/layout-dagre-flow-combo.ts index 70c01d76cca..d54f10eb012 100644 --- a/packages/g6/__tests__/demo/case/layout-dagre-flow-combo.ts +++ b/packages/g6/__tests__/demo/case/layout-dagre-flow-combo.ts @@ -39,7 +39,7 @@ export const layoutDagreFlowCombo: STDTestCase = async (context) => { ranksep: 50, nodesep: 5, }, - behaviors: ['drag-combo', 'drag-node', 'drag-canvas', 'zoom-canvas'], + behaviors: ['drag-element', 'drag-canvas', 'zoom-canvas'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-dagre-flow.ts b/packages/g6/__tests__/demo/case/layout-dagre-flow.ts index e26785b3661..1ff9c13b74f 100644 --- a/packages/g6/__tests__/demo/case/layout-dagre-flow.ts +++ b/packages/g6/__tests__/demo/case/layout-dagre-flow.ts @@ -31,7 +31,7 @@ export const layoutDagreFlow: STDTestCase = async (context) => { ranksep: 70, controlPoints: true, }, - behaviors: ['drag-combo', 'drag-node', 'drag-canvas', 'zoom-canvas'], + behaviors: ['drag-element', 'drag-canvas', 'zoom-canvas'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-dendrogram-basic.ts b/packages/g6/__tests__/demo/case/layout-dendrogram-basic.ts index b19a14df4fe..5bb59956072 100644 --- a/packages/g6/__tests__/demo/case/layout-dendrogram-basic.ts +++ b/packages/g6/__tests__/demo/case/layout-dendrogram-basic.ts @@ -25,7 +25,7 @@ export const layoutDendrogramBasic: STDTestCase = async (context) => { nodeSep: 36, rankSep: 250, }, - behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node', 'collapse-expand-tree'], + behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element', 'collapse-expand-tree'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-dendrogram-tb.ts b/packages/g6/__tests__/demo/case/layout-dendrogram-tb.ts index 61dcd121972..c8bdce5f9a1 100644 --- a/packages/g6/__tests__/demo/case/layout-dendrogram-tb.ts +++ b/packages/g6/__tests__/demo/case/layout-dendrogram-tb.ts @@ -32,7 +32,7 @@ export const layoutDendrogramTb: STDTestCase = async (context) => { nodeSep: 40, rankSep: 100, }, - behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node', 'collapse-expand-tree'], + behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element', 'collapse-expand-tree'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-force.ts b/packages/g6/__tests__/demo/case/layout-force.ts index 0221f68847a..3af7983ac82 100644 --- a/packages/g6/__tests__/demo/case/layout-force.ts +++ b/packages/g6/__tests__/demo/case/layout-force.ts @@ -8,7 +8,7 @@ export const layoutForce: STDTestCase = async (context) => { data, padding: 20, autoFit: 'view', - behaviors: ['zoom-canvas', 'drag-canvas', 'drag-node', 'click-select'], + behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element', 'click-select'], layout: { type: 'force', }, diff --git a/packages/g6/__tests__/demo/case/layout-fruchterman-basic.ts b/packages/g6/__tests__/demo/case/layout-fruchterman-basic.ts index 1a748ad9da6..9122c65e981 100644 --- a/packages/g6/__tests__/demo/case/layout-fruchterman-basic.ts +++ b/packages/g6/__tests__/demo/case/layout-fruchterman-basic.ts @@ -17,7 +17,7 @@ export const layoutFruchtermanBasic: STDTestCase = async (context) => { gravity: 5, speed: 5, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-fruchterman-cluster.ts b/packages/g6/__tests__/demo/case/layout-fruchterman-cluster.ts index ec05f7dcd33..50c02d20d76 100644 --- a/packages/g6/__tests__/demo/case/layout-fruchterman-cluster.ts +++ b/packages/g6/__tests__/demo/case/layout-fruchterman-cluster.ts @@ -22,7 +22,7 @@ export const layoutFruchtermanCluster: STDTestCase = async (context) => { clustering: true, nodeClusterBy: 'cluster', }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-fruchterman-fix.ts b/packages/g6/__tests__/demo/case/layout-fruchterman-fix.ts index bd51188746f..b30405dc771 100644 --- a/packages/g6/__tests__/demo/case/layout-fruchterman-fix.ts +++ b/packages/g6/__tests__/demo/case/layout-fruchterman-fix.ts @@ -11,7 +11,7 @@ export const layoutFruchtermanFix: STDTestCase = async (context) => { speed: 10, maxIteration: 500, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.on('node:dragstart', function () { diff --git a/packages/g6/__tests__/demo/case/layout-grid.ts b/packages/g6/__tests__/demo/case/layout-grid.ts index 864827ee16e..2ee0159de48 100644 --- a/packages/g6/__tests__/demo/case/layout-grid.ts +++ b/packages/g6/__tests__/demo/case/layout-grid.ts @@ -15,7 +15,7 @@ export const layoutGrid: STDTestCase = async (context) => { type: 'grid', sortBy: 'cluster', }, - behaviors: ['zoom-canvas', 'drag-canvas', 'drag-node', 'click-select'], + behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element', 'click-select'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-mds.ts b/packages/g6/__tests__/demo/case/layout-mds.ts index 18570108cca..1f0b7c3bca1 100644 --- a/packages/g6/__tests__/demo/case/layout-mds.ts +++ b/packages/g6/__tests__/demo/case/layout-mds.ts @@ -18,7 +18,7 @@ export const layoutMDS: STDTestCase = async (context) => { type: 'mds', linkDistance: 100, }, - behaviors: ['drag-node', 'drag-canvas', 'zoom-canvas', 'click-select'], + behaviors: ['drag-element', 'drag-canvas', 'zoom-canvas', 'click-select'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-radial-basic.ts b/packages/g6/__tests__/demo/case/layout-radial-basic.ts index 7e596b2081c..64e1df3c288 100644 --- a/packages/g6/__tests__/demo/case/layout-radial-basic.ts +++ b/packages/g6/__tests__/demo/case/layout-radial-basic.ts @@ -16,7 +16,7 @@ export const layoutRadialBasic: STDTestCase = async (context) => { type: 'radial', unitRadius: 50, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-radial-configuration-translate.ts b/packages/g6/__tests__/demo/case/layout-radial-configuration-translate.ts index 10173cdb846..1695896f393 100644 --- a/packages/g6/__tests__/demo/case/layout-radial-configuration-translate.ts +++ b/packages/g6/__tests__/demo/case/layout-radial-configuration-translate.ts @@ -22,7 +22,7 @@ export const layoutRadialConfigurationTranslate: STDTestCase = async (context) = type: 'radial', unitRadius: 50, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-radial-prevent-overlap-unstrict.ts b/packages/g6/__tests__/demo/case/layout-radial-prevent-overlap-unstrict.ts index a63cbe3dab2..c67404aa7ca 100644 --- a/packages/g6/__tests__/demo/case/layout-radial-prevent-overlap-unstrict.ts +++ b/packages/g6/__tests__/demo/case/layout-radial-prevent-overlap-unstrict.ts @@ -24,7 +24,7 @@ export const layoutRadialPreventOverlapUnstrict: STDTestCase = async (context) = preventOverlap: true, strictRadial: false, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-radial-prevent-overlap.ts b/packages/g6/__tests__/demo/case/layout-radial-prevent-overlap.ts index 46d871c2156..0d6a4494b83 100644 --- a/packages/g6/__tests__/demo/case/layout-radial-prevent-overlap.ts +++ b/packages/g6/__tests__/demo/case/layout-radial-prevent-overlap.ts @@ -24,7 +24,7 @@ export const layoutRadialPreventOverlap: STDTestCase = async (context) => { preventOverlap: true, maxPreventOverlapIteration: 100, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/case/layout-radial-sort.ts b/packages/g6/__tests__/demo/case/layout-radial-sort.ts index 567ed0ee21f..bd74b91363d 100644 --- a/packages/g6/__tests__/demo/case/layout-radial-sort.ts +++ b/packages/g6/__tests__/demo/case/layout-radial-sort.ts @@ -28,7 +28,7 @@ export const layoutRadialSort: STDTestCase = async (context) => { sortBy: 'sortAttr2', sortStrength: 50, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); await graph.render(); diff --git a/packages/g6/__tests__/demo/static/controller-element-z-index.ts b/packages/g6/__tests__/demo/static/controller-element-z-index.ts index 789da7f61b3..f8ed0dafb2b 100644 --- a/packages/g6/__tests__/demo/static/controller-element-z-index.ts +++ b/packages/g6/__tests__/demo/static/controller-element-z-index.ts @@ -23,12 +23,10 @@ export const controllerElementZIndex: STDTestCase = async (context) => { const graph = new Graph(options); await graph.render(); const front = () => graph.frontElement('node-2'); - const back = () => graph.backElement('node-2'); const to = (zIndex: number) => graph.setElementZIndex('node-2', zIndex); controllerElementZIndex.form = (panel) => [ panel.add({ front }, 'front').name('Bring Element To Front'), - panel.add({ back }, 'back').name('Send Element To Back'), panel.add({ to: 0 }, 'to', -10, 10, 1).onChange((zIndex: number) => to(zIndex)), ]; diff --git a/packages/g6/__tests__/demo/static/element-label-background.ts b/packages/g6/__tests__/demo/static/element-label-background.ts index 0686e1cee8d..2ea38c178d9 100644 --- a/packages/g6/__tests__/demo/static/element-label-background.ts +++ b/packages/g6/__tests__/demo/static/element-label-background.ts @@ -68,7 +68,7 @@ export const elementLabelBackground: StaticTestCase = async (context) => { labelBackgroundRadius: 2, }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], animation, theme, }); diff --git a/packages/g6/__tests__/demo/static/element-label-oversized.ts b/packages/g6/__tests__/demo/static/element-label-oversized.ts index beb4f37eca3..9ed42f416a1 100644 --- a/packages/g6/__tests__/demo/static/element-label-oversized.ts +++ b/packages/g6/__tests__/demo/static/element-label-oversized.ts @@ -72,7 +72,7 @@ export const elementLabelOversized: StaticTestCase = async (context) => { labelMaxLines: 4, }, }, - behaviors: ['drag-node'], + behaviors: ['drag-element'], animation, }); diff --git a/packages/g6/__tests__/main.ts b/packages/g6/__tests__/main.ts index 5613f266c41..ff91b68099f 100644 --- a/packages/g6/__tests__/main.ts +++ b/packages/g6/__tests__/main.ts @@ -77,6 +77,8 @@ async function render() { const result = await testCase({ container: canvas, animation: Animation, theme: Theme }); + Object.assign(window, { graph: result }); + renderForm(panels.panel, testCase.form); if (result?.totalDuration) { diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/collapse-combo-2.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/collapse-combo-2.svg new file mode 100644 index 00000000000..06877ec7369 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/collapse-combo-2.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + combo-2 + + + + + + + 2 + + + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/default.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/default.svg new file mode 100644 index 00000000000..dcf83d24618 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/default.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/expand-combo-1.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/expand-combo-1.svg new file mode 100644 index 00000000000..f93d22b0b63 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-collapse-expand/expand-combo-1.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/default.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/default.svg new file mode 100644 index 00000000000..f93d22b0b63 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/default.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-after-drop-move.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-after-drop-move.svg new file mode 100644 index 00000000000..5a16db23aa4 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-after-drop-move.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-after-drop-out.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-after-drop-out.svg new file mode 100644 index 00000000000..b79f65081e4 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-after-drop-out.svg @@ -0,0 +1,238 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-before-drop-move.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-before-drop-move.svg new file mode 100644 index 00000000000..59aedb1e4dc --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-before-drop-move.svg @@ -0,0 +1,238 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-before-drop-out.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-before-drop-out.svg new file mode 100644 index 00000000000..930dad83f8c --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-1-before-drop-out.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-2-after-drop-into.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-2-after-drop-into.svg new file mode 100644 index 00000000000..3f79bf27743 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-2-after-drop-into.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-2-before-drop-into.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-2-before-drop-into.svg new file mode 100644 index 00000000000..61ac4babe10 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-combo-2-before-drop-into.svg @@ -0,0 +1,238 @@ + + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-into.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-into.svg new file mode 100644 index 00000000000..8a44b5784d2 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-into.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-move.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-move.svg new file mode 100644 index 00000000000..924b7f5c6f1 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-move.svg @@ -0,0 +1,238 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-out.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-out.svg new file mode 100644 index 00000000000..dbba50db697 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-after-drop-out.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-into.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-into.svg new file mode 100644 index 00000000000..8a44b5784d2 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-into.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-move.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-move.svg new file mode 100644 index 00000000000..de027dd734f --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-move.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-out.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-out.svg new file mode 100644 index 00000000000..fa0370da67b --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-1-before-drop-out.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-2-after-drop-out.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-2-after-drop-out.svg new file mode 100644 index 00000000000..d5b217be657 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-2-after-drop-out.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-2-before-drop-out.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-2-before-drop-out.svg new file mode 100644 index 00000000000..6cffad34d0e --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element-combo/drag-node-2-before-drop-out.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-2 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-node/after-drag.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/after-drag.svg similarity index 97% rename from packages/g6/__tests__/snapshots/behaviors/behavior-drag-node/after-drag.svg rename to packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/after-drag.svg index 8ad6477ba11..ad3797a7b10 100644 --- a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-node/after-drag.svg +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/after-drag.svg @@ -59,7 +59,7 @@ /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/drag-combo-shadow.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/drag-combo-shadow.svg new file mode 100644 index 00000000000..500da25d412 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/drag-combo-shadow.svg @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/drag-combo.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/drag-combo.svg new file mode 100644 index 00000000000..3df3709dc08 --- /dev/null +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/drag-combo.svg @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-node/hideEdges-both.svg b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/hideEdges-both.svg similarity index 97% rename from packages/g6/__tests__/snapshots/behaviors/behavior-drag-node/hideEdges-both.svg rename to packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/hideEdges-both.svg index 06d6e064c80..80c58a0e99d 100644 --- a/packages/g6/__tests__/snapshots/behaviors/behavior-drag-node/hideEdges-both.svg +++ b/packages/g6/__tests__/snapshots/behaviors/behavior-drag-element/hideEdges-both.svg @@ -59,7 +59,7 @@ /> - + - + - + - + - + - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-bottomLeft.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-bottomLeft.svg index a7679075456..3bb8c997aa3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-bottomLeft.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-bottomLeft.svg @@ -13,22 +13,22 @@ - + - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-bottomRight.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-bottomRight.svg index a7b634f0f32..3bb8c997aa3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-bottomRight.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-bottomRight.svg @@ -13,22 +13,22 @@ - + - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-center.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-center.svg index 87bcdf7c714..3bb8c997aa3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-center.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-center.svg @@ -10,208 +10,25 @@ - - - - - - - - combo-2 - - - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - + - node-3 + combo-2 + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-left.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-left.svg index 3ea4213a446..3bb8c997aa3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-left.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-left.svg @@ -10,208 +10,25 @@ - - - - - - - - combo-2 - - - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - + - node-3 + combo-2 + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-right.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-right.svg index a000f4f8e0b..3bb8c997aa3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-right.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-right.svg @@ -10,208 +10,25 @@ - - - - - - - - combo-2 - - - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - + - node-3 + combo-2 + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-top.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-top.svg index 5c65da8d1c6..3bb8c997aa3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-top.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-top.svg @@ -13,22 +13,22 @@ - + - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-topLeft.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-topLeft.svg index 3ff495b42ee..3bb8c997aa3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-topLeft.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-topLeft.svg @@ -13,22 +13,22 @@ - + - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-topRight.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-topRight.svg index 6859feccac6..3bb8c997aa3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-topRight.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-collapse-topRight.svg @@ -13,22 +13,22 @@ - + - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-marker-childCount.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-marker-childCount.svg index e2584a0bfa6..61b9c8bdc35 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-marker-childCount.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-marker-childCount.svg @@ -13,22 +13,22 @@ - + - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-marker-custom.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-marker-custom.svg index cb8fb8ac1a3..8b7e1be544b 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-marker-custom.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-marker-custom.svg @@ -13,22 +13,22 @@ - + - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-marker-descendantCount.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-marker-descendantCount.svg index 0d2de7da11f..a2a1663d8ff 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-marker-descendantCount.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-marker-descendantCount.svg @@ -13,22 +13,22 @@ - + - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/circle-marker-nodeCount.svg b/packages/g6/__tests__/snapshots/elements/combo/circle-marker-nodeCount.svg index 6e3409acdc0..f7825209768 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/circle-marker-nodeCount.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/circle-marker-nodeCount.svg @@ -13,22 +13,22 @@ - + - - - - - - - - combo-1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - node-1 - - - - - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottom.svg b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottom.svg index ca24f4e3e4e..0903be325f3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottom.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottom.svg @@ -10,21 +10,25 @@ - + - + - + - + - + @@ -106,38 +110,6 @@ /> - - - - - - - @@ -168,62 +140,6 @@ - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - diff --git a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottomLeft.svg b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottomLeft.svg index 05c99197720..0903be325f3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottomLeft.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottomLeft.svg @@ -10,21 +10,25 @@ - + - + - + - + - + @@ -106,38 +110,6 @@ /> - - - - - - - @@ -168,62 +140,6 @@ - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - diff --git a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottomRight.svg b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottomRight.svg index a3dcb289e54..0903be325f3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottomRight.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-bottomRight.svg @@ -10,21 +10,25 @@ - + - + - + - + - + @@ -106,38 +110,6 @@ /> - - - - - - - @@ -168,62 +140,6 @@ - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - diff --git a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-center.svg b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-center.svg index a21d2b0d4dc..0903be325f3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-center.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-center.svg @@ -13,22 +13,22 @@ - + - + - + - + @@ -114,38 +110,6 @@ /> - - - - - - - @@ -176,62 +140,6 @@ - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - diff --git a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-left.svg b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-left.svg index 4e3a849a779..0903be325f3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-left.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-left.svg @@ -13,22 +13,22 @@ - + - + - + - + @@ -114,38 +110,6 @@ /> - - - - - - - @@ -176,62 +140,6 @@ - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - diff --git a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-right.svg b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-right.svg index 80e57d803e0..0903be325f3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-right.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-right.svg @@ -13,22 +13,22 @@ - + - + - + - + @@ -114,38 +110,6 @@ /> - - - - - - - @@ -176,62 +140,6 @@ - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - diff --git a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-top.svg b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-top.svg index 3f39bbeb161..0903be325f3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-top.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-top.svg @@ -13,22 +13,22 @@ - + - + - + - + @@ -110,38 +110,6 @@ /> - - - - - - - @@ -172,62 +140,6 @@ - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - diff --git a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-topLeft.svg b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-topLeft.svg index 3cca9556ad9..0903be325f3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-topLeft.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-topLeft.svg @@ -13,22 +13,22 @@ - + - + - + - + @@ -110,38 +110,6 @@ /> - - - - - - - @@ -172,62 +140,6 @@ - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - diff --git a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-topRight.svg b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-topRight.svg index 44436485743..0903be325f3 100644 --- a/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-topRight.svg +++ b/packages/g6/__tests__/snapshots/elements/combo/rect-collapse-topRight.svg @@ -13,22 +13,22 @@ - + - + - + - + @@ -110,38 +110,6 @@ /> - - - - - - - @@ -172,62 +140,6 @@ - - - - - - - - node-2 - - - - - - - - - - - - node-3 - - - - diff --git a/packages/g6/__tests__/snapshots/elements/position-combo/default.svg b/packages/g6/__tests__/snapshots/elements/position-combo/default.svg new file mode 100644 index 00000000000..2e672ef6268 --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/position-combo/default.svg @@ -0,0 +1,239 @@ + + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-4 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/default.svg b/packages/g6/__tests__/snapshots/elements/z-index/default.svg new file mode 100644 index 00000000000..a64ddef4fb9 --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/default.svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-4 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/drag-combo-1.svg b/packages/g6/__tests__/snapshots/elements/z-index/drag-combo-1.svg new file mode 100644 index 00000000000..2170fcf85ab --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/drag-combo-1.svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-4 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/drag-combo-2.svg b/packages/g6/__tests__/snapshots/elements/z-index/drag-combo-2.svg new file mode 100644 index 00000000000..385ec0bf9de --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/drag-combo-2.svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-4 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/drag-combo-3.svg b/packages/g6/__tests__/snapshots/elements/z-index/drag-combo-3.svg new file mode 100644 index 00000000000..18fc1693672 --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/drag-combo-3.svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-4 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-3.svg b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-3.svg new file mode 100644 index 00000000000..29b0ec7b420 --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-3.svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-4 + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(1).svg b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(1).svg new file mode 100644 index 00000000000..1244f9a519f --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(1).svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + combo-4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(2).svg b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(2).svg new file mode 100644 index 00000000000..e6c8ac32c6c --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(2).svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + combo-4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(3).svg b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(3).svg new file mode 100644 index 00000000000..0ca6bb87ed4 --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-combo-4(3).svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + combo-4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-1.svg b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-1.svg new file mode 100644 index 00000000000..73068928763 --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-1.svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-4 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-1 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-2.svg b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-2.svg new file mode 100644 index 00000000000..bc5c80cd66a --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-2.svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-4 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-3 + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-3.svg b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-3.svg new file mode 100644 index 00000000000..aa48595755a --- /dev/null +++ b/packages/g6/__tests__/snapshots/elements/z-index/drag-overlap-node-3.svg @@ -0,0 +1,328 @@ + + + + + + + + + + + + + combo-1 + + + + + + + + + + + + combo-4 + + + + + + + + + + + + combo-2 + + + + + + + + + + + + combo-3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node-1 + + + + + + + + + + + + node-2 + + + + + + + + + + + + node-3 + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/layouts/dagre-flow/flow-combo.svg b/packages/g6/__tests__/snapshots/layouts/dagre-flow/flow-combo.svg index e9e93abe893..138c06e40ac 100644 --- a/packages/g6/__tests__/snapshots/layouts/dagre-flow/flow-combo.svg +++ b/packages/g6/__tests__/snapshots/layouts/dagre-flow/flow-combo.svg @@ -9,21 +9,21 @@ - + @@ -140,7 +140,7 @@ /> { + let graph: Graph; + + beforeAll(async () => { + graph = await createDemoGraph(comboExpandCollapse, { animation: false }); + }); + + it('default status', async () => { + await expect(graph).toMatchSnapshot(__filename); + }); + + it('collapse', async () => { + // collapse combo-2 + graph.emit(`combo:${CommonEvent.DBLCLICK}`, { target: { id: 'combo-2' } }); + await expect(graph).toMatchSnapshot(__filename, 'collapse-combo-2'); + }); + + it('expand', async () => { + // expand combo-2 + graph.emit(`combo:${CommonEvent.DBLCLICK}`, { target: { id: 'combo-2' } }); + // expand combo-1 + graph.emit(`combo:${CommonEvent.DBLCLICK}`, { target: { id: 'combo-1' } }); + await expect(graph).toMatchSnapshot(__filename, 'expand-combo-1'); + }); +}); diff --git a/packages/g6/__tests__/unit/behaviors/behavior-drag-element-combo.spec.ts b/packages/g6/__tests__/unit/behaviors/behavior-drag-element-combo.spec.ts new file mode 100644 index 00000000000..bcb96187a75 --- /dev/null +++ b/packages/g6/__tests__/unit/behaviors/behavior-drag-element-combo.spec.ts @@ -0,0 +1,73 @@ +import { CommonEvent, type Graph } from '@/src'; +import { comboExpandCollapse } from '@@/demo/case'; +import { createDemoGraph } from '@@/utils'; + +describe('behavior drag combo', () => { + let graph: Graph; + + beforeAll(async () => { + graph = await createDemoGraph(comboExpandCollapse, { animation: false }); + }); + + it('default status', async () => { + graph.setBehaviors([{ type: 'drag-element', dropEffect: 'link' }]); + graph.expand('combo-1'); + await expect(graph).toMatchSnapshot(__filename); + }); + + it('drag node out', async () => { + // drag node-2 to combo-2 + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-2' }, targetType: 'node' }); + graph.emit(`node:${CommonEvent.DRAG}`, { dx: 80, dy: 60 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-node-2-before-drop-out'); + graph.emit(`combo:${CommonEvent.DROP}`, { target: { id: 'combo-2' } }); + await expect(graph).toMatchSnapshot(__filename, 'drag-node-2-after-drop-out'); + + // drag node-1 to canvas + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-1' }, targetType: 'node' }); + graph.emit(`node:${CommonEvent.DRAG}`, { dx: -70, dy: -70 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-node-1-before-drop-out'); + graph.emit(`canvas:${CommonEvent.DROP}`, { target: {} }); + await expect(graph).toMatchSnapshot(__filename, 'drag-node-1-after-drop-out'); + }); + + it('drag node into', async () => { + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-1' }, targetType: 'node' }); + graph.emit(`node:${CommonEvent.DRAG}`, { dx: 250, dy: 250 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-node-1-before-drop-into'); + graph.emit(`combo:${CommonEvent.DROP}`, { target: { id: 'combo-2' } }); + await expect(graph).toMatchSnapshot(__filename, 'drag-node-1-after-drop-into'); + }); + + it('drag node move', async () => { + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-1' }, targetType: 'node' }); + graph.emit(`node:${CommonEvent.DRAG}`, { dx: 100, dy: 100 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-node-1-before-drop-move'); + graph.emit(`combo:${CommonEvent.DROP}`, { target: { id: 'combo-2' } }); + await expect(graph).toMatchSnapshot(__filename, 'drag-node-1-after-drop-move'); + }); + + it('drag combo move', async () => { + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-1' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: 100, dy: 100 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-1-before-drop-move'); + graph.emit(`combo:${CommonEvent.DROP}`, { target: { id: 'combo-2' } }); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-1-after-drop-move'); + }); + + it('drag combo out', async () => { + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-1' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: -250, dy: -250 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-1-before-drop-out'); + graph.emit(`canvas:${CommonEvent.DROP}`, { target: {} }); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-1-after-drop-out'); + }); + + it('drag combo into', async () => { + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-2' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: -200, dy: -200 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-2-before-drop-into'); + graph.emit(`combo:${CommonEvent.DROP}`, { target: { id: 'combo-1' } }); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-2-after-drop-into'); + }); +}); diff --git a/packages/g6/__tests__/unit/behaviors/behavior-drag-node.spec.ts b/packages/g6/__tests__/unit/behaviors/behavior-drag-element.spec.ts similarity index 53% rename from packages/g6/__tests__/unit/behaviors/behavior-drag-node.spec.ts rename to packages/g6/__tests__/unit/behaviors/behavior-drag-element.spec.ts index 4afe3929140..21282351ae4 100644 --- a/packages/g6/__tests__/unit/behaviors/behavior-drag-node.spec.ts +++ b/packages/g6/__tests__/unit/behaviors/behavior-drag-element.spec.ts @@ -2,7 +2,7 @@ import { CommonEvent, type Graph } from '@/src'; import { behaviorDragNode } from '@@/demo/case'; import { createDemoGraph } from '@@/utils'; -describe('behavior drag node', () => { +describe('behavior drag element', () => { let graph: Graph; beforeAll(async () => { @@ -12,7 +12,7 @@ describe('behavior drag node', () => { it('default status', async () => { await expect(graph).toMatchSnapshot(__filename); - graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-4' } }); + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-4' }, targetType: 'node' }); graph.emit(`node:${CommonEvent.DRAG}`, { dx: 20, dy: 20 }); graph.emit(`node:${CommonEvent.DRAG_END}`); @@ -20,31 +20,48 @@ describe('behavior drag node', () => { }); it('hide edges', async () => { - graph.setBehaviors([{ type: 'drag-node', hideEdges: 'both' }]); - graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-4' } }); + graph.setBehaviors([{ type: 'drag-element', hideEdges: 'both' }]); + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-4' }, targetType: 'node' }); graph.emit(`node:${CommonEvent.DRAG}`, { dx: 20, dy: 20 }); await expect(graph).toMatchSnapshot(__filename, 'hideEdges-both'); graph.emit(`node:${CommonEvent.DRAG_END}`); - graph.setBehaviors([{ type: 'drag-node', hideEdges: 'in' }]); - graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-3' } }); + graph.setBehaviors([{ type: 'drag-element', hideEdges: 'in' }]); + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-3' }, targetType: 'node' }); graph.emit(`node:${CommonEvent.DRAG}`, { dx: 0, dy: 20 }); await expect(graph).toMatchSnapshot(__filename, 'hideEdges-in'); graph.emit(`node:${CommonEvent.DRAG_END}`); - graph.setBehaviors([{ type: 'drag-node', hideEdges: 'out' }]); - graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-3' } }); + graph.setBehaviors([{ type: 'drag-element', hideEdges: 'out' }]); + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-3' }, targetType: 'node' }); graph.emit(`node:${CommonEvent.DRAG}`, { dx: 0, dy: 20 }); await expect(graph).toMatchSnapshot(__filename, 'hideEdges-out'); graph.emit(`node:${CommonEvent.DRAG_END}`); }); - it('shadow', async () => { - graph.setBehaviors([{ type: 'drag-node', shadow: true, shadowStroke: 'red', shadowStrokeOpacity: 1 }]); - graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-4' } }); + it('drag node shadow', async () => { + graph.setBehaviors([{ type: 'drag-element', shadow: true, shadowStroke: 'red', shadowStrokeOpacity: 1 }]); + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-4' }, targetType: 'node' }); graph.emit(`node:${CommonEvent.DRAG}`, { dx: 20, dy: 20 }); await expect(graph).toMatchSnapshot(__filename, 'shadow'); graph.emit(`node:${CommonEvent.DRAG_END}`); await expect(graph).toMatchSnapshot(__filename, 'shadow-after-drag'); }); + + it('drag combo', async () => { + graph.setBehaviors(['drag-element']); + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-1' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: 20, dy: 20 }); + graph.emit(`combo:${CommonEvent.DRAG_END}`); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo'); + }); + + it('drag combo shadow', async () => { + graph.setBehaviors([{ type: 'drag-element', shadow: true, shadowStroke: 'red', shadowStrokeOpacity: 1 }]); + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-1' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: 20, dy: 20 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-shadow'); + graph.emit(`combo:${CommonEvent.DRAG_END}`); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-shadow-after-drag'); + }); }); diff --git a/packages/g6/__tests__/unit/elements/combo.spec.ts b/packages/g6/__tests__/unit/elements/combo.spec.ts index ebbf3ac5daf..a8f8845d3c2 100644 --- a/packages/g6/__tests__/unit/elements/combo.spec.ts +++ b/packages/g6/__tests__/unit/elements/combo.spec.ts @@ -14,7 +14,7 @@ describe('combo', () => { }); it('collapse circle combo', async () => { - const expandCombo = () => { + const expandCombo = async () => { graph.updateComboData([ { id: 'combo-2', @@ -23,9 +23,9 @@ describe('combo', () => { }, }, ]); - graph.render(); + await graph.render(); }; - const collapseCombo = (collapsedOrigin: any) => { + const collapseCombo = async (collapsedOrigin: any) => { graph.updateComboData([ { id: 'combo-2', @@ -36,38 +36,38 @@ describe('combo', () => { }, }, ]); - graph.render(); + await graph.render(); }; - collapseCombo('top'); + await collapseCombo('top'); await expect(graph).toMatchSnapshot(__filename, 'circle-collapse-top'); - expandCombo(); - collapseCombo('right'); + await expandCombo(); + await collapseCombo('right'); await expect(graph).toMatchSnapshot(__filename, 'circle-collapse-right'); - collapseCombo('left'); + await collapseCombo('left'); await expect(graph).toMatchSnapshot(__filename, 'circle-collapse-left'); - expandCombo(); - collapseCombo('bottom'); + await expandCombo(); + await collapseCombo('bottom'); await expect(graph).toMatchSnapshot(__filename, 'circle-collapse-bottom'); - expandCombo(); - collapseCombo('center'); + await expandCombo(); + await collapseCombo('center'); await expect(graph).toMatchSnapshot(__filename, 'circle-collapse-center'); - expandCombo(); - collapseCombo('top-left'); + await expandCombo(); + await collapseCombo('top-left'); await expect(graph).toMatchSnapshot(__filename, 'circle-collapse-topLeft'); - expandCombo(); - collapseCombo('top-right'); + await expandCombo(); + await collapseCombo('top-right'); await expect(graph).toMatchSnapshot(__filename, 'circle-collapse-topRight'); - expandCombo(); - collapseCombo('bottom-left'); + await expandCombo(); + await collapseCombo('bottom-left'); await expect(graph).toMatchSnapshot(__filename, 'circle-collapse-bottomLeft'); - expandCombo(); - collapseCombo('bottom-right'); + await expandCombo(); + await collapseCombo('bottom-right'); await expect(graph).toMatchSnapshot(__filename, 'circle-collapse-bottomRight'); - expandCombo(); + await expandCombo(); }); it('collapse rect combo', async () => { - const expandCombo = () => { + const expandCombo = async () => { graph.updateComboData([ { id: 'combo-1', @@ -77,9 +77,9 @@ describe('combo', () => { }, }, ]); - graph.render(); + await graph.render(); }; - const collapseCombo = (collapsedOrigin: any) => { + const collapseCombo = async (collapsedOrigin: any) => { graph.updateComboData([ { id: 'combo-1', @@ -91,40 +91,39 @@ describe('combo', () => { }, }, ]); - graph.render(); + await graph.render(); }; - collapseCombo('top'); + await collapseCombo('top'); await expect(graph).toMatchSnapshot(__filename, 'rect-collapse-top'); - expandCombo(); - collapseCombo('right'); + await expandCombo(); + await collapseCombo('right'); await expect(graph).toMatchSnapshot(__filename, 'rect-collapse-right'); - collapseCombo('left'); + await collapseCombo('left'); await expect(graph).toMatchSnapshot(__filename, 'rect-collapse-left'); - expandCombo(); - collapseCombo('bottom'); + await expandCombo(); + await collapseCombo('bottom'); await expect(graph).toMatchSnapshot(__filename, 'rect-collapse-bottom'); - expandCombo(); - collapseCombo('center'); + await expandCombo(); + await collapseCombo('center'); await expect(graph).toMatchSnapshot(__filename, 'rect-collapse-center'); - expandCombo(); - collapseCombo('top-left'); + await expandCombo(); + await collapseCombo('top-left'); await expect(graph).toMatchSnapshot(__filename, 'rect-collapse-topLeft'); - expandCombo(); - collapseCombo('top-right'); + await expandCombo(); + await collapseCombo('top-right'); await expect(graph).toMatchSnapshot(__filename, 'rect-collapse-topRight'); - expandCombo(); - collapseCombo('bottom-left'); + await expandCombo(); + await collapseCombo('bottom-left'); await expect(graph).toMatchSnapshot(__filename, 'rect-collapse-bottomLeft'); - expandCombo(); - collapseCombo('bottom-right'); + await expandCombo(); + await collapseCombo('bottom-right'); await expect(graph).toMatchSnapshot(__filename, 'rect-collapse-bottomRight'); - expandCombo(); + await expandCombo(); }); it('collapse combo with collapsed marker', async () => { - const expandCombo = () => { - graph.updateComboData((data) => [ - ...data, + const expandCombo = async () => { + graph.updateComboData([ { id: 'combo-2', style: { @@ -132,9 +131,9 @@ describe('combo', () => { }, }, ]); - graph.render(); + await graph.render(); }; - const collapseCombo = (type: any | ((children: any[]) => string)) => { + const collapseCombo = async (type: any | ((children: any) => string)) => { graph.updateComboData([ { id: 'combo-2', @@ -148,16 +147,16 @@ describe('combo', () => { ]); graph.render(); }; - collapseCombo('child-count'); + await collapseCombo('child-count'); await expect(graph).toMatchSnapshot(__filename, 'circle-marker-childCount'); - expandCombo(); - collapseCombo('descendant-count'); + await expandCombo(); + await collapseCombo('descendant-count'); await expect(graph).toMatchSnapshot(__filename, 'circle-marker-descendantCount'); - expandCombo(); - collapseCombo('node-count'); + await expandCombo(); + await collapseCombo('node-count'); await expect(graph).toMatchSnapshot(__filename, 'circle-marker-nodeCount'); - expandCombo(); - collapseCombo((children: any[]) => children.length.toString() + 'nodes'); + await expandCombo(); + await collapseCombo((children: any) => children.length.toString() + 'nodes'); await expect(graph).toMatchSnapshot(__filename, 'circle-marker-custom'); }); }); diff --git a/packages/g6/__tests__/unit/elements/position-combo.spec.ts b/packages/g6/__tests__/unit/elements/position-combo.spec.ts new file mode 100644 index 00000000000..dcd1eb37648 --- /dev/null +++ b/packages/g6/__tests__/unit/elements/position-combo.spec.ts @@ -0,0 +1,15 @@ +import type { Graph } from '@/src'; +import { elementPositionCombo } from '@@/demo/case'; +import { createDemoGraph } from '@@/utils'; + +describe('element position combo', () => { + let graph: Graph; + + beforeAll(async () => { + graph = await createDemoGraph(elementPositionCombo, { animation: false }); + }); + + it('default status', async () => { + await expect(graph).toMatchSnapshot(__filename); + }); +}); diff --git a/packages/g6/__tests__/unit/elements/z-index.spec.ts b/packages/g6/__tests__/unit/elements/z-index.spec.ts new file mode 100644 index 00000000000..fd11548638e --- /dev/null +++ b/packages/g6/__tests__/unit/elements/z-index.spec.ts @@ -0,0 +1,69 @@ +import { CommonEvent, type Graph } from '@/src'; +import { elementZIndex } from '@@/demo/case'; +import { createDemoGraph } from '@@/utils'; + +describe('element zIndex', () => { + let graph: Graph; + + beforeAll(async () => { + graph = await createDemoGraph(elementZIndex, { animation: false }); + }); + + it('default status', async () => { + await expect(graph).toMatchSnapshot(__filename); + }); + + it('drag overlap', async () => { + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-1' }, targetType: 'node' }); + graph.emit(`node:${CommonEvent.DRAG}`, { dx: 140, dy: 0 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-overlap-node-1'); + graph.emit(`node:${CommonEvent.DRAG_END}`); + + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-2' }, targetType: 'node' }); + graph.emit(`node:${CommonEvent.DRAG}`, { dx: -65, dy: 100 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-overlap-node-2'); + graph.emit(`node:${CommonEvent.DRAG_END}`); + + graph.emit(`node:${CommonEvent.DRAG_START}`, { target: { id: 'node-3' }, targetType: 'node' }); + graph.emit(`node:${CommonEvent.DRAG}`, { dx: 75, dy: -100 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-overlap-node-3'); + graph.emit(`node:${CommonEvent.DRAG_END}`); + }); + + it('combo overlap', async () => { + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-1' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: 20, dy: 0 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-1'); + graph.emit(`combo:${CommonEvent.DRAG_END}`); + + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-2' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: 20, dy: 0 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-2'); + graph.emit(`combo:${CommonEvent.DRAG_END}`); + + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-3' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: 20, dy: 0 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-combo-3'); + graph.emit(`combo:${CommonEvent.DRAG_END}`); + + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-3' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: 20, dy: 0 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-overlap-combo-3'); + graph.emit(`combo:${CommonEvent.DRAG_END}`); + + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-4' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: -20, dy: 0 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-overlap-combo-4(1)'); + graph.emit(`combo:${CommonEvent.DRAG_END}`); + + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-4' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: -40, dy: 0 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-overlap-combo-4(2)'); + graph.emit(`combo:${CommonEvent.DRAG_END}`); + + graph.emit(`combo:${CommonEvent.DRAG_START}`, { target: { id: 'combo-4' }, targetType: 'combo' }); + graph.emit(`combo:${CommonEvent.DRAG}`, { dx: -40, dy: 0 }); + await expect(graph).toMatchSnapshot(__filename, 'drag-overlap-combo-4(3)'); + graph.emit(`combo:${CommonEvent.DRAG_END}`); + }); +}); diff --git a/packages/g6/__tests__/unit/layouts/radial-layout.spec.ts b/packages/g6/__tests__/unit/layouts/radial-layout.spec.ts index 89ff580f13d..36c6188e860 100644 --- a/packages/g6/__tests__/unit/layouts/radial-layout.spec.ts +++ b/packages/g6/__tests__/unit/layouts/radial-layout.spec.ts @@ -14,7 +14,7 @@ describe('radial layout', () => { graph.destroy(); }); - it('configuration translate', async () => { + it.skip('configuration translate', async () => { const graph = await createDemoGraph(layoutRadialConfigurationTranslate); await expect(graph).toMatchSnapshot(__filename, 'configuration-translate'); graph.destroy(); diff --git a/packages/g6/__tests__/unit/runtime/data.spec.ts b/packages/g6/__tests__/unit/runtime/data.spec.ts index e07cd56a600..595a715e812 100644 --- a/packages/g6/__tests__/unit/runtime/data.spec.ts +++ b/packages/g6/__tests__/unit/runtime/data.spec.ts @@ -3,6 +3,7 @@ import { DataController } from '@/src/runtime/data'; import { reduceDataChanges } from '@/src/utils/change'; import tree from '@@/dataset/algorithm-category.json'; import { clone } from '@antv/util'; +import { idOf } from '../../../src/utils/id'; const data = { nodes: [ @@ -108,6 +109,10 @@ describe('DataController', () => { expect(controller.getEdgeData(['edge-1'])).toEqual(data.edges.slice(0, 1)); expect(controller.getComboData(['combo-1'])).toEqual(data.combos.slice(0, 1)); + + expect(controller.getChildrenData('combo-1').map(idOf)).toEqual(['node-2', 'node-3']); + + expect(controller.getAncestorsData('node-2', 'combo').map(idOf)).toEqual(['combo-1']); }); it('updateData', () => { @@ -209,8 +214,8 @@ describe('DataController', () => { expect(controller.getData()).toEqual({ nodes: [ - { id: 'node-1', data: {}, style: { x: 150, y: 150, z: 0, parentId: 'combo-1' } }, - { id: 'node-2', data: {}, style: { x: 200, y: 200, z: 0, parentId: 'combo-1' } }, + { id: 'node-1', data: {}, style: { x: 50, y: 50, parentId: 'combo-1' } }, + { id: 'node-2', data: {}, style: { x: 100, y: 100, parentId: 'combo-1' } }, ], edges: [], combos: [ @@ -223,8 +228,8 @@ describe('DataController', () => { expect(controller.getData()).toEqual({ nodes: [ - { id: 'node-1', data: {}, style: { x: 150, y: 150, z: 0, parentId: 'combo-1' } }, - { id: 'node-2', data: {}, style: { x: 200, y: 200, z: 0, parentId: 'combo-1' } }, + { id: 'node-1', data: {}, style: { x: 50, y: 50, parentId: 'combo-1' } }, + { id: 'node-2', data: {}, style: { x: 100, y: 100, parentId: 'combo-1' } }, ], edges: [], combos: [ @@ -244,7 +249,7 @@ describe('DataController', () => { combos: [{ id: 'combo-1' }], }); - controller.translateComboBy(['combo-1'], [100, 100]); + controller.translateComboBy('combo-1', [100, 100]); expect(controller.getData()).toEqual({ nodes: [{ id: 'node-1', data: {}, style: { parentId: 'combo-1', x: 100, y: 100, z: 0 } }], @@ -265,7 +270,7 @@ describe('DataController', () => { combos: [{ id: 'combo-1' }], }); - controller.translateComboBy(['combo-1'], [66, 67]); + controller.translateComboBy('combo-1', [66, 67]); expect(controller.getNodeData()).toEqual([ { id: 'node-1', data: {}, style: {} }, @@ -281,7 +286,7 @@ describe('DataController', () => { combos: [{ id: 'combo-1' }], }); - controller.translateComboBy(['combo-1'], [100, 100]); + controller.translateComboBy('combo-1', [100, 100]); expect(controller.getData()).toEqual({ nodes: [], @@ -301,7 +306,7 @@ describe('DataController', () => { combos: [{ id: 'combo-1' }], }); - controller.translateComboTo(['combo-1'], [100, 100]); + controller.translateComboTo('combo-1', [100, 100]); expect(controller.getData()).toEqual({ nodes: [ @@ -373,7 +378,7 @@ describe('DataController', () => { controller.addData(clone(data)); - expect(controller.getParentComboData('node-2')).toEqual(data.combos[0]); + expect(controller.getParentData('node-2', 'combo')).toEqual(data.combos[0]); controller.removeComboData(['combo-1']); @@ -390,7 +395,7 @@ describe('DataController', () => { combos: [], }); - expect(controller.getParentComboData('node-2')).toEqual(undefined); + expect(controller.getParentData('node-2', 'combo')).toEqual(undefined); }); it('removeComboData with children', () => { @@ -410,12 +415,12 @@ describe('DataController', () => { controller.addData(data); - expect(controller.getParentComboData('node-1')).toEqual(data.combos[0]); - expect(controller.getParentComboData('combo-1')).toEqual(data.combos[1]); + expect(controller.getParentData('node-1', 'combo')?.id).toEqual('combo-1'); + expect(controller.getParentData('combo-1', 'combo')?.id).toEqual('combo-2'); controller.removeComboData(['combo-1']); - expect(controller.getParentComboData('node-1')).toEqual(data.combos[1]); + expect(controller.getParentData('node-1', 'combo')?.id).toEqual('combo-2'); expect(controller.getData()).toEqual({ nodes: [ @@ -448,6 +453,17 @@ describe('DataController', () => { { value: { id: 'node-1', data: { value: 1 }, style: { fill: 'red' } }, type: 'NodeAdded' }, { value: { id: 'node-2', data: { value: 2 }, style: { fill: 'green', parentId: 'combo-1' } }, type: 'NodeAdded' }, { value: { id: 'node-3', data: { value: 3 }, style: { fill: 'blue', parentId: 'combo-1' } }, type: 'NodeAdded' }, + // 新增子元素后更新 combo / update combo after add child + { + value: { id: 'combo-1', data: {}, style: {} }, + original: { id: 'combo-1', data: {}, style: {} }, + type: 'ComboUpdated', + }, + { + value: { id: 'combo-1', data: {}, style: {} }, + original: { id: 'combo-1', data: {}, style: {} }, + type: 'ComboUpdated', + }, { value: { id: 'edge-1', source: 'node-1', target: 'node-2', data: { weight: 1 }, style: {} }, type: 'EdgeAdded', @@ -463,6 +479,12 @@ describe('DataController', () => { original: { id: 'node-3', data: { value: 3 }, style: { fill: 'blue', parentId: 'combo-1' } }, type: 'NodeUpdated', }, + // 移动节点后更新 combo / update combo after move node + { + value: { id: 'combo-2', data: {}, style: {} }, + original: { id: 'combo-2', data: {}, style: {} }, + type: 'ComboUpdated', + }, { value: { id: 'edge-1', source: 'node-1', target: 'node-2', data: { weight: 1 }, style: {} }, type: 'EdgeRemoved', @@ -476,6 +498,12 @@ describe('DataController', () => { value: { id: 'node-2', data: { value: 2 }, style: { fill: 'green', parentId: 'combo-1' } }, type: 'NodeRemoved', }, + // 移除节点后更新 combo / update combo after remove node + { + value: { id: 'combo-1', data: {}, style: {} }, + original: { id: 'combo-1', data: {}, style: {} }, + type: 'ComboUpdated', + }, { value: { id: 'combo-1', data: {}, style: {} }, type: 'ComboRemoved' }, ]); @@ -484,7 +512,7 @@ describe('DataController', () => { type: 'NodeAdded', value: { id: 'node-3', data: { value: 3 }, style: { fill: 'pink', parentId: 'combo-2' } }, }, - { value: { id: 'combo-2' }, type: 'ComboAdded' }, + { value: { id: 'combo-2', data: {}, style: {} }, type: 'ComboAdded' }, { value: { id: 'node-4', data: { value: 4 }, style: { fill: 'yellow' } }, type: 'NodeAdded' }, ]); @@ -506,7 +534,7 @@ describe('DataController', () => { const changes = controller.getChanges(); expect(reduceDataChanges(changes)).toEqual([ - { value: { id: 'combo-2' }, type: 'ComboAdded' }, + { value: { id: 'combo-2', data: {}, style: {} }, type: 'ComboAdded' }, { type: 'NodeAdded', value: { id: 'node-3', data: { value: 3 }, style: { fill: 'pink', parentId: 'combo-2' } }, @@ -565,12 +593,17 @@ describe('DataController', () => { expect(controller.getNodeLikeData()).toEqual([...data.combos, ...data.nodes]); }); - it('getParentData getChildrenData', () => { + it('getAncestorsData getParentData getChildrenData', () => { const controller = new DataController(); controller.addData(Utils.treeToGraphData(tree)); - expect(controller.getParentData('Classification')?.id).toBe(tree.id); + expect(controller.getAncestorsData('Logistic regression', 'tree').map(idOf)).toEqual([ + 'Classification', + 'Modeling Methods', + ]); + + expect(controller.getParentData('Classification', 'tree')?.id).toBe(tree.id); expect(controller.getChildrenData('Modeling Methods').map((child) => child.id)).toEqual( tree.children.map((child) => child.id), @@ -609,13 +642,11 @@ describe('DataController', () => { controller.addData(clone(data)); - expect(controller.getComboChildrenData('combo-undefined')).toEqual([]); - - expect(controller.getComboChildrenData('combo-1')).toEqual(data.nodes.slice(1)); + expect(controller.getChildrenData('combo-1')).toEqual(data.nodes.slice(1)); controller.updateNodeData([{ id: 'node-1', style: { parentId: 'combo-1' } }]); - expect(controller.getComboChildrenData('combo-1')?.sort((a, b) => (a.id < b.id ? -1 : 1))).toEqual([ + expect(controller.getChildrenData('combo-1')?.sort((a, b) => (a.id < b.id ? -1 : 1))).toEqual([ { id: 'node-1', data: { value: 1 }, style: { fill: 'red', parentId: 'combo-1' } }, { id: 'node-2', data: { value: 2 }, style: { fill: 'green', parentId: 'combo-1' } }, { id: 'node-3', data: { value: 3 }, style: { fill: 'blue', parentId: 'combo-1' } }, @@ -628,11 +659,11 @@ describe('DataController', () => { { id: 'node-3', style: { parentId: 'combo-2' } }, ]); - expect(controller.getComboChildrenData('combo-1')).toEqual([ + expect(controller.getChildrenData('combo-1')).toEqual([ { id: 'node-1', data: { value: 1 }, style: { fill: 'red', parentId: 'combo-1' } }, ]); - expect(controller.getComboChildrenData('combo-2')).toEqual([ + expect(controller.getChildrenData('combo-2')).toEqual([ { id: 'node-2', data: { value: 2 }, style: { fill: 'green', parentId: 'combo-2' } }, { id: 'node-3', data: { value: 3 }, style: { fill: 'blue', parentId: 'combo-2' } }, ]); @@ -643,13 +674,13 @@ describe('DataController', () => { controller.addData(clone(data)); - expect(controller.getParentComboData('node-1')).toEqual(undefined); + expect(controller.getParentData('node-1', 'combo')).toEqual(undefined); controller.updateNodeData([{ id: 'node-1', style: { parentId: 'combo-1' } }]); - expect(controller.getParentComboData('node-1')).toEqual(data.combos[0]); + expect(controller.getParentData('node-1', 'combo')).toEqual(data.combos[0]); - expect(controller.getParentComboData('combo-3')).toEqual(undefined); + expect(controller.getParentData('combo-3', 'combo')).toEqual(undefined); }); it('getRelatedEdgesData', () => { diff --git a/packages/g6/__tests__/unit/runtime/element.spec.ts b/packages/g6/__tests__/unit/runtime/element.spec.ts index fb24dcd0acb..c8a33708842 100644 --- a/packages/g6/__tests__/unit/runtime/element.spec.ts +++ b/packages/g6/__tests__/unit/runtime/element.spec.ts @@ -20,21 +20,15 @@ describe('ElementController', () => { const options = graph.getOptions(); - const edge1Id = idOf(options.data!.edges![0]); - const edge2Id = idOf(options.data!.edges![1]); - - expect(elementController.getDataStyle('node-1')).toEqual(options.data!.nodes![0].style || {}); - // 没有属性 / no style - expect(elementController.getDataStyle('node-2')).toEqual({ x: 150, y: 100 }); - // 没有样式属性 / No style attribute - expect(elementController.getDataStyle('node-3')).toEqual({ - x: 125, - y: 150, - parentId: 'combo-1', - states: ['selected'], - }); - expect(elementController.getDataStyle(edge1Id)).toEqual(options.data!.edges![0].style || {}); - expect(elementController.getDataStyle('combo-1')).toEqual({}); + const node1 = options.data!.nodes![0]; + const node2 = options.data!.nodes![1]; + const node3 = options.data!.nodes![2]; + const edge1 = options.data!.edges![0]; + const edge2 = options.data!.edges![1]; + const combo1 = options.data!.combos![0]; + + const edge1Id = idOf(edge1); + const edge2Id = idOf(edge2); // ref light theme expect(elementController.getThemeStyle('node')).toEqual(LIGHT_THEME.node!.style); @@ -72,22 +66,7 @@ describe('ElementController', () => { }); expect(elementController.getStateStyle('combo-1')).toEqual({}); - // expect(Object.keys(elementController.getElementsByState('selected'))).toEqual([ - // 'node-3', - // idOf(options.data!.edges![1]), - // ]); - - // elementController.setElementsState({ 'node-1': ['active'] }); - // expect(elementController.getElementStates('node-1')).toEqual(['active']); - // elementController.setElementsState({ 'node-1': [] }); - // expect(elementController.getElementStates('node-1')).toEqual([]); - - // expect(elementController.getElementStates('node-2')).toEqual([]); - // expect(elementController.getElementStates('node-3')).toEqual(['selected']); - // expect(elementController.getElementStates('edge-1')).toEqual([]); - // expect(elementController.getElementStates(idOf(options.data!.edges![1]))).toEqual(['active', 'selected']); - - expect(elementController.getElementComputedStyle('node', 'node-1')).toEqual({ + expect(elementController.getElementComputedStyle('node', node1)).toEqual({ ...LIGHT_THEME.node?.style, type: 'circle', fill: 'blue', @@ -100,7 +79,7 @@ describe('ElementController', () => { y: 100, }); - expect(elementController.getElementComputedStyle('node', 'node-2')).toEqual({ + expect(elementController.getElementComputedStyle('node', node2)).toEqual({ ...LIGHT_THEME.node?.style, type: 'circle', fill: 'red', @@ -111,7 +90,7 @@ describe('ElementController', () => { y: 100, }); - expect(elementController.getElementComputedStyle('node', 'node-3')).toEqual({ + expect(elementController.getElementComputedStyle('node', node3)).toEqual({ ...LIGHT_THEME.node?.style, ...LIGHT_THEME.node?.state?.selected, type: 'circle', @@ -126,13 +105,13 @@ describe('ElementController', () => { y: 150, }); - expect(omit(elementController.getElementComputedStyle('edge', edge1Id), ['sourceNode', 'targetNode'])).toEqual({ + expect(omit(elementController.getElementComputedStyle('edge', edge1), ['sourceNode', 'targetNode'])).toEqual({ ...LIGHT_THEME.edge?.style, type: 'line', color: BUILT_IN_PALETTES.oranges.at(-1), }); - expect(omit(elementController.getElementComputedStyle('edge', edge2Id), ['sourceNode', 'targetNode'])).toEqual({ + expect(omit(elementController.getElementComputedStyle('edge', edge2), ['sourceNode', 'targetNode'])).toEqual({ ...LIGHT_THEME.edge?.style, ...LIGHT_THEME.edge?.state?.active, ...LIGHT_THEME.edge?.state?.selected, @@ -143,11 +122,11 @@ describe('ElementController', () => { color: BUILT_IN_PALETTES.oranges.at(-2), }); - const comboStyle = elementController.getElementComputedStyle('combo', 'combo-1'); + const comboStyle = elementController.getElementComputedStyle('combo', combo1); expect(comboStyle.childrenNode[0].id).toEqual('node-3'); - expect(omit(comboStyle, ['childrenNode'])).toEqual({ + expect(omit(comboStyle, ['childrenNode', 'childrenData'])).toEqual({ ...LIGHT_THEME.combo?.style, type: 'circle', color: BUILT_IN_PALETTES.blues[0], diff --git a/packages/g6/__tests__/unit/runtime/element/z-index.spec.ts b/packages/g6/__tests__/unit/runtime/element/z-index.spec.ts index 43684ba9c4e..faa6a7b4122 100644 --- a/packages/g6/__tests__/unit/runtime/element/z-index.spec.ts +++ b/packages/g6/__tests__/unit/runtime/element/z-index.spec.ts @@ -19,12 +19,6 @@ describe('element z-index', () => { await expect(graph).toMatchSnapshot(__filename, 'front'); }); - it('back', async () => { - graph.backElement('node-2'); - - await expect(graph).toMatchSnapshot(__filename, 'back'); - }); - it('to', async () => { graph.setElementZIndex({ 'node-2': 0 }); diff --git a/packages/g6/__tests__/unit/runtime/graph/graph.spec.ts b/packages/g6/__tests__/unit/runtime/graph/graph.spec.ts index a07606448b5..e5aac241673 100644 --- a/packages/g6/__tests__/unit/runtime/graph/graph.spec.ts +++ b/packages/g6/__tests__/unit/runtime/graph/graph.spec.ts @@ -129,7 +129,7 @@ describe('Graph', () => { expect(graph.getComboData('combo-1').id).toEqual('combo-1'); expect(graph.getComboData(['combo-1']).map(idOf)).toEqual(['combo-1']); expect(graph.getComboData().map(idOf)).toEqual(['combo-1']); - expect(graph.getComboChildrenData('combo-1').map(idOf)).toEqual(['node-3', 'node-4']); + expect(graph.getChildrenData('combo-1').map(idOf)).toEqual(['node-3', 'node-4']); graph.updateNodeData([{ id: 'node-3', style: { x: 100, y: 100 } }]); graph.updateEdgeData([{ id: 'edge-2', style: { lineWidth: 10 } }]); graph.updateComboData([{ id: 'combo-1', style: { stroke: 'red' } }]); @@ -173,7 +173,7 @@ describe('Graph', () => { }); it('getParentData', () => { - expect(graph.getParentData('node-1')).toBeUndefined(); + expect(graph.getParentData('node-1', 'combo')).toBeUndefined(); }); it('getElementRenderBounds', () => { diff --git a/packages/g6/__tests__/unit/spec/index.spec.ts b/packages/g6/__tests__/unit/spec/index.spec.ts index ed10bea4054..825af0a114c 100644 --- a/packages/g6/__tests__/unit/spec/index.spec.ts +++ b/packages/g6/__tests__/unit/spec/index.spec.ts @@ -52,7 +52,7 @@ describe('spec', () => { }, }, theme: 'light', - behaviors: ['drag-canvas', 'my-behavior', { type: 'drag-node' }], + behaviors: ['drag-canvas', 'my-behavior', { type: 'drag-element' }], plugins: ['my-plugin', { type: 'another-plugin', text: 'text', value: 1 }], }; diff --git a/packages/g6/__tests__/unit/utils/combo.spec.ts b/packages/g6/__tests__/unit/utils/combo.spec.ts index 1a020b9609c..3e9a6bc38b1 100644 --- a/packages/g6/__tests__/unit/utils/combo.spec.ts +++ b/packages/g6/__tests__/unit/utils/combo.spec.ts @@ -1,11 +1,4 @@ -import { Circle, CircleCombo } from '@/src/elements'; -import { - getCircleCollapsedOrigin, - getCollapsedMarkerText, - getDescendantCount, - getRectCollapsedOrigin, - getXYByCollapsedOrigin, -} from '@/src/utils/combo'; +import { getCircleCollapsedOrigin, getRectCollapsedOrigin, getXYByCollapsedOrigin } from '@/src/utils/combo'; describe('combo', () => { it('getRectCollapsedOrigin', () => { @@ -38,18 +31,4 @@ describe('combo', () => { expect(getXYByCollapsedOrigin('center', [100, 100], [100, 100], [200, 200])).toEqual([100, 100]); expect(getXYByCollapsedOrigin([0.5, 0.5], [100, 100], [100, 100], [200, 200])).toEqual([100, 100]); }); - - it('getCollapsedMarkerText', () => { - const children = [new CircleCombo({ style: { childrenNode: [new Circle({})] } })]; - expect(getCollapsedMarkerText('child-count', children)).toEqual('1'); - expect(getCollapsedMarkerText('descendant-count', children)).toEqual('2'); - expect(getCollapsedMarkerText('node-count', children)).toEqual('1'); - expect(getCollapsedMarkerText(undefined, children)).toEqual(''); - }); - - it('getDescendantCount', () => { - expect(getDescendantCount([new Circle({}), new Circle({})])).toEqual(2); - expect(getDescendantCount([new CircleCombo({ style: { childrenNode: [new Circle({})] } })])).toEqual(2); - expect(getDescendantCount([new CircleCombo({ style: { childrenNode: [new Circle({})] } })], true)).toEqual(1); - }); }); diff --git a/packages/g6/__tests__/unit/utils/edge.spec.ts b/packages/g6/__tests__/unit/utils/edge.spec.ts index 7702f9a3d78..f63cb709bf0 100644 --- a/packages/g6/__tests__/unit/utils/edge.spec.ts +++ b/packages/g6/__tests__/unit/utils/edge.spec.ts @@ -7,10 +7,12 @@ import { getPolylinePath, getQuadraticPath, getRadians, + getSubgraphRelatedEdges, parseCurveOffset, parseCurvePosition, } from '@/src/utils/edge'; import { AABB, Line } from '@antv/g'; +import type { ID } from '@antv/graphlib'; describe('edge', () => { describe('getLabelPositionStyle', () => { @@ -224,4 +226,64 @@ describe('edge', () => { [40, 140], ]); }); + + it('getSubgraphRelatedEdges', () => { + /** + * 1 - 2 + * / \ + * 3 - - - 4 + * \ | / + * 5 + */ + const data = { + nodes: [ + { id: 'node-1', style: { parentId: 'combo-1' } }, + { id: 'node-2', style: { parentId: 'combo-1' } }, + { id: 'node-3' }, + { id: 'node-4' }, + { id: 'node-5' }, + ], + edges: [ + { id: 'node-1-node-2', source: 'node-1', target: 'node-2' }, + { id: 'node-1-node-3', source: 'node-1', target: 'node-3' }, + { id: 'node-2-node-4', source: 'node-2', target: 'node-4' }, + { id: 'node-3-node-5', source: 'node-3', target: 'node-5' }, + { id: 'node-4-node-5', source: 'node-4', target: 'node-5' }, + { id: 'combo-1-node-5', source: 'combo-1', target: 'node-5' }, + ], + combos: [{ id: 'combo-1' }], + }; + + const getRelatedEdges = (id: ID) => data.edges.filter((edge) => edge.id.includes(id as string)); + + expect(getSubgraphRelatedEdges(['node-1', 'node-2', 'combo-1'], getRelatedEdges)).toEqual({ + edges: [ + { id: 'node-1-node-2', source: 'node-1', target: 'node-2' }, + { id: 'node-1-node-3', source: 'node-1', target: 'node-3' }, + { id: 'node-2-node-4', source: 'node-2', target: 'node-4' }, + { id: 'combo-1-node-5', source: 'combo-1', target: 'node-5' }, + ], + external: [ + { id: 'node-1-node-3', source: 'node-1', target: 'node-3' }, + { id: 'node-2-node-4', source: 'node-2', target: 'node-4' }, + { id: 'combo-1-node-5', source: 'combo-1', target: 'node-5' }, + ], + internal: [{ id: 'node-1-node-2', source: 'node-1', target: 'node-2' }], + }); + + expect(getSubgraphRelatedEdges(['node-3', 'node-5'], getRelatedEdges)).toEqual({ + edges: [ + { id: 'node-1-node-3', source: 'node-1', target: 'node-3' }, + { id: 'node-3-node-5', source: 'node-3', target: 'node-5' }, + { id: 'node-4-node-5', source: 'node-4', target: 'node-5' }, + { id: 'combo-1-node-5', source: 'combo-1', target: 'node-5' }, + ], + external: [ + { id: 'node-1-node-3', source: 'node-1', target: 'node-3' }, + { id: 'node-4-node-5', source: 'node-4', target: 'node-5' }, + { id: 'combo-1-node-5', source: 'combo-1', target: 'node-5' }, + ], + internal: [{ id: 'node-3-node-5', source: 'node-3', target: 'node-5' }], + }); + }); }); diff --git a/packages/g6/__tests__/unit/utils/extension.spec.ts b/packages/g6/__tests__/unit/utils/extension.spec.ts index d717da1c5e2..fa4986da7ed 100644 --- a/packages/g6/__tests__/unit/utils/extension.spec.ts +++ b/packages/g6/__tests__/unit/utils/extension.spec.ts @@ -6,7 +6,7 @@ describe('extension', () => { expect(parseExtensions('behavior', [])).toEqual([]); const options: BehaviorOptions = [ - 'drag-node', + 'drag-element', { type: 'drag-canvas' }, { type: 'shortcut', key: 'shortcut-zoom-in' }, { type: 'shortcut', key: 'shortcut-zoom-out' }, @@ -15,7 +15,7 @@ describe('extension', () => { ]; expect(parseExtensions('behavior', options)).toEqual([ - { type: 'drag-node', key: 'behavior-drag-node-0' }, + { type: 'drag-element', key: 'behavior-drag-element-0' }, { type: 'drag-canvas', key: 'behavior-drag-canvas-0' }, { type: 'shortcut', key: 'shortcut-zoom-in' }, { type: 'shortcut', key: 'shortcut-zoom-out' }, diff --git a/packages/g6/__tests__/unit/utils/position.spec.ts b/packages/g6/__tests__/unit/utils/position.spec.ts index bdefe09c046..40d8eb040d1 100644 --- a/packages/g6/__tests__/unit/utils/position.spec.ts +++ b/packages/g6/__tests__/unit/utils/position.spec.ts @@ -1,4 +1,4 @@ -import { getXYByAnchor, getXYByPlacement, getXYByRelativePlacement } from '@/src/utils/position'; +import { getXYByAnchor, getXYByPlacement, getXYByRelativePlacement, positionOf } from '@/src/utils/position'; import { AABB } from '@antv/g'; describe('position', () => { @@ -29,4 +29,11 @@ describe('position', () => { expect(getXYByAnchor(bbox, [1, 1])).toEqual([100, 100]); expect(getXYByAnchor(bbox, [0.2, 0.2])).toEqual([20, 20]); }); + + it('positionOf', () => { + expect(positionOf({ id: 'node' })).toEqual([0, 0, 0]); + expect(positionOf({ id: 'node', style: { x: 10 } })).toEqual([10, 0, 0]); + expect(positionOf({ id: 'node', style: { x: 10, y: 20 } })).toEqual([10, 20, 0]); + expect(positionOf({ id: 'node', style: { x: 10, y: 20, z: 30 } })).toEqual([10, 20, 30]); + }); }); diff --git a/packages/g6/__tests__/unit/utils/style.spec.ts b/packages/g6/__tests__/unit/utils/style.spec.ts index 9654aa8697b..0b0ac1f05fd 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 } from '@/src/utils/style'; +import { computeElementCallbackStyle, zIndexOf } from '@/src/utils/style'; describe('style', () => { it('computeElementCallbackStyle', () => { @@ -38,4 +38,11 @@ describe('style', () => { fill: 'red', }); }); + + it('zIndexOf', () => { + expect(zIndexOf({ id: 'node-1' })).toBe(0); + expect(zIndexOf({ id: 'node-1', style: {} })).toBe(0); + expect(zIndexOf({ id: 'node-1', style: { zIndex: 1 } })).toBe(1); + expect(zIndexOf({ id: 'node-1', style: { zIndex: -1 } })).toBe(-1); + }); }); diff --git a/packages/g6/__tests__/unit/utils/traverse.spec.ts b/packages/g6/__tests__/unit/utils/traverse.spec.ts index c958f8a26c5..dc89d96f9db 100644 --- a/packages/g6/__tests__/unit/utils/traverse.spec.ts +++ b/packages/g6/__tests__/unit/utils/traverse.spec.ts @@ -39,4 +39,34 @@ describe('traverse', () => { expect(result).toEqual([4, 3, 2, 6, 5, 1]); }); + + it('validate depth TB', () => { + const result: Record = {}; + + dfs( + tree, + (node, depth) => { + result[node.value] = depth; + }, + (node) => node.children, + 'TB', + ); + + expect(result).toEqual({ 1: 0, 2: 1, 3: 2, 4: 3, 5: 1, 6: 2 }); + }); + + it('validate depth BT', () => { + const result: Record = {}; + + dfs( + tree, + (node, depth) => { + result[node.value] = depth; + }, + (node) => node.children, + 'BT', + ); + + expect(result).toEqual({ 1: 0, 2: 1, 3: 2, 4: 3, 5: 1, 6: 2 }); + }); }); diff --git a/packages/g6/src/animations/index.ts b/packages/g6/src/animations/index.ts index b222db415b4..089d1744c01 100644 --- a/packages/g6/src/animations/index.ts +++ b/packages/g6/src/animations/index.ts @@ -15,3 +15,5 @@ export const translate = [ fields: ['x', 'y'], }, ]; + +export const comboCollapseExpand = [{ fields: ['x', 'y'] }, { fields: ['r', 'width', 'height'], shape: 'key' }]; diff --git a/packages/g6/src/behaviors/collapse-expand.ts b/packages/g6/src/behaviors/collapse-expand.ts new file mode 100644 index 00000000000..3d3b0228c2a --- /dev/null +++ b/packages/g6/src/behaviors/collapse-expand.ts @@ -0,0 +1,91 @@ +import type { FederatedMouseEvent } from '@antv/g'; +import type { ID } from '@antv/graphlib'; +import { isFunction } from '@antv/util'; +import { CommonEvent } from '../constants'; +import type { RuntimeContext } from '../runtime/types'; +import { BehaviorEvent } from '../types'; +import type { BaseBehaviorOptions } from './base-behavior'; +import { BaseBehavior } from './base-behavior'; + +export interface CollapseExpandOptions extends BaseBehaviorOptions { + /** + * 是否启用动画 + * + * Whether to enable animation + */ + animation: boolean; + /** + * 是否启用展开/收起功能 + * + * Whether to enable the expand/collapse function + */ + enable?: boolean | ((event: BehaviorEvent) => boolean); + /** + * 完成收起时的回调 + * + * Callback when collapse is completed + */ + oncollapse?: (id: ID) => void; + /** + * 完成展开时的回调 + * + * Callback when expand is completed + */ + onexpand?: (id: ID) => void; +} + +export class CollapseExpand extends BaseBehavior { + static defaultOptions: Partial = { + enable: true, + animation: true, + }; + + constructor(context: RuntimeContext, options: CollapseExpandOptions) { + super(context, Object.assign({}, CollapseExpand.defaultOptions, options)); + + this.bindEvents(); + } + + private bindEvents() { + const { graph } = this.context; + this.unbindEvents(); + + graph.on(`combo:${CommonEvent.DBLCLICK}`, this.onCollapseExpand); + } + + private unbindEvents() { + const { graph } = this.context; + graph.off(`combo:${CommonEvent.DBLCLICK}`, this.onCollapseExpand); + } + + private onCollapseExpand = async (event: BehaviorEvent) => { + if (!this.validate(event)) return; + + const id = event?.target?.id; + const { model, graph } = this.context; + const data = model.getComboData([id])[0]; + if (!data) return false; + + const { oncollapse, onexpand, animation } = this.options; + const isCollapse = data.style?.collapsed; + if (isCollapse) { + await graph.expand(id, animation); + onexpand?.(id); + } else { + await graph.collapse(id, animation); + oncollapse?.(id); + } + }; + + private validate(event: BehaviorEvent): boolean { + if (this.destroyed) return false; + const { enable } = this.options; + if (isFunction(enable)) return enable(event); + return !!enable; + } + + public destroy(): void { + this.unbindEvents(); + super.destroy(); + } +} diff --git a/packages/g6/src/behaviors/drag-node.ts b/packages/g6/src/behaviors/drag-element.ts similarity index 59% rename from packages/g6/src/behaviors/drag-node.ts rename to packages/g6/src/behaviors/drag-element.ts index 871a646b982..2f73f5a41bb 100644 --- a/packages/g6/src/behaviors/drag-node.ts +++ b/packages/g6/src/behaviors/drag-element.ts @@ -2,16 +2,17 @@ import type { BaseStyleProps, FederatedMouseEvent } from '@antv/g'; import { Rect } from '@antv/g'; import { ID } from '@antv/graphlib'; import { isFunction } from '@antv/util'; -import { CommonEvent } from '../constants'; +import { COMBO_KEY, CommonEvent } from '../constants'; import { RuntimeContext } from '../runtime/types'; import type { BehaviorEvent, EdgeDirection, Point, PrefixObject } from '../types'; import { getBBoxSize, getCombinedBBox } from '../utils/bbox'; import { idOf } from '../utils/id'; import { subStyleProps } from '../utils/prefix'; import { subtract } from '../utils/vector'; -import { BaseBehavior, BaseBehaviorOptions } from './base-behavior'; +import type { BaseBehaviorOptions } from './base-behavior'; +import { BaseBehavior } from './base-behavior'; -export interface DragNodeOptions extends BaseBehaviorOptions, PrefixObject { +export interface DragElementOptions extends BaseBehaviorOptions, PrefixObject { /** * 是否启用拖拽动画 * @@ -24,6 +25,28 @@ export interface DragNodeOptions extends BaseBehaviorOptions, PrefixObject Whether to enable the function of dragging the node */ enable?: boolean | ((event: BehaviorEvent | BehaviorEvent) => boolean); + /** + * 支持拖拽的元素类型 + * + * Supported element types for dragging + */ + draggableElement: ('node' | 'combo')[]; + /** + * 拖拽操作效果 + * - link: 将拖拽元素置入为目标元素的子元素 + * - move: 移动元素并更新父元素尺寸 + * - none: 仅更新拖拽目标位置,不做任何额外操作 + * + * Drag operation effect + * - link: Place the drag element as a child element of the target element + * - move: Move the element and update the parent element size + * - none: Only update the drag target position, no additional operations + * @description + * combo 元素可作为元素容器置入 node 或 combo 元素 + * + * The combo element can be placed as an element container into the node or combo element + */ + dropEffect: 'link' | 'move' | 'none'; /** * 节点选中的状态,启用多选时会基于该状态查找选中的节点 * @@ -64,10 +87,12 @@ export interface DragNodeOptions extends BaseBehaviorOptions, PrefixObject void; } -export class DragNode extends BaseBehavior { - static defaultOptions: Partial = { +export class DragElement extends BaseBehavior { + static defaultOptions: Partial = { animation: true, enable: true, + draggableElement: ['node', 'combo'], + dropEffect: 'move', state: 'selected', hideEdges: 'none', shadowZIndex: 100, @@ -93,16 +118,34 @@ export class DragNode extends BaseBehavior { return this.options.animation; } - constructor(context: RuntimeContext, options: DragNodeOptions) { - super(context, Object.assign({}, DragNode.defaultOptions, options)); + private get element() { + return new Set(this.options.draggableElement); + } + + constructor(context: RuntimeContext, options: DragElementOptions) { + super(context, Object.assign({}, DragElement.defaultOptions, options)); + this.bindEvents(); + } + + public update(options: Partial): void { + super.update(options); this.bindEvents(); } private bindEvents() { const { graph } = this.context; - graph.on(`node:${CommonEvent.DRAG_START}`, this.onDragStart); - graph.on(`node:${CommonEvent.DRAG}`, this.onDrag); - graph.on(`node:${CommonEvent.DRAG_END}`, this.onDragEnd); + this.unbindEvents(); + + this.element.forEach((type) => { + graph.on(`${type}:${CommonEvent.DRAG_START}`, this.onDragStart); + graph.on(`${type}:${CommonEvent.DRAG}`, this.onDrag); + graph.on(`${type}:${CommonEvent.DRAG_END}`, this.onDragEnd); + }); + + if (['link'].includes(this.options.dropEffect)) { + graph.on(`combo:${CommonEvent.DROP}`, this.onDrop); + graph.on(`canvas:${CommonEvent.DROP}`, this.onDrop); + } } private getSelectedNodeIDs(currTarget: ID[]) { @@ -122,6 +165,7 @@ export class DragNode extends BaseBehavior { this.target = this.getSelectedNodeIDs([event.target.id]); this.hideEdges(); + this.context.graph.frontElement(this.target); if (this.options.shadow) this.createShadow(this.target); }; @@ -130,7 +174,7 @@ export class DragNode extends BaseBehavior { const { dx, dy } = event; if (this.options.shadow) this.moveShadow([dx, dy]); - else this.moveNode(this.target, [dx, dy]); + else this.moveElement(this.target, [dx, dy]); }; private onDragEnd = () => { @@ -140,22 +184,48 @@ export class DragNode extends BaseBehavior { this.shadow.style.visibility = 'hidden'; const { x = 0, y = 0 } = this.shadow.attributes; const [dx, dy] = subtract([+x, +y], this.shadowOrigin); - this.moveNode(this.target, [dx, dy]); + this.moveElement(this.target, [dx, dy]); } this.showEdges(); this.options.onfinish?.(this.target); this.target = []; }; + private onDrop = async (event: DragEvent) => { + if (this.options.dropEffect !== 'link') return; + const { model, element } = this.context; + const modifiedParentId = event.target.id; + this.target.forEach((id) => { + const originalParent = model.getParentData(id, COMBO_KEY); + // 如果是在原父 combo 内部拖拽,需要刷新 combo 数据 + // If it is a drag and drop within the original parent combo, you need to refresh the combo data + if (originalParent && idOf(originalParent) === modifiedParentId) { + model.refreshComboData(modifiedParentId); + } + model.setParent(id, modifiedParentId, COMBO_KEY); + }); + await element?.draw({ animation: true }); + }; + private validate(event: DragEvent) { if (this.destroyed) return false; + if (!this.element.has(event.targetType)) return false; const { enable } = this.options; if (isFunction(enable)) return enable(event); return !!enable; } - private moveNode(ids: ID[], offset: Point) { - this.context.graph.translateElementBy(Object.fromEntries(ids.map((id) => [id, offset])), this.animation); + private async moveElement(ids: ID[], offset: Point) { + const { model, element } = this.context; + const { dropEffect } = this.options; + ids.forEach((id) => { + const elementType = model.getElementType(id); + if (elementType === 'node') model.translateNodeBy(id, offset); + else if (elementType === 'combo') model.translateComboBy(id, offset); + }); + + if (dropEffect === 'move') ids.forEach((id) => model.refreshComboData(id)); + await element!.draw({ animation: this.animation }); } private moveShadow(offset: Point) { @@ -213,10 +283,21 @@ export class DragNode extends BaseBehavior { graph.hideElement(this.hiddenEdges); } + private unbindEvents() { + const { graph } = this.context; + + this.element.forEach((type) => { + graph.off(`${type}:${CommonEvent.DRAG_START}`, this.onDragStart); + graph.off(`${type}:${CommonEvent.DRAG}`, this.onDrag); + graph.off(`${type}:${CommonEvent.DRAG_END}`, this.onDragEnd); + }); + + graph.off(`combo:${CommonEvent.DROP}`, this.onDrop); + graph.off(`canvas:${CommonEvent.DROP}`, this.onDrop); + } + public destroy() { - this.context.graph.off(`node:${CommonEvent.DRAG_START}`, this.onDragStart); - this.context.graph.off(`node:${CommonEvent.DRAG}`, this.onDrag); - this.context.graph.off(`node:${CommonEvent.DRAG_END}`, this.onDragEnd); + this.unbindEvents(); this.shadow?.destroy(); super.destroy(); } diff --git a/packages/g6/src/behaviors/index.ts b/packages/g6/src/behaviors/index.ts index b06b8abde8c..6aa76d13026 100644 --- a/packages/g6/src/behaviors/index.ts +++ b/packages/g6/src/behaviors/index.ts @@ -1,9 +1,11 @@ export { BaseBehavior } from './base-behavior'; +export { CollapseExpand } from './collapse-expand'; export { DragCanvas } from './drag-canvas'; -export { DragNode } from './drag-node'; +export { DragElement } from './drag-element'; export { ZoomCanvas } from './zoom-canvas'; export type { BaseBehaviorOptions } from './base-behavior'; +export type { CollapseExpandOptions } from './collapse-expand'; export type { DragCanvasOptions } from './drag-canvas'; -export type { DragNodeOptions } from './drag-node'; +export type { DragElementOptions } from './drag-element'; export type { ZoomCanvasOptions } from './zoom-canvas'; diff --git a/packages/g6/src/elements/combos/base-combo.ts b/packages/g6/src/elements/combos/base-combo.ts index 5b61e005b44..76045454e66 100644 --- a/packages/g6/src/elements/combos/base-combo.ts +++ b/packages/g6/src/elements/combos/base-combo.ts @@ -1,11 +1,15 @@ import type { AABB, BaseStyleProps, DisplayObject, DisplayObjectConfig, Group } from '@antv/g'; -import { deepMix, isEmpty } from '@antv/util'; -import type { BaseComboProps, Combo, Node, Position, PrefixObject, STDSize } from '../../types'; +import { deepMix, isEmpty, isFunction } from '@antv/util'; +import { COMBO_KEY } from '../../constants'; +import type { BaseComboProps, NodeLikeData, Position, PrefixObject, STDSize } from '../../types'; import { getBBoxHeight, getBBoxWidth, getCombinedBBox, getExpandedBBox } from '../../utils/bbox'; -import { getCollapsedMarkerText, getXYByCollapsedOrigin } from '../../utils/combo'; -import { getXYByPlacement } from '../../utils/position'; +import { getXYByCollapsedOrigin } from '../../utils/combo'; +import { idOf } from '../../utils/id'; +import { parsePadding } from '../../utils/padding'; +import { getXYByPlacement, positionOf } from '../../utils/position'; import { subStyleProps } from '../../utils/prefix'; import { parseSize } from '../../utils/size'; +import { add, divide } from '../../utils/vector'; import type { BaseNodeStyleProps } from '../nodes'; import { BaseNode } from '../nodes'; import { Icon, IconStyleProps } from '../shapes'; @@ -18,9 +22,9 @@ export type CollapsedMarkerStyleProps = IconStyleProps & { * - 'child-count': Number of child elements * - 'descendant-count': Number of descendant elements (including Nodes and Combos) * - 'node-count': Number of descendant elements (only Nodes) - * - (children: (Node | Combo)[]) => string: Custom function + * - (children: NodeLikeData[]) => string: Custom function */ - type?: 'child-count' | 'descendant-count' | 'node-count' | ((children: (Node | Combo)[]) => string); + type?: 'child-count' | 'descendant-count' | 'node-count' | ((children: NodeLikeData[]) => string); }; export type BaseComboStyleProps = BaseComboProps & PrefixObject & { @@ -34,9 +38,7 @@ export type ParsedBaseComboStyleProps = Re export abstract class BaseCombo extends BaseNode { public type = 'combo'; - static defaultStyleProps: BaseComboStyleProps = { - size: 0, - padding: 0, + static defaultStyleProps: Partial = { childrenNode: [], droppable: true, draggable: true, @@ -44,6 +46,7 @@ export abstract class BaseCombo, container: Group): DisplayObject | undefined; protected calculatePosition(attributes: Required): Position { - const { x: comboX, y: comboY, collapsed } = attributes; - - if (!isEmpty(comboX) && !isEmpty(comboY)) return [comboX, comboY, 0] as Position; + const { x = 0, y = 0, collapsed, childrenNode = [], childrenData = [] } = attributes; + + if (childrenNode.length < childrenData.length) { + if (childrenData.length > 0) { + // combo 被收起,返回平均中心位置 / combo is collapsed, return the average center position + if (collapsed) { + const totalPosition = childrenData.reduce((acc, datum) => add(acc, positionOf(datum)), [0, 0, 0] as Position); + return divide(totalPosition, childrenData.length); + } + } + return [+x, +y, 0]; + } + // empty combo + if (!childrenData.length) return [+x, +y, 0]; return !collapsed ? this.getContentBBox(attributes).center : this.getCollapsedOriginPosition(attributes); } @@ -76,15 +90,17 @@ export abstract class BaseCombo): STDSize { - const { size, collapsed, collapsedSize } = attributes; - - if (collapsed && !isEmpty(collapsedSize)) return parseSize(collapsedSize); - - if (!collapsed && !isEmpty(size)) return parseSize(size); - + const { collapsed, childrenNode = [] } = attributes; + if (childrenNode.length === 0) return this.getEmptyKeySize(attributes); return collapsed ? this.getCollapsedKeySize(attributes) : this.getExpandedKeySize(attributes); } + protected getEmptyKeySize(attributes: Required): STDSize { + const { padding, collapsedSize } = attributes; + const [top, right, bottom, left] = parsePadding(padding); + return add(parseSize(collapsedSize), [left + right, top + bottom, 0]) as STDSize; + } + protected getCollapsedKeySize(attributes: Required): STDSize { return parseSize(attributes.collapsedSize); } @@ -119,20 +135,50 @@ export abstract class BaseCombo): string { + const { context, childrenData = [] } = attributes; + if (!context) return ''; + const { model } = context; + + if (type === 'descendant-count') return model.getDescendantsData(this.id).length.toString(); + if (type === 'child-count') return childrenData.length.toString(); + if (type === 'node-count') + return model + .getDescendantsData(this.id) + .filter((datum) => model.getElementType(idOf(datum)) === 'node') + .length.toString(); + if (isFunction(type)) return type(childrenData); + return ''; + } + + protected getComboZIndex(attributes: Required): number { + const ancestors = attributes.context?.model.getAncestorsData(this.id, COMBO_KEY) || []; + return ancestors.length; + } + + protected getComboStyle(attributes: Required) { + const { zIndex = this.getComboZIndex(attributes) } = attributes; + const [x, y] = this.calculatePosition(attributes); + return { x, y, zIndex }; } public render(attributes: Required, container: Group = this) { super.render(attributes, container); + const comboStyle = this.getComboStyle(attributes); + Object.assign(this.style, comboStyle); - const [x, y] = this.calculatePosition(attributes); - this.style.x = x; - this.style.y = y; + // Sync combo position to model + attributes.context?.model.syncComboDatum({ id: this.id, style: comboStyle }); // collapsed marker this.drawCollapsedMarkerShape(attributes, container); diff --git a/packages/g6/src/elements/combos/rect.ts b/packages/g6/src/elements/combos/rect.ts index 986943ebb0a..22b8c3769e4 100644 --- a/packages/g6/src/elements/combos/rect.ts +++ b/packages/g6/src/elements/combos/rect.ts @@ -11,8 +11,7 @@ type ParsedRectComboStyleProps = ParsedBaseComboStyleProps; type RectComboOptions = DisplayObjectConfig; export class RectCombo extends BaseCombo { - static defaultStyleProps: RectComboStyleProps = { - size: [100, 30], + static defaultStyleProps: Partial = { anchor: [0.5, 0.5], }; diff --git a/packages/g6/src/elements/index.ts b/packages/g6/src/elements/index.ts index 66099e6c925..f4ac019fe3f 100644 --- a/packages/g6/src/elements/index.ts +++ b/packages/g6/src/elements/index.ts @@ -1,3 +1,3 @@ -export { CircleCombo, RectCombo } from './combos'; -export { Cubic, CubicHorizontal, CubicVertical, Line, Polyline, Quadratic } from './edges'; -export { Circle, Diamond, Ellipse, Image, Rect, Star, Triangle } from './nodes'; +export * from './combos'; +export * from './edges'; +export * from './nodes'; diff --git a/packages/g6/src/elements/nodes/base-node.ts b/packages/g6/src/elements/nodes/base-node.ts index 91a512d7a87..af87d2eb538 100644 --- a/packages/g6/src/elements/nodes/base-node.ts +++ b/packages/g6/src/elements/nodes/base-node.ts @@ -56,7 +56,7 @@ export type BaseNodeStyleProps = BaseN export abstract class BaseNode extends BaseShape { public type = 'node'; - static defaultStyleProps: BaseNodeStyleProps = { + static defaultStyleProps: Partial = { x: 0, y: 0, size: 24, diff --git a/packages/g6/src/elements/shapes/base-shape.ts b/packages/g6/src/elements/shapes/base-shape.ts index 9303311e506..00d692d5da4 100644 --- a/packages/g6/src/elements/shapes/base-shape.ts +++ b/packages/g6/src/elements/shapes/base-shape.ts @@ -107,8 +107,8 @@ export abstract class BaseShape extends */ public getGraphicStyle>( attributes: T, - ): Omit { - const { x, y, className, transform, transformOrigin, context, ...style } = attributes; + ): Omit { + const { x, y, className, transform, transformOrigin, context, zIndex, ...style } = attributes; return style; } diff --git a/packages/g6/src/registry/build-in.ts b/packages/g6/src/registry/build-in.ts index bf71f89911a..d12b62c95ec 100644 --- a/packages/g6/src/registry/build-in.ts +++ b/packages/g6/src/registry/build-in.ts @@ -1,5 +1,5 @@ -import { fade, translate } from '../animations'; -import { DragCanvas, DragNode, ZoomCanvas } from '../behaviors'; +import { comboCollapseExpand, fade, translate } from '../animations'; +import { CollapseExpand, DragCanvas, DragElement, ZoomCanvas } from '../behaviors'; import { Circle, CircleCombo, @@ -48,11 +48,13 @@ export const BUILT_IN_EXTENSIONS: ExtensionRegistry = { animation: { fade, translate, + 'combo-collapse-expand': comboCollapseExpand, }, behavior: { 'zoom-canvas': ZoomCanvas, 'drag-canvas': DragCanvas, - 'drag-node': DragNode, + 'drag-element': DragElement, + 'collapse-expand': CollapseExpand, }, combo: { circle: CircleCombo, diff --git a/packages/g6/src/runtime/behavior.ts b/packages/g6/src/runtime/behavior.ts index e00fe93983a..18499123219 100644 --- a/packages/g6/src/runtime/behavior.ts +++ b/packages/g6/src/runtime/behavior.ts @@ -53,12 +53,12 @@ export class BehaviorController extends ExtensionController { - canvas.addEventListener(name, this.forwardCanvasEvents.bind(this)); + canvas.addEventListener(name, this.forwardCanvasEvents); }); } } - private forwardCanvasEvents(event: FederatedPointerEvent | FederatedWheelEvent) { + private forwardCanvasEvents = (event: FederatedPointerEvent | FederatedWheelEvent) => { const target = eventTargetOf(event.target as DisplayObject); if (!target) return; const { graph, canvas } = this.context; @@ -103,7 +103,7 @@ export class BehaviorController extends ExtensionController; @@ -131,10 +135,9 @@ export class DataController { public getNodeData(ids?: ID[]) { return this.model.getAllNodes().reduce((acc, node) => { - const data = node.data; + const data = toG6Data(node); if (this.isCombo(idOf(data))) return acc; - - if (ids === undefined) acc.push(toG6Data(node)); + if (ids === undefined) acc.push(data); else ids.includes(idOf(data)) && acc.push(data); return acc; }, [] as NodeData[]); @@ -142,7 +145,7 @@ export class DataController { public getEdgeData(ids?: ID[]) { return this.model.getAllEdges().reduce((acc, edge) => { - const data = edge.data; + const data = toG6Data(edge); if (ids === undefined) acc.push(data); else ids.includes(idOf(data)) && acc.push(data); return acc; @@ -150,35 +153,59 @@ export class DataController { } public getComboData(ids?: ID[]) { - return this.model.getAllNodes().reduce((acc, node) => { - if (!this.isCombo(idOf(node.data))) return acc; + return this.model.getAllNodes().reduce((acc, combo) => { + const data = toG6Data(combo); + if (!this.isCombo(idOf(data))) return acc; - if (ids === undefined) acc.push(node.data); - else ids.includes(idOf(node.data)) && acc.push(node.data); + if (ids === undefined) acc.push(data); + else ids.includes(idOf(data)) && acc.push(data); return acc; }, [] as ComboData[]); } - public getParentData(id: ID): NodeData | undefined { - if (!this.model.hasTreeStructure(TREE_KEY)) return undefined; - const parent = this.model.getParent(id, TREE_KEY); - return parent?.data; + public getAncestorsData(id: ID, hierarchy: HierarchyKey): NodeLikeData[] { + const { model } = this; + if (!model.hasNode(id) || !model.hasTreeStructure(hierarchy)) return []; + return model.getAncestors(id, hierarchy).map(toG6Data); + } + + public getDescendantsData(id: ID): NodeLikeData[] { + const root = this.getElementsData([id])[0] as NodeLikeData; + const data: NodeLikeData[] = []; + dfs( + root, + (node) => { + if (node !== root) data.push(node); + }, + (node) => this.getChildrenData(idOf(node)), + 'TB', + ); + return data; } - /** - * 获取节点的子节点数据 - * - * Get the child node data - * @param id - 节点 ID | node ID - * @returns 子节点数据 | child node data - * @description - * 仅在树图中有效 - * - * Only valid in tree graph - */ - public getChildrenData(id: ID): NodeData[] { - if (!this.model.hasNode(id)) return []; - return this.model.getChildren(id, TREE_KEY).map((node) => node.data); + public getParentData( + id: ID, + hierarchy: HierarchyKey | undefined = this.inferStructureKey(id), + ): NodeLikeData | undefined { + const { model } = this; + if (!hierarchy) { + console.error('The hierarchy structure key is not specified'); + return undefined; + } + if (!model.hasNode(id) || !model.hasTreeStructure(hierarchy)) return undefined; + const parent = model.getParent(id, hierarchy); + return parent ? toG6Data(parent) : undefined; + } + + public getChildrenData(id: ID): NodeLikeData[] { + const structureKey = this.getElementType(id) === 'node' ? TREE_KEY : COMBO_KEY; + const { model } = this; + if (!model.hasNode(id) || !model.hasTreeStructure(structureKey)) return []; + return model.getChildren(id, structureKey).map(toG6Data); + } + + private inferStructureKey(id: ID) { + if (this.isCombo(id)) return COMBO_KEY; } /** @@ -220,7 +247,7 @@ export class DataController { */ public getNodeLikeData(ids?: ID[]) { return this.model.getAllNodes().reduce((acc, node) => { - const data = node.data; + const data = toG6Data(node); if (ids) ids.includes(idOf(data)) && acc.push(data); else acc.push(data); return acc; @@ -248,23 +275,12 @@ export class DataController { return this.model.hasNode(id) && this.isCombo(id); } - public getComboChildrenData(id: ID): NodeLikeData[] { - if (!this.model.hasNode(id)) return []; - return this.model.getChildren(id, COMBO_KEY).map((node) => node.data); - } - - public getParentComboData(id: ID): ComboData | undefined { - if (!this.model.hasNode(id)) return undefined; - const parent = this.model.getParent(id, COMBO_KEY); - return parent?.data; - } - public getRelatedEdgesData(id: ID, direction: EdgeDirection = 'both') { - return this.model.getRelatedEdges(id, direction).map((edge) => edge.data); + return this.model.getRelatedEdges(id, direction).map(toG6Data) as EdgeData[]; } public getNeighborNodesData(id: ID) { - return this.model.getNeighbors(id).map((node) => node.data); + return this.model.getNeighbors(id).map(toG6Data); } public setData(data: GraphData) { @@ -347,27 +363,39 @@ export class DataController { } protected updateNodeLikeHierarchy(data: NodeLikeData[]) { + if (!this.enableUpdateNodeLikeHierarchy) return; const { model } = this; data.forEach((datum) => { const id = idOf(datum); - const parentId = parentIdOf(datum); - if (parentId !== undefined) { - model.attachTreeStructure(COMBO_KEY); - model.setParent(id, parentId, COMBO_KEY); - } + model.attachTreeStructure(COMBO_KEY); + this.setParent(id, parentIdOf(datum), COMBO_KEY); const children = datum?.style?.children; if (children !== undefined) { model.attachTreeStructure(TREE_KEY); children.forEach((child) => { - model.setParent(child, id, TREE_KEY); + this.setParent(child, id, TREE_KEY); }); } }); } + private enableUpdateNodeLikeHierarchy = true; + + /** + * 执行变更时不要更新节点层次结构 + * + * Do not update the node hierarchy when executing changes + * @param callback - 变更函数 | change function + */ + public preventUpdateNodeLikeHierarchy(callback: () => void) { + this.enableUpdateNodeLikeHierarchy = false; + callback(); + this.enableUpdateNodeLikeHierarchy = true; + } + public updateData(data: PartialGraphData) { const { nodes, edges, combos } = data; this.batch(() => { @@ -379,37 +407,50 @@ export class DataController { public updateNodeData(nodes: PartialNodeLikeData[] = []) { if (!nodes.length) return; - + const { model } = this; this.batch(() => { + const modifiedNodes: NodeData[] = []; nodes.forEach((modifiedNode) => { - const originalNode = this.model.getNode(idOf(modifiedNode)).data; + const id = idOf(modifiedNode); + const originalNode = toG6Data(model.getNode(id)); if (isEqual(originalNode, modifiedNode)) return; const value = mergeElementsData(originalNode, modifiedNode); this.pushChange({ value, original: originalNode, type: ChangeTypeEnum.NodeUpdated }); - this.model.mergeNodeData(idOf(modifiedNode), value); + model.mergeNodeData(id, value); + modifiedNodes.push(value); }); - this.updateNodeLikeHierarchy(nodes); + this.updateNodeLikeHierarchy(modifiedNodes); }); } + public syncNodeDatum(datum: PartialNodeLikeData) { + const { model } = this; + + const id = idOf(datum); + const original = toG6Data(model.getNode(id)); + const value = mergeElementsData(original, datum); + model.mergeNodeData(id, value); + } + public updateEdgeData(edges: PartialEdgeData[] = []) { if (!edges.length) return; - + const { model } = this; this.batch(() => { edges.forEach((modifiedEdge) => { - const originalEdge = this.model.getEdge(idOf(modifiedEdge)).data; + const id = idOf(modifiedEdge); + const originalEdge = toG6Data(model.getEdge(id)); if (isEqual(originalEdge, modifiedEdge)) return; if (modifiedEdge.source && originalEdge.source !== modifiedEdge.source) { - this.model.updateEdgeSource(idOf(modifiedEdge), modifiedEdge.source); + model.updateEdgeSource(id, modifiedEdge.source); } if (modifiedEdge.target && originalEdge.target !== modifiedEdge.target) { - this.model.updateEdgeTarget(idOf(modifiedEdge), modifiedEdge.target); + model.updateEdgeTarget(id, modifiedEdge.target); } const updatedData = mergeElementsData(originalEdge, modifiedEdge); - this.model.mergeEdgeData(idOf(modifiedEdge), updatedData); + model.mergeEdgeData(id, updatedData); this.pushChange({ value: updatedData, original: originalEdge, type: ChangeTypeEnum.EdgeUpdated }); }); }); @@ -419,90 +460,161 @@ export class DataController { if (!combos.length) return; const { model } = this; model.batch(() => { + const modifiedCombos: ComboData[] = []; combos.forEach((modifiedCombo) => { - const modifiedComboId = idOf(modifiedCombo); - const originalCombo = model.getNode(modifiedComboId).data; + const id = idOf(modifiedCombo); + const originalCombo = toG6Data(model.getNode(id)); if (isEqual(originalCombo, modifiedCombo)) return; - // 如果 combo 的位置发生了变化,需要更新其子节点的位置 - // If the position of the combo has changed, the position of its child nodes needs to be updated - if (Object.keys(modifiedCombo.style || {}).some((key) => ['x', 'y', 'z'].includes(key))) { - const { x = 0, y = 0, z = 0 } = modifiedCombo.style || {}; - this.translateComboTo([modifiedComboId], [+x, +y, +z]); - } - const value = mergeElementsData(originalCombo, modifiedCombo); this.pushChange({ value, original: originalCombo, type: ChangeTypeEnum.ComboUpdated }); - model.mergeNodeData(modifiedComboId, value); + model.mergeNodeData(id, value); + modifiedCombos.push(value); }); - this.updateNodeLikeHierarchy(combos); + this.updateNodeLikeHierarchy(modifiedCombos); }); } - public translateComboBy(ids: ID[], delta: Point) { - const [dx = 0, dy = 0, dz = 0] = delta; - if ([dx, dy, dz].some(isNaN) || [dx, dy, dz].every((o) => o === 0)) return; + /** + * 设置节点的父节点 + * + * Set the parent node of the node + * @param id - 节点 ID | node ID + * @param parentId - 父节点 ID | parent node ID + * @param hierarchy - 层次结构类型 | hierarchy type + * @param update - 添加新/旧父节点数据更新记录 | add new/old parent node data update record + */ + public setParent(id: ID, parentId: ID | undefined, hierarchy: HierarchyKey, update: boolean = true) { + if (id === parentId) return; + const originalParentId = parentIdOf(this.getNodeLikeData([id])[0]); + + // Sync data + if (originalParentId !== parentId) { + const modifiedDatum = { id, style: { parentId } }; + if (this.isCombo(id)) this.syncComboDatum(modifiedDatum); + else this.syncNodeDatum(modifiedDatum); + } - const { model } = this; - model.batch(() => { - this.getComboData(ids).forEach((combo) => { - dfs( - combo, - (succeed) => { - const succeedID = idOf(succeed); - const { x = 0, y = 0, z = 0 } = succeed.style || {}; - const value = mergeElementsData(succeed, { - style: { x: +x + dx, y: +y + dy, z: z + dz }, - }); - this.pushChange({ - value, - original: succeed, - type: this.isCombo(succeedID) ? ChangeTypeEnum.ComboUpdated : ChangeTypeEnum.NodeUpdated, - }); - model.mergeNodeData(succeedID, value); - }, - (node) => this.getComboChildrenData(idOf(node)), - 'BT', - ); + this.model.setParent(id, parentId, hierarchy); + + if (update) { + new Set([originalParentId, parentId]).forEach((pId) => { + if (pId !== undefined) this.refreshComboData(pId); }); - }); + } } - public translateComboTo(ids: ID[], point: Point) { - const [x = 0, y = 0, z = 0] = point; - if (point.some(isNaN)) return; + /** + * 刷新 combo 数据 + * + * Refresh combo data + * @param id - combo ID | combo ID + * @description + * 不会更改数据,但会触发数据变更事件 + * + * Will not change the data, but will trigger data change events + */ + public refreshComboData(id: ID) { + const combo = this.getComboData([id])[0]; + const ancestors = this.getAncestorsData(id, COMBO_KEY); + + if (combo) this.pushChange({ value: combo, original: combo, type: ChangeTypeEnum.ComboUpdated }); + + ancestors.forEach((value) => { + this.pushChange({ value: value, original: value, type: ChangeTypeEnum.ComboUpdated }); + }); + } + /** + * 将 combo 数据同步到 model 中 + * + * Synchronize combo data to the model + * @param datum - combo 数据 | combo data + */ + public syncComboDatum(datum: PartialNodeLikeData) { const { model } = this; - model.batch(() => { - this.getComboData(ids).forEach((combo) => { - const { x: comboX = 0, y: comboY = 0, z: comboZ = 0 } = combo.style || {}; - const dx = x - +comboX; - const dy = y - +comboY; - const dz = z - +comboZ; - - dfs( - combo, - (succeed) => { - const succeedID = idOf(succeed); - const { x = 0, y = 0, z = 0 } = succeed.style || {}; - const value = mergeElementsData(succeed, { - style: { x: +x + dx, y: +y + dy, z: +z + dz }, - }); - this.pushChange({ - value, - original: succeed, - type: this.isCombo(succeedID) ? ChangeTypeEnum.ComboUpdated : ChangeTypeEnum.NodeUpdated, - }); - model.mergeNodeData(succeedID, value); - }, - (node) => this.getComboChildrenData(idOf(node)), - 'BT', - ); - }); + + const id = idOf(datum); + const original = toG6Data(model.getNode(id)); + const value = mergeElementsData(original, datum); + model.mergeNodeData(id, value); + } + + public getElementPosition(id: ID): Position { + const datum = this.getElementsData([id])[0] as NodeLikeData; + return positionOf(datum); + } + + public translateNodeBy(id: ID, offset: Position) { + const curr = this.getElementPosition(id); + const position = add(curr, [...offset, 0].slice(0, 3) as Point); + this.translateNodeTo(id, position); + } + + public translateNodeTo(id: ID, position: Position) { + const [x = 0, y = 0, z = 0] = position; + this.preventUpdateNodeLikeHierarchy(() => { + this.updateNodeData([{ id, style: { x, y, z } }]); }); } + public translateComboBy(id: ID, offset: Position) { + const [dx = 0, dy = 0, dz = 0] = offset; + if ([dx, dy, dz].some(isNaN) || [dx, dy, dz].every((o) => o === 0)) return; + const combo = this.getComboData([id])[0]; + if (!combo) return; + dfs( + combo, + (succeed) => { + const succeedID = idOf(succeed); + const [x, y, z] = positionOf(succeed); + const value = mergeElementsData(succeed, { + style: { x: x + dx, y: y + dy, z: z + dz }, + }); + this.pushChange({ + value, + original: succeed, + type: this.isCombo(succeedID) ? ChangeTypeEnum.ComboUpdated : ChangeTypeEnum.NodeUpdated, + }); + this.model.mergeNodeData(succeedID, value); + }, + (node) => this.getChildrenData(idOf(node)), + 'BT', + ); + } + + public translateComboTo(id: ID, position: Position) { + if (position.some(isNaN)) return; + const [tx = 0, ty = 0, tz = 0] = position; + const combo = this.getComboData([id])?.[0]; + if (!combo) return; + + const [comboX, comboY, comboZ] = positionOf(combo); + const dx = tx - comboX; + const dy = ty - comboY; + const dz = tz - comboZ; + + dfs( + combo, + (succeed) => { + const succeedId = idOf(succeed); + const [x, y, z] = positionOf(succeed); + const value = mergeElementsData(succeed, { + style: { x: x + dx, y: y + dy, z: z + dz }, + }); + this.pushChange({ + value, + original: succeed, + type: this.isCombo(succeedId) ? ChangeTypeEnum.ComboUpdated : ChangeTypeEnum.NodeUpdated, + }); + this.model.mergeNodeData(succeedId, value); + }, + (node) => this.getChildrenData(idOf(node)), + 'BT', + ); + } + public removeData(data: DataID) { const { nodes, edges, combos } = data; this.batch(() => { @@ -543,6 +655,7 @@ export class DataController { ids.forEach((id) => { this.pushChange({ value: this.getComboData([id])[0], type: ChangeTypeEnum.ComboRemoved }); this.removeNodeLikeHierarchy(id); + this.comboIds.delete(id); }); this.model.removeNodes(ids); }); @@ -556,20 +669,22 @@ export class DataController { */ protected removeNodeLikeHierarchy(id: ID) { if (this.model.hasTreeStructure(COMBO_KEY)) { + const grandParentId = parentIdOf(this.getNodeLikeData([id])[0]); + // 从父节点的 children 列表中移除 // remove from its parent's children list - this.model.setParent(id, undefined, COMBO_KEY); + // 调用 graphlib.setParent,不需要更新数据 + this.setParent(id, undefined, COMBO_KEY, false); // 将子节点移动到父节点的 children 列表中 // move the children to the grandparent's children list - const [data] = this.getNodeLikeData([id]); this.model.getChildren(id, COMBO_KEY).forEach((child) => { - const childData = child.data; + const childData = toG6Data(child); const childId = idOf(childData); - this.model.setParent(idOf(childData), parentIdOf(data), COMBO_KEY); + this.setParent(idOf(childData), grandParentId, COMBO_KEY, false); const value = mergeElementsData(childData, { id: idOf(childData), - style: { parentId: parentIdOf(data) }, + style: { parentId: grandParentId }, }); this.pushChange({ value, @@ -578,6 +693,8 @@ export class DataController { }); this.model.mergeNodeData(idOf(childData), value); }); + + if (!isUndefined(grandParentId)) this.refreshComboData(grandParentId); } } @@ -599,6 +716,40 @@ export class DataController { throw new Error(`Unknown element type of id: ${id}`); } + /** + * 计算元素置顶后的 zIndex + * + * Calculate the zIndex after the element is placed on top + * @param id - 元素 ID | ID of the element + * @returns zIndex | zIndex + */ + public getFrontZIndex(id: ID) { + const elementType = this.getElementType(id); + let elementsToCompare: NodeLikeData[] = []; + + if (elementType === 'combo') { + const ancestors = [id, ...this.getAncestorsData(id, COMBO_KEY).map(idOf)]; + // 过滤掉以下 combo 不参与 zIndex 计算 + // - 未展开的 combo + // - 当前 combo 及其祖先和后代 + // The following combos do not participate in zIndex calculation + // - collapsed combo + // - current combo and its ancestors and descendants + elementsToCompare = this.getComboData().filter((combo) => { + const comboId = idOf(combo); + const comboAncestors = this.getAncestorsData(comboId, COMBO_KEY); + const comboAncestorIds = comboAncestors.map(idOf); + return ( + !comboAncestors.some((combo) => !!combo.style?.collapsed) && + !ancestors.includes(comboId) && + !comboAncestorIds.includes(comboId) + ); + }); + } else elementsToCompare = this.getNodeData().filter((node) => idOf(node) !== id); + + return Math.max(0, ...elementsToCompare.map(zIndexOf)) + 1; + } + public destroy() { const { model } = this; const nodes = model.getAllNodes(); @@ -611,3 +762,5 @@ export class DataController { delete this.context; } } + +export type HierarchyKey = typeof TREE_KEY | typeof COMBO_KEY; diff --git a/packages/g6/src/runtime/element.ts b/packages/g6/src/runtime/element.ts index dabe24ff986..14a3c1c6835 100644 --- a/packages/g6/src/runtime/element.ts +++ b/packages/g6/src/runtime/element.ts @@ -12,9 +12,6 @@ import type { BaseShape } from '../elements/shapes'; import { getExtension } from '../registry'; import type { ComboData, EdgeData, NodeData } from '../spec'; import type { AnimationStage } from '../spec/element/animation'; -import { ComboStyle } from '../spec/element/combo'; -import type { EdgeStyle } from '../spec/element/edge'; -import type { NodeStyle } from '../spec/element/node'; import type { AnimatableTask, Combo, @@ -24,16 +21,19 @@ import type { ElementDatum, ElementType, Node, + NodeLike, + NodeLikeData, State, StyleIterationContext, } from '../types'; import { executeAnimatableTasks, inferDefaultValue, withAnimationCallbacks } from '../utils/animation'; import { cacheStyle, getCachedStyle, hasCachedStyle } from '../utils/cache'; import { reduceDataChanges } from '../utils/change'; +import { getSubgraphRelatedEdges } from '../utils/edge'; import { updateStyle } from '../utils/element'; import type { BaseEvent } from '../utils/event'; import { AnimateEvent, GraphLifeCycleEvent } from '../utils/event'; -import { idOf, parentIdOf } from '../utils/id'; +import { idOf } from '../utils/id'; import { assignColorByPalette, parsePalette } from '../utils/palette'; import { computeElementCallbackStyle } from '../utils/style'; import type { RuntimeContext } from './types'; @@ -122,11 +122,6 @@ export class ElementController { return { color }; } - public getDataStyle(id: ID): NodeStyle | EdgeStyle | ComboStyle { - const datum = this.context.model.getElementsData([id])?.[0]; - return datum?.style || {}; - } - private defaultStyle: Record> = {}; /** @@ -287,33 +282,20 @@ export class ElementController { * * Only the most basic node instances and connection point position information are provided, and more context information needs to be calculated in the edge element */ - private getEdgeEndsContext(id: ID) { - const { model } = this.context; - - const data = model.getEdgeData([id])?.[0]; - if (!data) return {}; - - const { source, target } = data; + private getEdgeEndsContext(datum: EdgeData) { + const { source, target } = datum; const sourceNode = this.getElement(source); const targetNode = this.getElement(target); - return { - sourceNode, - targetNode, - }; + return { sourceNode, targetNode }; } - private getComboChildren(id: ID) { - const { model } = this.context; - - return model.getComboChildrenData(id).map((datum) => this.getElement(idOf(datum))!); - } - - public getElementComputedStyle(elementType: ElementType, id: ID) { + public getElementComputedStyle(elementType: ElementType, datum: ElementDatum) { + const id = idOf(datum); // 优先级(从低到高) Priority (from low to high): const themeStyle = this.getThemeStyle(elementType); const paletteStyle = this.getPaletteStyle(id); - const dataStyle = this.getDataStyle(id); + const dataStyle = datum.style || {}; const defaultStyle = this.getDefaultStyle(id); const themeStateStyle = this.getThemeStateStyle(elementType, this.getElementState(id)); const stateStyle = this.getStateStyle(id); @@ -321,11 +303,14 @@ export class ElementController { const style = Object.assign({}, themeStyle, paletteStyle, dataStyle, defaultStyle, themeStateStyle, stateStyle); if (elementType === 'edge') { - Object.assign(style, this.getEdgeEndsContext(id)); + Object.assign(style, this.getEdgeEndsContext(datum as EdgeData)); } else if (elementType === 'combo') { - Object.assign(style, { - childrenNode: this.getComboChildren(id), - }); + const childrenData = this.context.model.getChildrenData(id); + const isCollapsed = !!style.collapsed; + const childrenNode = isCollapsed + ? [] + : (childrenData.map((child) => this.getElement(idOf(child))).filter(Boolean) as NodeLike[]); + Object.assign(style, { childrenNode, childrenData }); } if (!style.type) { @@ -413,49 +398,139 @@ export class ElementController { }, }; - const output = [this.updateRelatedEdgeFlow, this.updateRelatedComboFlow].reduce((data, flow) => flow(data), input); - + const flows: Flow[] = [this.updateRelatedEdgeFlow, this.arrangeDrawOrderFlow, this.collapseExpandFlow]; + const output = flows.reduce((data, flow) => flow(data), input); return output; } /** - * 如果更新了节点,需要更新连接的边 - * If the node is updated, the connected edge and the combo it is in need to be updated + * 如果更新了节点 / combo,需要更新连接的边 + * If the node / combo is updated, the connected edge and the combo it is in need to be updated */ private updateRelatedEdgeFlow: Flow = (input) => { const { model } = this.context; const { - update: { nodes, edges }, + update: { nodes, edges, combos }, } = input; - nodes.forEach((_, id) => { + const addRelatedEdges = (_: NodeLikeData, id: ID) => { const relatedEdgesData = model.getRelatedEdgesData(id); relatedEdgesData.forEach((edge) => edges.set(idOf(edge), edge)); + }; + + nodes.forEach(addRelatedEdges); + combos.forEach(addRelatedEdges); + + return input; + }; + + /** + * 调整元素绘制顺序 + * + * Adjust the drawing order of elements + */ + private arrangeDrawOrderFlow: Flow = (input) => { + const { model } = this.context; + + const combosToAdd = input.add.combos; + + const order: [ID, ComboData, number][] = []; + combosToAdd.forEach((combo, id) => { + const ancestors = model.getAncestorsData(id, 'combo'); + const path = ancestors.map((ancestor) => idOf(ancestor)).reverse(); + // combo 的 zIndex 为距离根 combo 的深度 + // The zIndex of the combo is the depth from the root combo + order.push([id, combo, path.length]); }); + input.add.combos = new Map( + order + // 基于 zIndex 降序排序,优先绘制子 combo / Sort based on zIndex in descending order, draw child combo first + .sort(([, , zIndex1], [, , zIndex2]) => zIndex2 - zIndex1) + .map(([id, datum]) => [id, datum]), + ); + return input; }; /** - * 如果操作(新增/更新/移除)了节点或 combo,需要更新相对应的 combo - * If nodes or combos are operated (added/updated/removed), the related combo needs to be updated + * 处理元素的收起和展开 + * + * Process the collapse and expand of elements */ - private updateRelatedComboFlow: Flow = (input) => { - const { add, update, remove } = input; + private collapseExpandFlow: Flow = (input) => { const { model } = this.context; + const { add, update } = input; + /** + * 重新分配绘制任务 + * + * Reassign drawing tasks + */ + const reassignTo = (type: 'add' | 'update' | 'remove', elementType: ElementType, datum: ElementDatum) => { + const typeName = `${elementType}s` as keyof ProcedureData; + Object.entries(input).forEach(([_type, value]) => { + if (type === _type) value[typeName].set(idOf(datum), datum as any); + else value[typeName].delete(idOf(datum)); + }); + }; - const comboIds = [add.nodes, update.nodes, remove.nodes, add.combos, update.combos, remove.combos].reduce( - (acc, data) => { - data.forEach((datum) => { - const parentId = parentIdOf(datum); - if (parentId !== undefined) acc.push(parentId); + // combo 添加和更新的顺序为先子后父,因此采用倒序遍历 + // The order of adding and updating combos is first child and then parent, so reverse traversal is used + const combos = [...input.update.combos.entries(), ...input.add.combos.entries()]; + while (combos.length) { + const [id, combo] = combos.pop()!; + + const isCollapsed = !!combo.style?.collapsed; + if (isCollapsed) { + const descendants = model.getDescendantsData(id); + const descendantIds = descendants.map(idOf); + const { internal, external } = getSubgraphRelatedEdges(descendantIds, (id) => model.getRelatedEdgesData(id)); + + // 移除所有后代元素 / Remove all descendant elements + descendants.forEach((descendant) => { + const descendantId = idOf(descendant); + // 不再处理当前 combo 的后代 combo + // No longer process the descendant combo of the current combo + const comboIndex = combos.findIndex(([id]) => id === descendantId); + if (comboIndex !== -1) combos.splice(comboIndex, 1); + + const elementType = model.getElementType(descendantId); + reassignTo('remove', elementType, descendant); }); - return acc; - }, - [] as ID[], - ); - model.getComboData(comboIds).forEach((combo, index) => update.combos.set(comboIds[index], combo)); + // 如果是内部边/节点 销毁 + // If it is an internal edge/node, destroy it + internal.forEach((edge) => reassignTo('remove', 'edge', edge)); + + // 如果是外部边,连接到收起对象上 + // If it is an external edge, connect to the collapsed object + external.forEach((edge) => { + const id = idOf(edge); + const type = descendantIds.includes(edge.source) ? 'source' : 'target'; + const datum = { ...edge, [type]: idOf(combo) }; + if (add.edges.has(id)) add.edges.set(id, datum); + if (update.edges.has(id)) update.edges.set(id, datum); + }); + } else { + const children = model.getChildrenData(id); + const childrenIds = children.map(idOf); + const { edges } = getSubgraphRelatedEdges(childrenIds, (id) => model.getRelatedEdgesData(id)); + + [...children, ...edges].forEach((descendant) => { + const id = idOf(descendant); + const elementType = model.getElementType(id); + + const element = this.getElement(id); + // 如果节点不存在,则添加到新增列表,如果存在,添加到更新列表 + // If the node does not exist, add it to the new list, if it exists, add it to the update list + if (element) reassignTo('update', elementType, descendant); + else reassignTo('add', elementType, descendant); + + // 继续展开子节点 / Continue to expand child nodes + if (elementType === 'combo') combos.push([id, descendant as ComboData]); + }); + } + } return input; }; @@ -465,7 +540,7 @@ export class ElementController { const id = idOf(datum); const currentShape = this.getElement(id); if (currentShape) return () => null; - const { type, ...style } = this.getElementComputedStyle(elementType, id); + const { type, ...style } = this.getElementComputedStyle(elementType, datum); // get shape constructor const Ctor = getExtension(elementType, type); @@ -490,8 +565,8 @@ export class ElementController { const { nodes, edges, combos } = data; const iteration: [ElementType, Map][] = [ ['node', nodes], - ['edge', edges], ['combo', combos], + ['edge', edges], ]; const tasks: AnimatableTask[] = []; @@ -531,7 +606,7 @@ export class ElementController { const id = idOf(datum); const shape = this.getElement(id); if (!shape) return () => null; - const { type, ...style } = this.getElementComputedStyle(elementType, id); + const { type, ...style } = this.getElementComputedStyle(elementType, datum); // 如果类型不同,需要先销毁原有元素,再创建新元素 // If the type is different, you need to destroy the original element first, and then create a new element @@ -578,15 +653,15 @@ export class ElementController { const { nodes, edges, combos } = data; const iteration: [ElementType, Map][] = [ ['node', nodes], - ['edge', edges], ['combo', combos], + ['edge', edges], ]; - const { animation } = context; + const { animation, stage } = context; const tasks: AnimatableTask[] = []; iteration.forEach(([elementType, elementData]) => { if (elementData.size === 0) return []; - const animator = this.getAnimationExecutor(elementType, context.stage || 'update', animation); + const animator = this.getAnimationExecutor(elementType, stage || 'update', animation); elementData.forEach((datum) => tasks.push(() => this.updateElement(elementType, datum, { ...context, animator })), ); @@ -621,10 +696,11 @@ export class ElementController { ['node', nodes], ]; + const { animation, stage } = context; const tasks: AnimatableTask[] = []; iteration.forEach(([elementType, elementData]) => { if (elementData.size === 0) return []; - const animator = this.getAnimationExecutor(elementType, 'exit'); + const animator = this.getAnimationExecutor(elementType, stage || 'exit', animation); elementData.forEach((datum) => tasks.push(() => this.destroyElement(datum, { ...context, animator }))); }); @@ -641,12 +717,6 @@ export class ElementController { delete this.shapeTypeMap[id]; } - public getElementZIndexRange(elementType: ElementType) { - const childNodes = this.container[elementType].childNodes as DisplayObject[]; - const zIndexes = childNodes.map((node) => node.attributes.zIndex ?? inferDefaultValue('zIndex')).sort(); - return [zIndexes.at(0), zIndexes.at(-1)] as [number, number]; - } - public destroy() { Object.values(this.container).forEach((container) => container.destroy()); this.elementMap = {}; @@ -681,11 +751,11 @@ type DrawContext = { * * In Element Controller, in order to improve query performance, use Map to store data uniformly */ -type ProcedureData = { - nodes: Map; - edges: Map; - combos: Map; -}; +class ProcedureData { + nodes: Map = new Map(); + edges: Map = new Map(); + combos: Map = new Map(); +} type FlowData = { add: ProcedureData; diff --git a/packages/g6/src/runtime/graph.ts b/packages/g6/src/runtime/graph.ts index c25c90383d8..e721cfc1078 100644 --- a/packages/g6/src/runtime/graph.ts +++ b/packages/g6/src/runtime/graph.ts @@ -2,7 +2,7 @@ import EventEmitter from '@antv/event-emitter'; import type { AABB, BaseStyleProps, DataURLOptions } from '@antv/g'; import type { ID } from '@antv/graphlib'; import { debounce, isEqual, isFunction, isNumber, isObject, isString, omit } from '@antv/util'; -import { GraphEvent } from '../constants'; +import { COMBO_KEY, GraphEvent } from '../constants'; import { getExtension } from '../registry'; import type { BehaviorOptions, @@ -37,10 +37,13 @@ import type { } from '../types'; import { sizeOf } from '../utils/dom'; import { ElementStateChangeEvent, GraphLifeCycleEvent, emit } from '../utils/event'; +import { idOf } from '../utils/id'; import { parsePoint, toPointObject } from '../utils/point'; -import { add, subtract } from '../utils/vector'; +import { zIndexOf } from '../utils/style'; +import { subtract } from '../utils/vector'; import { BehaviorController } from './behavior'; import { Canvas } from './canvas'; +import type { HierarchyKey } from './data'; import { DataController } from './data'; import { ElementController } from './element'; import { LayoutController } from './layout'; @@ -244,10 +247,6 @@ export class Graph extends EventEmitter { return this.context.model.getComboData([id])?.[0]; } - public getComboChildrenData(id: ID): NodeLikeData[] { - return this.context.model.getComboChildrenData(id); - } - public setData(data: CallableValue): void { this.context.model.setData(isFunction(data) ? data(this.getData()) : data); } @@ -312,8 +311,43 @@ export class Graph extends EventEmitter { return this.context.model.getNeighborNodesData(id); } - public getParentData(id: ID): NodeData | undefined { - return this.context.model.getParentData(id); + /** + * 获取节点或 combo 的祖先元素数据 + * + * Get the ancestor element data of the node or combo + * @param id - 节点或 combo ID | node or combo ID + * @param hierarchy - 指定树图层级关系还是 combo 层级关系 | specify tree or combo hierarchy relationship + * @returns 祖先元素数据 | ancestor element data + * @description + * 数组中的顺序是从父节点到祖先节点 + * + * The order in the array is from the parent node to the ancestor node + */ + public getAncestorsData(id: ID, hierarchy: HierarchyKey): NodeLikeData[] { + return this.context.model.getAncestorsData(id, hierarchy); + } + + /** + * 获取节点或 combo 的父元素数据 + * + * Get the parent element data of the node or combo + * @param id - 节点或 combo ID | node or combo ID + * @param hierarchy - 指定树图层级关系还是 combo 层级关系 | specify tree or combo hierarchy relationship + * @returns 父元素数据 | parent element data + */ + public getParentData(id: ID, hierarchy: HierarchyKey): NodeLikeData | undefined { + return this.context.model.getParentData(id, hierarchy); + } + + /** + * 获取节点或 combo 的子元素数据 + * + * Get the child element data of the node or combo + * @param id - 节点或 combo ID | node or combo ID + * @returns 子元素数据 | child element data + */ + public getChildrenData(id: ID): NodeLikeData[] { + return this.context.model.getChildrenData(id); } public getElementDataByState(elementType: 'node', state: State): NodeData[]; @@ -624,17 +658,8 @@ export class Graph extends EventEmitter { ? [args1, (args2 as boolean) ?? true] : [{ [args1 as ID]: args2 as Position }, args3]; - const positions = Object.entries(config).reduce( - (acc, [id, offset]) => { - const curr = this.getElementPosition(id); - const next = add(curr, [...offset, 0].slice(0, 3) as Point); - acc[id] = next; - return acc; - }, - {} as Record, - ); - - await this.translateElementTo(positions, animation); + Object.entries(config).forEach(([id, offset]) => this.context.model.translateNodeBy(id, offset)); + await this.context.element!.draw({ animation }); } /** @@ -659,25 +684,16 @@ export class Graph extends EventEmitter { args2?: boolean | Position, args3: boolean = true, ): Promise { - const dataToUpdate: Required = { nodes: [], edges: [], combos: [] }; const [config, animation] = isObject(args1) ? [args1, (args2 as boolean) ?? true] : [{ [args1 as ID]: args2 as Position }, args3]; - Object.entries(config).forEach(([id, [x, y, z = 0]]) => { - const elementType = this.getElementType(id); - dataToUpdate[`${elementType}s`].push({ id, style: { x, y, z } }); - }); - - this.updateData(dataToUpdate); - + Object.entries(config).forEach(([id, position]) => this.context.model.translateNodeTo(id, position)); await this.context.element!.draw({ animation }); } public getElementPosition(id: ID): Position { - const element = this.context.element!.getElement(id)!; - const { x = 0, y = 0, z = 0 } = element.style; - return [x, y, z]; + return this.context.model.getElementPosition(id); } public getElementRenderStyle(id: ID) { @@ -793,9 +809,9 @@ export class Graph extends EventEmitter { dataToUpdate[`${elementType}s`].push({ id, style: { zIndex: value } }); }); - this.updateData(dataToUpdate); - - await this.context.element!.draw(); + const { model, element } = this.context; + model.preventUpdateNodeLikeHierarchy(() => model.updateData(dataToUpdate)); + await element!.draw({ animation: false }); } /** @@ -806,38 +822,25 @@ export class Graph extends EventEmitter { */ public async frontElement(id: ID | ID[]): Promise { const ids = Array.isArray(id) ? id : [id]; + const { model } = this.context; + const config: Record = {}; + + ids.map((_id) => { + const zIndex = model.getFrontZIndex(_id); + const elementType = model.getElementType(_id); + if (elementType === 'combo') { + const ancestor = model.getAncestorsData(_id, COMBO_KEY).at(-1) || this.getComboData(_id); + const combos = [ancestor, ...model.getDescendantsData(idOf(ancestor))].filter((datum) => + model.isCombo(idOf(datum)), + ); + const delta = zIndex - zIndexOf(ancestor); + combos.forEach((combo) => { + config[idOf(combo)] = zIndexOf(combo) + delta; + }); + } else config[_id] = zIndex; + }); - await this.setElementZIndex( - Object.fromEntries( - ids.map((_id) => { - const elementType = this.getElementType(_id); - const [, max] = this.context.element!.getElementZIndexRange(elementType); - const parsedZIndex = max + 1; - return [_id, parsedZIndex]; - }), - ), - ); - } - - /** - * 将元素置于最底层 - * - * Send the element to the back - * @param id - 元素 ID | element ID - */ - public async backElement(id: ID | ID[]): Promise { - const ids = Array.isArray(id) ? id : [id]; - - await this.setElementZIndex( - Object.fromEntries( - ids.map((_id) => { - const elementType = this.getElementType(_id); - const [min] = this.context.element!.getElementZIndexRange(elementType); - const parsedZIndex = min - 1; - return [_id, parsedZIndex]; - }), - ), - ); + await this.setElementZIndex(config); } /** @@ -847,9 +850,8 @@ export class Graph extends EventEmitter { * @param id - 元素 ID | element ID * @returns 元素层级 | element z-index */ - public getElementZIndex(id: ID): BaseStyleProps['zIndex'] { - const element = this.context.element!.getElement(id)!; - return element.style.zIndex ?? 0; + public getElementZIndex(id: ID): number { + return zIndexOf(this.context.model.getElementsData([id])[0]); } /** @@ -906,11 +908,21 @@ export class Graph extends EventEmitter { return this.context.element!.getElement(id)!.getRenderBounds(); } - // TODO - public async collapse(id: ID | ID[], options?: unknown): Promise {} + public async collapse(id: ID, animation: boolean = true): Promise { + this.setElementCollapsibility(id, true); + await this.context.element!.draw({ animation, stage: 'collapse' }); + } - // TODO - public async expand(id: ID | ID[], options?: unknown): Promise {} + public async expand(id: ID, animation: boolean = true): Promise { + this.setElementCollapsibility(id, false); + await this.context.element!.draw({ animation, stage: 'expand' }); + } + + private setElementCollapsibility(id: ID, collapsed: boolean) { + const elementType = this.getElementType(id); + if (elementType === 'node') this.updateNodeData([{ id, style: { collapsed } }]); + else if (elementType === 'combo') this.updateComboData([{ id, style: { collapsed } }]); + } public async toDataURL(options: Partial = {}): Promise { return this.context.canvas!.toDataURL(options); diff --git a/packages/g6/src/spec/element/animation.ts b/packages/g6/src/spec/element/animation.ts index 79ae3ffbf8d..6bdbc2ca0a3 100644 --- a/packages/g6/src/spec/element/animation.ts +++ b/packages/g6/src/spec/element/animation.ts @@ -13,4 +13,4 @@ export type AnimationOptions = * * Animation stage */ -export type AnimationStage = 'enter' | 'update' | 'exit' | 'visibility'; +export type AnimationStage = 'enter' | 'update' | 'exit' | 'visibility' | 'show' | 'hide' | 'collapse' | 'expand'; diff --git a/packages/g6/src/themes/base.ts b/packages/g6/src/themes/base.ts index e89fe669fdf..0e03965019a 100644 --- a/packages/g6/src/themes/base.ts +++ b/packages/g6/src/themes/base.ts @@ -196,7 +196,6 @@ export function create(tokens: ThemeTokens): Theme { lineDash: 0, lineWidth: 1, padding: 10, - size: 0, stroke: comboStroke, }, state: { @@ -228,6 +227,8 @@ export function create(tokens: ThemeTokens): Theme { enter: 'fade', exit: 'fade', visibility: 'fade', + expand: 'combo-collapse-expand', + collapse: 'combo-collapse-expand', update: [{ fields: ['x', 'y'] }, { fields: ['size', 'color', 'stroke'], shape: 'key' }], }, }, diff --git a/packages/g6/src/types/element.ts b/packages/g6/src/types/element.ts index d491f4d39a7..3a8900bb831 100644 --- a/packages/g6/src/types/element.ts +++ b/packages/g6/src/types/element.ts @@ -3,6 +3,7 @@ import type { ID } from '@antv/graphlib'; import type { BaseCombo } from '../elements/combos'; import type { BaseEdge } from '../elements/edges'; import type { BaseNode } from '../elements/nodes'; +import type { RuntimeContext } from '../runtime/types'; import type { ComboOptions, EdgeOptions, NodeData, NodeOptions } from '../spec'; import type { NodeLikeData } from './data'; import type { Padding } from './padding'; @@ -23,7 +24,11 @@ export type NodeLike = Node | Combo; export type Element = Node | Edge | Combo; -export type BaseNodeProps = BaseStyleProps & { +type BaseElementStyleProps = BaseStyleProps & { + context?: RuntimeContext; +}; + +export type BaseNodeProps = BaseElementStyleProps & { /** * x 坐标 * @@ -84,7 +89,7 @@ export type BaseNodeProps = BaseStyleProps & { childrenData?: NodeData[]; }; -export type BaseEdgeProps = BaseStyleProps & +export type BaseEdgeProps = BaseElementStyleProps & Pick< PathStyleProps, 'isBillboard' | 'markerStart' | 'markerStartOffset' | 'markerEnd' | 'markerEndOffset' | 'markerMid' @@ -116,7 +121,7 @@ export type BaseEdgeProps = BaseStyleProps & targetPort?: string; }; -export type BaseComboProps = BaseNodeProps & { +export type BaseComboProps = BaseElementStyleProps & { /** * Combo 展开后的默认大小 * @@ -141,9 +146,13 @@ export type BaseComboProps = BaseNodeProps & { */ childrenNode?: NodeLike[]; /** - * Combo 的子元素数据,可以是节点或者 Combo + * Combo 的子元素数据 + * + * The data of the children of combo + * @description + * 如果 combo 是收起状态,children 可能为空,通过 childrenData 能够获取完整的子元素数据 * - * The data of the children of combo, which can be nodes or combos + * If the combo is collapsed, children may be empty, and the complete child element data can be obtained through childrenData */ childrenData?: NodeLikeData[]; /** diff --git a/packages/g6/src/utils/combo.ts b/packages/g6/src/utils/combo.ts index 4156e4c2765..5cb08ca510d 100644 --- a/packages/g6/src/utils/combo.ts +++ b/packages/g6/src/utils/combo.ts @@ -1,8 +1,5 @@ import { AABB } from '@antv/g'; -import { isFunction } from '@antv/util'; -import type { CollapsedMarkerStyleProps } from '../elements/combos/base-combo'; -import type { BaseComboProps, Combo, Node, Point, Position, Size } from '../types'; -import { isNode } from './element'; +import type { BaseComboProps, Point, Position, Size } from '../types'; import { getXYByAnchor } from './position'; import { parseSize } from './size'; @@ -134,45 +131,3 @@ export function getXYByCollapsedOrigin( ); return getXYByAnchor(expandedBBox, origin); } - -/** - * 获取收起时标记的文本 - * - * Get the text of the collapsed marker - * @param type - 收起时标记类型 | type of the collapsed marker - * @param children - 子元素 | children - * @returns 收起时标记文本 | text of the collapsed marker - */ -export function getCollapsedMarkerText(type: CollapsedMarkerStyleProps['type'], children: (Node | Combo)[]) { - if (type === 'descendant-count') { - return getDescendantCount(children).toString(); - } else if (type === 'child-count') { - return children.length.toString(); - } else if (type === 'node-count') { - return getDescendantCount(children, true).toString(); - } else if (isFunction(type)) { - return type(children); - } - return ''; -} - -/** - * 获取子孙节点数量 - * - * Get the number of descendant nodes - * @param children - 子元素 | children - * @param onlyNode - 是否只统计 Node 类型的子孙节点| Whether to only count the descendant nodes of the Node type - * @returns 子孙节点数量 | number of descendant nodes - */ -export function getDescendantCount(children: (Node | Combo)[], onlyNode = false): number { - let count = 0; - for (const child of children) { - if (!onlyNode || isNode(child)) { - count += 1; - } - if ('childrenNode' in child.attributes) { - count += getDescendantCount(child.attributes.childrenNode as (Node | Combo)[], onlyNode); - } - } - return count; -} diff --git a/packages/g6/src/utils/edge.ts b/packages/g6/src/utils/edge.ts index c281c0ed97d..9fa3d69c282 100644 --- a/packages/g6/src/utils/edge.ts +++ b/packages/g6/src/utils/edge.ts @@ -1,6 +1,8 @@ import type { AABB } from '@antv/g'; +import type { ID } from '@antv/graphlib'; import type { PathArray } from '@antv/util'; import { isEqual, isNumber } from '@antv/util'; +import type { EdgeData } from '../spec'; import type { EdgeKey, EdgeLabelPlacement, @@ -519,3 +521,28 @@ export function getPolylineLoopControlPoints(node: Node, sourcePoint: Point, tar return controlPoints; } + +/** + * 获取子图内的所有边,并按照内部边和外部边分组 + * + * Get all the edges in the subgraph and group them into internal and external edges + * @param ids - 节点 ID 数组 | Node ID array + * @param getRelatedEdges - 获取节点邻边 | Get node edges + * @returns 子图边 | Subgraph edges + */ +export function getSubgraphRelatedEdges(ids: ID[], getRelatedEdges: (id: ID) => EdgeData[]) { + const edges = new Set(); + const internal = new Set(); + const external = new Set(); + + ids.forEach((id) => { + const relatedEdges = getRelatedEdges(id); + relatedEdges.forEach((edge) => { + edges.add(edge); + if (ids.includes(edge.source) && ids.includes(edge.target)) internal.add(edge); + else external.add(edge); + }); + }); + + return { edges: Array.from(edges), internal: Array.from(internal), external: Array.from(external) }; +} diff --git a/packages/g6/src/utils/element.ts b/packages/g6/src/utils/element.ts index 5f89eca767e..3ed9c3ad5fc 100644 --- a/packages/g6/src/utils/element.ts +++ b/packages/g6/src/utils/element.ts @@ -1,10 +1,9 @@ import type { AABB, DisplayObject, TextStyleProps } from '@antv/g'; import { get, isString } from '@antv/util'; -import { BaseEdge } from '../elements/edges/base-edge'; -import { BaseNode } from '../elements/nodes'; +import { BaseCombo, BaseEdge, BaseNode } from '../elements'; import { NodePortStyleProps } from '../elements/nodes/base-node'; import type { TriangleDirection } from '../elements/nodes/triangle'; -import type { Edge, Node, Placement, Point, Position } from '../types'; +import type { Combo, Edge, Node, Placement, Point, Position } from '../types'; import type { LabelPlacement, Port } from '../types/node'; import { getBBoxHeight, getBBoxWidth } from './bbox'; import { isPoint } from './is'; @@ -33,6 +32,17 @@ export function isEdge(shape: DisplayObject): shape is Edge { return shape instanceof BaseEdge; } +/** + * 判断是否是 BaseCombo 的实例 + * + * Judge whether the instance is BaseCombo + * @param shape - 实例 | instance + * @returns 是否是 BaseCombo 的实例 | whether the instance is BaseCombo + */ +export function isCombo(shape: DisplayObject): shape is Combo { + return shape instanceof BaseCombo; +} + /** * 判断两个节点是否相同 * diff --git a/packages/g6/src/utils/event/index.ts b/packages/g6/src/utils/event/index.ts index 3bcfae8e542..98cf9d9afd4 100644 --- a/packages/g6/src/utils/event/index.ts +++ b/packages/g6/src/utils/event/index.ts @@ -2,7 +2,7 @@ import type EventEmitter from '@antv/event-emitter'; import type { DisplayObject } from '@antv/g'; import { Document } from '@antv/g'; import { Target } from '../../types'; -import { isEdge, isNode } from '../element'; +import { isCombo, isEdge, isNode } from '../element'; import type { BaseEvent } from './events'; export * from './events'; @@ -42,8 +42,7 @@ export function eventTargetOf(shape?: DisplayObject | Document): { type: string; // This condition is not applicable to the case where the label and node are rendered separately if (isNode(element)) return { type: 'node', element }; if (isEdge(element)) return { type: 'edge', element }; - // TODO is not combo - // if (isCombo(element)) return { type: 'combo', element }; + if (isCombo(element)) return { type: 'combo', element }; element = element.parentElement as DisplayObject | null; } diff --git a/packages/g6/src/utils/id.ts b/packages/g6/src/utils/id.ts index 3e0d2f9f2f8..32c20cbedc2 100644 --- a/packages/g6/src/utils/id.ts +++ b/packages/g6/src/utils/id.ts @@ -1,3 +1,4 @@ +import type { ID } from '@antv/graphlib'; import { isNumber, isString } from '@antv/util'; import type { ComboData, EdgeData, NodeData } from '../spec'; import { isEdgeData } from './is'; @@ -9,7 +10,7 @@ import { isEdgeData } from './is'; * @param data - 节点/边/Combo 的数据 | data of node/edge/combo * @returns 节点/边/Combo 的 ID | ID of node/edge/combo */ -export function idOf(data: Partial) { +export function idOf(data: Partial): ID { if (isString(data.id) || isNumber(data.id)) return data.id; if (isEdgeData(data)) return `${data.source}-${data.target}`; diff --git a/packages/g6/src/utils/position.ts b/packages/g6/src/utils/position.ts index e6763570d28..ce11706bd2f 100644 --- a/packages/g6/src/utils/position.ts +++ b/packages/g6/src/utils/position.ts @@ -1,8 +1,20 @@ import type { AABB } from '@antv/g'; -import type { Anchor, Placement, Position, RelativePlacement } from '../types'; +import type { Anchor, NodeLikeData, Placement, Position, RelativePlacement } from '../types'; import { parseAnchor } from './anchor'; import { parsePlacement } from './placement'; +/** + * 获取节点/ combo 的位置坐标 + * + * Get the position of node/combo + * @param datum - 节点/ combo 的数据 | data of node/combo + * @returns - 坐标 | position + */ +export function positionOf(datum: NodeLikeData): Position { + const { x = 0, y = 0, z = 0 } = datum.style || {}; + return [+x, +y, +z]; +} + /** * 获取相对位置坐标 * diff --git a/packages/g6/src/utils/style.ts b/packages/g6/src/utils/style.ts index 0a5381ff2a3..87e81deabae 100644 --- a/packages/g6/src/utils/style.ts +++ b/packages/g6/src/utils/style.ts @@ -1,5 +1,6 @@ import { isFunction } from '@antv/util'; import type { CallableObject, ElementDatum, StyleIterationContext } from '../types'; +import { inferDefaultValue } from './animation'; /** * 计算支持回调的动态样式 @@ -24,3 +25,14 @@ export function computeElementCallbackStyle( }), ); } + +/** + * 获取元素的 z-index + * + * Get the z-index of the element + * @param datum - 元素数据 | element data + * @returns z-index | z-index + */ +export function zIndexOf(datum: ElementDatum) { + return datum.style?.zIndex ?? inferDefaultValue('zIndex') ?? 0; +} diff --git a/packages/g6/src/utils/traverse.ts b/packages/g6/src/utils/traverse.ts index cd7b4f32f11..1fdc99d51b1 100644 --- a/packages/g6/src/utils/traverse.ts +++ b/packages/g6/src/utils/traverse.ts @@ -10,22 +10,24 @@ export type HierarchyStructure = T & { * @param visitor - 访问节点函数 | visitor function * @param navigator - 获取子节点函数 | get children function * @param mode - 访问模式,BT: 自底向上访问,TB: 自顶向下访问 | traverse mode, BT: bottom to top, TB: top to bottom + * @param depth - 当前深度 | current depth */ -export function dfs( - node: Node, - visitor: (node: Node) => void, - navigator: (node: Node) => Node[] | undefined, +export function dfs( + node: N, + visitor: (node: N, depth: number) => void, + navigator: (node: N) => N[] | undefined, mode: 'BT' | 'TB', + depth: number = 0, ) { - if (mode === 'TB') visitor(node); + if (mode === 'TB') visitor(node, depth); const children = navigator(node); if (children) { for (const child of children) { - dfs(child, visitor, navigator, mode); + dfs(child, visitor, navigator, mode, depth + 1); } } - if (mode === 'BT') visitor(node); + if (mode === 'BT') visitor(node, depth); } diff --git a/packages/site/examples/item/defaultEdges/demo/polyline.ts b/packages/site/examples/item/defaultEdges/demo/polyline.ts index e8da9eb6e0f..84e1b93fc36 100644 --- a/packages/site/examples/item/defaultEdges/demo/polyline.ts +++ b/packages/site/examples/item/defaultEdges/demo/polyline.ts @@ -24,7 +24,7 @@ const graph = new Graph({ controlPoints: (d) => d.style.controlPoints, }, }, - behaviors: [{ type: 'drag-node' }], + behaviors: [{ type: 'drag-element' }], }); graph.render(); diff --git a/packages/site/examples/item/defaultEdges/demo/polylineOrth.ts b/packages/site/examples/item/defaultEdges/demo/polylineOrth.ts index a82500bb3e5..5e24bb8d2db 100644 --- a/packages/site/examples/item/defaultEdges/demo/polylineOrth.ts +++ b/packages/site/examples/item/defaultEdges/demo/polylineOrth.ts @@ -23,7 +23,7 @@ const graph = new Graph({ router: true, }, }, - behaviors: [{ type: 'drag-node' }], + behaviors: [{ type: 'drag-element' }], }); graph.render(); diff --git a/packages/site/examples/item/defaultEdges/demo/polylineOrthHasCPs.ts b/packages/site/examples/item/defaultEdges/demo/polylineOrthHasCPs.ts index f3ed3b2508c..18eee0b643a 100644 --- a/packages/site/examples/item/defaultEdges/demo/polylineOrthHasCPs.ts +++ b/packages/site/examples/item/defaultEdges/demo/polylineOrthHasCPs.ts @@ -26,7 +26,7 @@ const graph = new Graph({ controlPoints: (d) => d.style.controlPoints, }, }, - behaviors: [{ type: 'drag-node' }], + behaviors: [{ type: 'drag-element' }], }); graph.render(); diff --git a/packages/site/examples/item/label/demo/copyLabel.ts b/packages/site/examples/item/label/demo/copyLabel.ts index 8f21bd375a6..08e30e75d4c 100644 --- a/packages/site/examples/item/label/demo/copyLabel.ts +++ b/packages/site/examples/item/label/demo/copyLabel.ts @@ -30,7 +30,7 @@ const graph = new Graph({ labelBackgroundPointerEvents: 'none', }, }, - behaviors: ['drag-node'], + behaviors: ['drag-element'], }); graph.render(); diff --git a/packages/site/examples/item/label/demo/labelLen.ts b/packages/site/examples/item/label/demo/labelLen.ts index 6f6cbb6ca15..aeb3dd229a6 100644 --- a/packages/site/examples/item/label/demo/labelLen.ts +++ b/packages/site/examples/item/label/demo/labelLen.ts @@ -60,7 +60,7 @@ const graph = new Graph({ labelBackgroundRadius: 4, }, }, - behaviors: ['drag-node'], + behaviors: ['drag-element'], }); graph.render(); diff --git a/packages/site/examples/item/label/demo/labelLen1.ts b/packages/site/examples/item/label/demo/labelLen1.ts index 6b242509408..f329ef3f98f 100644 --- a/packages/site/examples/item/label/demo/labelLen1.ts +++ b/packages/site/examples/item/label/demo/labelLen1.ts @@ -66,7 +66,7 @@ const graph = new Graph({ labelMaxLines: 4, }, }, - behaviors: ['drag-node'], + behaviors: ['drag-element'], }); graph.render(); diff --git a/packages/site/examples/item/labelBg/demo/label-background.ts b/packages/site/examples/item/labelBg/demo/label-background.ts index 0e4276f321f..def7f563899 100644 --- a/packages/site/examples/item/labelBg/demo/label-background.ts +++ b/packages/site/examples/item/labelBg/demo/label-background.ts @@ -69,7 +69,7 @@ const graph = new Graph({ layout: { type: 'force', }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/net/circular/demo/basic.ts b/packages/site/examples/net/circular/demo/basic.ts index e87a6508e1e..e159c275d51 100644 --- a/packages/site/examples/net/circular/demo/basic.ts +++ b/packages/site/examples/net/circular/demo/basic.ts @@ -397,7 +397,7 @@ const graph = new Graph({ stroke: '#5F95FF', }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/net/circular/demo/configurationTranslate.ts b/packages/site/examples/net/circular/demo/configurationTranslate.ts index 10f97e98493..638c58b9af5 100644 --- a/packages/site/examples/net/circular/demo/configurationTranslate.ts +++ b/packages/site/examples/net/circular/demo/configurationTranslate.ts @@ -409,7 +409,7 @@ const graph = new Graph({ }, }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], animation: true, }); graph.render(); diff --git a/packages/site/examples/net/circular/demo/degree.ts b/packages/site/examples/net/circular/demo/degree.ts index b1f9de1bb6b..fb0cc87e352 100644 --- a/packages/site/examples/net/circular/demo/degree.ts +++ b/packages/site/examples/net/circular/demo/degree.ts @@ -399,7 +399,7 @@ const graph = new Graph({ stroke: '#5F95FF', }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/net/circular/demo/division.ts b/packages/site/examples/net/circular/demo/division.ts index 37e74459227..2209be6910c 100644 --- a/packages/site/examples/net/circular/demo/division.ts +++ b/packages/site/examples/net/circular/demo/division.ts @@ -409,7 +409,7 @@ const graph = new Graph({ }, }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/net/circular/demo/spiral.ts b/packages/site/examples/net/circular/demo/spiral.ts index 63f89067a92..26753703fea 100644 --- a/packages/site/examples/net/circular/demo/spiral.ts +++ b/packages/site/examples/net/circular/demo/spiral.ts @@ -408,7 +408,7 @@ const graph = new Graph({ }, }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/net/comboLayout/demo/comboCombined.ts b/packages/site/examples/net/comboLayout/demo/comboCombined.ts index ba44bfdc188..c20e3699749 100644 --- a/packages/site/examples/net/comboLayout/demo/comboCombined.ts +++ b/packages/site/examples/net/comboLayout/demo/comboCombined.ts @@ -558,14 +558,14 @@ const graph = new Graph({ }, edge: { style: (model) => { - const { size, color } = model.data; + const { size, color } = model.data as { size: number; color: string }; return { stroke: color || '#99ADD1', lineWidth: size || 1, }; }, }, - behaviors: ['drag-combo', 'drag-node', 'drag-canvas', 'zoom-canvas'], + behaviors: ['drag-element', 'drag-canvas', 'zoom-canvas'], autoFit: 'view', }); diff --git a/packages/site/examples/net/compactBox/demo/basicCompactBox.ts b/packages/site/examples/net/compactBox/demo/basicCompactBox.ts index d1029925005..f9f1bd3e030 100644 --- a/packages/site/examples/net/compactBox/demo/basicCompactBox.ts +++ b/packages/site/examples/net/compactBox/demo/basicCompactBox.ts @@ -7,7 +7,7 @@ fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/algorithm-category.j container: 'container', autoFit: 'view', data: Utils.treeToGraphData(data), - behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'], node: { style: { labelText: (data) => data.id, diff --git a/packages/site/examples/net/compactBox/demo/compactBoxLeftAlign.ts b/packages/site/examples/net/compactBox/demo/compactBoxLeftAlign.ts index 213029e812b..4d9ecb2808f 100644 --- a/packages/site/examples/net/compactBox/demo/compactBoxLeftAlign.ts +++ b/packages/site/examples/net/compactBox/demo/compactBoxLeftAlign.ts @@ -7,7 +7,7 @@ fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/algorithm-category.j container: 'container', autoFit: 'view', data: Utils.treeToGraphData(data), - behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'], node: { style: { labelText: (data) => data.id, diff --git a/packages/site/examples/net/compactBox/demo/topToBottomCompactBox.ts b/packages/site/examples/net/compactBox/demo/topToBottomCompactBox.ts index bc27475f507..e2934f57414 100644 --- a/packages/site/examples/net/compactBox/demo/topToBottomCompactBox.ts +++ b/packages/site/examples/net/compactBox/demo/topToBottomCompactBox.ts @@ -51,7 +51,7 @@ fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/algorithm-category.j return 20; }, }, - behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'], animation: false, }); diff --git a/packages/site/examples/net/concentricLayout/demo/basicConcentric.ts b/packages/site/examples/net/concentricLayout/demo/basicConcentric.ts index 0c52a2cb657..766d9263d7f 100644 --- a/packages/site/examples/net/concentricLayout/demo/basicConcentric.ts +++ b/packages/site/examples/net/concentricLayout/demo/basicConcentric.ts @@ -26,7 +26,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/8dacf27e-e1bc-4522-b6d3-4b6 stroke: '#E2E2E2', }, }, - behaviors: ['zoom-canvas', 'drag-canvas', 'drag-node'], + behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element'], animation: false, }); diff --git a/packages/site/examples/net/dagreFlow/demo/dagre.ts b/packages/site/examples/net/dagreFlow/demo/dagre.ts index b134a479188..b79245f8639 100644 --- a/packages/site/examples/net/dagreFlow/demo/dagre.ts +++ b/packages/site/examples/net/dagreFlow/demo/dagre.ts @@ -159,7 +159,7 @@ const graph = new Graph({ }, }, autoFit: 'view', - behaviors: ['drag-combo', 'drag-node', 'drag-canvas', 'zoom-canvas'], + behaviors: ['drag-element', 'drag-canvas', 'zoom-canvas'], }); graph.render(); diff --git a/packages/site/examples/net/dagreFlow/demo/dagreCombo.ts b/packages/site/examples/net/dagreFlow/demo/dagreCombo.ts index 6a419021d22..1cf99b7877c 100644 --- a/packages/site/examples/net/dagreFlow/demo/dagreCombo.ts +++ b/packages/site/examples/net/dagreFlow/demo/dagreCombo.ts @@ -188,6 +188,6 @@ const graph = new Graph({ }, }, autoFit: 'view', - behaviors: ['drag-combo', 'drag-node', 'drag-canvas', 'zoom-canvas'], + behaviors: ['drag-element', 'drag-canvas', 'zoom-canvas'], }); graph.render(); diff --git a/packages/site/examples/net/dendrogram/demo/basicDendrogram.ts b/packages/site/examples/net/dendrogram/demo/basicDendrogram.ts index 1d68b2ecadb..1b18bb9844b 100644 --- a/packages/site/examples/net/dendrogram/demo/basicDendrogram.ts +++ b/packages/site/examples/net/dendrogram/demo/basicDendrogram.ts @@ -33,7 +33,7 @@ fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/algorithm-category.j nodeSep: 36, rankSep: 250, }, - behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node', 'collapse-expand-tree'], + behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element', 'collapse-expand-tree'], }); graph.render(); diff --git a/packages/site/examples/net/dendrogram/demo/tbDendrogram.ts b/packages/site/examples/net/dendrogram/demo/tbDendrogram.ts index 6e02641d4ca..8bc0400fcae 100644 --- a/packages/site/examples/net/dendrogram/demo/tbDendrogram.ts +++ b/packages/site/examples/net/dendrogram/demo/tbDendrogram.ts @@ -39,7 +39,7 @@ fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/algorithm-category.j nodeSep: 40, rankSep: 100, }, - behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node', 'collapse-expand-tree'], + behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element', 'collapse-expand-tree'], }); graph.render(); diff --git a/packages/site/examples/net/fruchtermanLayout/demo/basicFruchterman.ts b/packages/site/examples/net/fruchtermanLayout/demo/basicFruchterman.ts index cce6708c8dc..52e1c825f26 100644 --- a/packages/site/examples/net/fruchtermanLayout/demo/basicFruchterman.ts +++ b/packages/site/examples/net/fruchtermanLayout/demo/basicFruchterman.ts @@ -123,7 +123,7 @@ const graph = new Graph({ }, }, animation: true, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanCluster.ts b/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanCluster.ts index 46f571d798b..3b20d6cd1a2 100644 --- a/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanCluster.ts +++ b/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanCluster.ts @@ -128,7 +128,7 @@ const graph = new Graph({ endArrowPath: 'M 0,0 L 4,2 L 4,-2 Z', }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], animation: true, }); diff --git a/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanFix.ts b/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanFix.ts index 8aaac6568ff..ccf6f9b5b40 100644 --- a/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanFix.ts +++ b/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanFix.ts @@ -26,7 +26,7 @@ fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/relations.json') animated: true, maxIteration: 500, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], animation: true, }); diff --git a/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanWebWorker.ts b/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanWebWorker.ts index 009d93341f0..9b67edac2f9 100644 --- a/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanWebWorker.ts +++ b/packages/site/examples/net/fruchtermanLayout/demo/fruchtermanWebWorker.ts @@ -28,7 +28,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/7bacd7d1-4119-4ac1-8be3-4c4 stroke: '#ddd', }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/net/gpuLayout/demo/basicFruchterman.ts b/packages/site/examples/net/gpuLayout/demo/basicFruchterman.ts index b0e27821b85..df156f24d1b 100644 --- a/packages/site/examples/net/gpuLayout/demo/basicFruchterman.ts +++ b/packages/site/examples/net/gpuLayout/demo/basicFruchterman.ts @@ -563,7 +563,7 @@ const graph = new Graph({ speed: 10, maxIteration: 2000, }, - behaviors: ['zoom-canvas', 'drag-canvas', 'drag-node', 'click-select'], + behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element', 'click-select'], }); graph.render(); diff --git a/packages/site/examples/net/gpuLayout/demo/fruchtermanComplexData.ts b/packages/site/examples/net/gpuLayout/demo/fruchtermanComplexData.ts index 18387000079..d9d0a6f18df 100644 --- a/packages/site/examples/net/gpuLayout/demo/fruchtermanComplexData.ts +++ b/packages/site/examples/net/gpuLayout/demo/fruchtermanComplexData.ts @@ -25,7 +25,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/7bacd7d1-4119-4ac1-8be3-4c4 layout: { type: 'fruchterman-gpu', }, - behaviors: ['zoom-canvas', 'drag-canvas', 'drag-node', 'click-select'], + behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element', 'click-select'], }); graph.render(); diff --git a/packages/site/examples/net/gridLayout/demo/grid.ts b/packages/site/examples/net/gridLayout/demo/grid.ts index 4943dc79779..bc050cef3d5 100644 --- a/packages/site/examples/net/gridLayout/demo/grid.ts +++ b/packages/site/examples/net/gridLayout/demo/grid.ts @@ -625,7 +625,7 @@ const graph = new Graph({ color: 'antv', }, }, - behaviors: ['zoom-canvas', 'drag-canvas', 'drag-node', 'click-select'], + behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element', 'click-select'], animation: true, }); diff --git a/packages/site/examples/net/mdsLayout/demo/basicMDS.ts b/packages/site/examples/net/mdsLayout/demo/basicMDS.ts index a3d0fc0effb..9e3d3cc8f60 100644 --- a/packages/site/examples/net/mdsLayout/demo/basicMDS.ts +++ b/packages/site/examples/net/mdsLayout/demo/basicMDS.ts @@ -592,7 +592,7 @@ const graph = new Graph({ labelBackground: false, }, }, - behaviors: ['drag-node', 'drag-canvas', 'zoom-canvas', 'click-select'], + behaviors: ['drag-element', 'drag-canvas', 'zoom-canvas', 'click-select'], animation: true, }); diff --git a/packages/site/examples/net/radialLayout/demo/basic.ts b/packages/site/examples/net/radialLayout/demo/basic.ts index 4d739b03970..f4e2b84d98f 100644 --- a/packages/site/examples/net/radialLayout/demo/basic.ts +++ b/packages/site/examples/net/radialLayout/demo/basic.ts @@ -400,7 +400,7 @@ const graph = new Graph({ stroke: '#5F95FF', }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/net/radialLayout/demo/configurationTranslate.ts b/packages/site/examples/net/radialLayout/demo/configurationTranslate.ts index 6ffb9b51fa5..ef424a32b9a 100644 --- a/packages/site/examples/net/radialLayout/demo/configurationTranslate.ts +++ b/packages/site/examples/net/radialLayout/demo/configurationTranslate.ts @@ -412,7 +412,7 @@ const graph = new Graph({ }, }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], animation: true, }); graph.render(); diff --git a/packages/site/examples/net/radialLayout/demo/preventOverlap.ts b/packages/site/examples/net/radialLayout/demo/preventOverlap.ts index e27c32a59a4..59f8ceb0e1c 100644 --- a/packages/site/examples/net/radialLayout/demo/preventOverlap.ts +++ b/packages/site/examples/net/radialLayout/demo/preventOverlap.ts @@ -410,7 +410,7 @@ const graph = new Graph({ }, }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/net/radialLayout/demo/preventOverlapUnstrict.ts b/packages/site/examples/net/radialLayout/demo/preventOverlapUnstrict.ts index cf3c5067d61..040ec16ff9f 100644 --- a/packages/site/examples/net/radialLayout/demo/preventOverlapUnstrict.ts +++ b/packages/site/examples/net/radialLayout/demo/preventOverlapUnstrict.ts @@ -410,7 +410,7 @@ const graph = new Graph({ }, }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/net/radialLayout/demo/sort.ts b/packages/site/examples/net/radialLayout/demo/sort.ts index 1bc67251b95..f54b3790d13 100644 --- a/packages/site/examples/net/radialLayout/demo/sort.ts +++ b/packages/site/examples/net/radialLayout/demo/sort.ts @@ -460,7 +460,7 @@ const graph = new Graph({ }, }, }, - behaviors: ['drag-canvas', 'drag-node'], + behaviors: ['drag-canvas', 'drag-element'], }); graph.render(); diff --git a/packages/site/examples/performance/perf/demo/eva.ts b/packages/site/examples/performance/perf/demo/eva.ts index 3b1d290ba42..228bcdb03e9 100644 --- a/packages/site/examples/performance/perf/demo/eva.ts +++ b/packages/site/examples/performance/perf/demo/eva.ts @@ -1,4 +1,4 @@ -import { Graph, Extensions, extend } from '@antv/g6'; +import { Extensions, Graph, extend } from '@antv/g6'; import Stats from 'stats.js'; const dataFormat = (dataAUR, options = {}, graphCore) => { @@ -84,7 +84,7 @@ const graph = new ExtGraph({ }, { type: 'drag-canvas', enableOptimize: true }, 'activate-relations', - 'drag-node', + 'drag-element', ], }, node: (model) => { diff --git a/packages/site/examples/performance/perf/demo/evaWebGL.ts b/packages/site/examples/performance/perf/demo/evaWebGL.ts index 7c228739e83..da5a5843878 100644 --- a/packages/site/examples/performance/perf/demo/evaWebGL.ts +++ b/packages/site/examples/performance/perf/demo/evaWebGL.ts @@ -1,4 +1,4 @@ -import { Graph, Extensions, extend } from '@antv/g6'; +import { Extensions, Graph, extend } from '@antv/g6'; import Stats from 'stats.js'; const dataFormat = (dataAUR, options = {}, graphCore) => { @@ -76,7 +76,7 @@ const graph = new ExtGraph({ }, ], modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, node: (model) => { const { id, data } = model; diff --git a/packages/site/examples/performance/perf/demo/netscience.ts b/packages/site/examples/performance/perf/demo/netscience.ts index 5ce303d86c2..7a8fd8d3b38 100644 --- a/packages/site/examples/performance/perf/demo/netscience.ts +++ b/packages/site/examples/performance/perf/demo/netscience.ts @@ -1,4 +1,4 @@ -import { Graph, Extensions, extend } from '@antv/g6'; +import { Extensions, Graph, extend } from '@antv/g6'; import Stats from 'stats.js'; const ExtGraph = extend(Graph, { @@ -20,7 +20,7 @@ const graph = new ExtGraph({ width, height, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, node: { keyShape: { diff --git a/packages/site/examples/performance/perf/demo/netscienceWebGL.ts b/packages/site/examples/performance/perf/demo/netscienceWebGL.ts index 986d8f32d01..63166a26e12 100644 --- a/packages/site/examples/performance/perf/demo/netscienceWebGL.ts +++ b/packages/site/examples/performance/perf/demo/netscienceWebGL.ts @@ -1,4 +1,4 @@ -import { Graph, Extensions, extend } from '@antv/g6'; +import { Extensions, Graph, extend } from '@antv/g6'; import Stats from 'stats.js'; const ExtGraph = extend(Graph, { @@ -21,7 +21,7 @@ const graph = new ExtGraph({ height, renderer: 'webgl', modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, node: { keyShape: { diff --git a/packages/site/examples/tool/contextMenu/demo/contextMenu.ts b/packages/site/examples/tool/contextMenu/demo/contextMenu.ts index a94e1ed1971..53d052758c5 100644 --- a/packages/site/examples/tool/contextMenu/demo/contextMenu.ts +++ b/packages/site/examples/tool/contextMenu/demo/contextMenu.ts @@ -17,7 +17,7 @@ const graph = new Graph({ height, data, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, }); @@ -25,7 +25,10 @@ const contextMenu = { type: 'menu', key: 'my-context-menu', trigger: 'contextmenu', - /** async string menu */ + /** + * async string menu + * @param e + */ getContent: (e) => { return `
    diff --git a/packages/site/examples/tool/grid/demo/default.ts b/packages/site/examples/tool/grid/demo/default.ts index 410f4d71b30..22d742d8021 100644 --- a/packages/site/examples/tool/grid/demo/default.ts +++ b/packages/site/examples/tool/grid/demo/default.ts @@ -17,7 +17,7 @@ const graph = new Graph({ height, data, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, plugins: [ { @@ -28,4 +28,4 @@ const graph = new Graph({ ], }); -window.graph = graph; \ No newline at end of file +window.graph = graph; diff --git a/packages/site/examples/tool/legend/demo/legend.ts b/packages/site/examples/tool/legend/demo/legend.ts index 264967a08b4..8800ae06e03 100644 --- a/packages/site/examples/tool/legend/demo/legend.ts +++ b/packages/site/examples/tool/legend/demo/legend.ts @@ -162,6 +162,6 @@ new Graph({ }, }, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, }); diff --git a/packages/site/examples/tool/legend/demo/legendCustomMarker.ts b/packages/site/examples/tool/legend/demo/legendCustomMarker.ts index 442f07c1c00..412cae61e3b 100644 --- a/packages/site/examples/tool/legend/demo/legendCustomMarker.ts +++ b/packages/site/examples/tool/legend/demo/legendCustomMarker.ts @@ -172,6 +172,6 @@ new Graph({ }, }, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, }); diff --git a/packages/site/examples/tool/legend/demo/legendSVG.ts b/packages/site/examples/tool/legend/demo/legendSVG.ts index 3227a1d528a..2c1d2b94e0f 100644 --- a/packages/site/examples/tool/legend/demo/legendSVG.ts +++ b/packages/site/examples/tool/legend/demo/legendSVG.ts @@ -163,6 +163,6 @@ new Graph({ }, }, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, }); diff --git a/packages/site/examples/tool/minimap/demo/minimap-api.ts b/packages/site/examples/tool/minimap/demo/minimap-api.ts index 2399b447540..f553f83b5ab 100644 --- a/packages/site/examples/tool/minimap/demo/minimap-api.ts +++ b/packages/site/examples/tool/minimap/demo/minimap-api.ts @@ -22,7 +22,7 @@ const graph = new Graph({ type: 'force', }, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, }); diff --git a/packages/site/examples/tool/minimap/demo/minimap.ts b/packages/site/examples/tool/minimap/demo/minimap.ts index cc6362d99b0..36a2b57a549 100644 --- a/packages/site/examples/tool/minimap/demo/minimap.ts +++ b/packages/site/examples/tool/minimap/demo/minimap.ts @@ -55,7 +55,7 @@ new Graph({ }, }, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, plugins: [minimap1, minimap2, minimap3], }); diff --git a/packages/site/examples/tool/overview/demo/default.ts b/packages/site/examples/tool/overview/demo/default.ts index 35546f1f79a..86a6d436344 100644 --- a/packages/site/examples/tool/overview/demo/default.ts +++ b/packages/site/examples/tool/overview/demo/default.ts @@ -23,7 +23,7 @@ new Graph({ height, data, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, plugins: [ 'toolbar', diff --git a/packages/site/examples/tool/snapline/demo/snapline.ts b/packages/site/examples/tool/snapline/demo/snapline.ts index 1c6c89909c6..d7648d25338 100644 --- a/packages/site/examples/tool/snapline/demo/snapline.ts +++ b/packages/site/examples/tool/snapline/demo/snapline.ts @@ -27,8 +27,8 @@ new Graph({ 'zoom-canvas', 'drag-canvas', { - type: 'drag-node', - // TODO: snapline with drag-node enableTransient: true (default) has bug now, use enableTransient: false instead temporary + type: 'drag-element', + // TODO: snapline with drag-element enableTransient: true (default) has bug now, use enableTransient: false instead temporary enableTransient: false, }, ], diff --git a/packages/site/examples/tool/timebar/demo/timebar-chart.ts b/packages/site/examples/tool/timebar/demo/timebar-chart.ts index 658738daf29..bb1832a75fc 100644 --- a/packages/site/examples/tool/timebar/demo/timebar-chart.ts +++ b/packages/site/examples/tool/timebar/demo/timebar-chart.ts @@ -1,4 +1,4 @@ -import { Graph as BaseGraph, Extensions, Util, extend } from '@antv/g6'; +import { Graph as BaseGraph, Extensions, extend } from '@antv/g6'; const Graph = extend(BaseGraph, { plugins: { @@ -43,7 +43,7 @@ new Graph({ height, data: graphData, modes: { - default: ['drag-canvas', 'drag-node', 'zoom-canvas'], + default: ['drag-canvas', 'drag-element', 'zoom-canvas'], }, plugins: [ { diff --git a/packages/site/examples/tool/timebar/demo/timebar-time.ts b/packages/site/examples/tool/timebar/demo/timebar-time.ts index 3efd26f4404..f43f92a76c2 100644 --- a/packages/site/examples/tool/timebar/demo/timebar-time.ts +++ b/packages/site/examples/tool/timebar/demo/timebar-time.ts @@ -1,4 +1,4 @@ -import { Graph as BaseGraph, Extensions, Util, extend } from '@antv/g6'; +import { Graph as BaseGraph, Extensions, extend } from '@antv/g6'; const Graph = extend(BaseGraph, { plugins: { @@ -43,7 +43,7 @@ new Graph({ height, data: graphData, modes: { - default: ['drag-canvas', 'drag-node', 'zoom-canvas'], + default: ['drag-canvas', 'drag-element', 'zoom-canvas'], }, plugins: [ { diff --git a/packages/site/examples/tool/toolbar/demo/self-toolbar.ts b/packages/site/examples/tool/toolbar/demo/self-toolbar.ts index f2d34af7b18..e5bbe0f7cc7 100644 --- a/packages/site/examples/tool/toolbar/demo/self-toolbar.ts +++ b/packages/site/examples/tool/toolbar/demo/self-toolbar.ts @@ -20,7 +20,7 @@ const graph = new Graph({ type: 'grid', }, modes: { - default: ['drag-canvas', 'drag-node', 'zoom-canvas'], + default: ['drag-canvas', 'drag-element', 'zoom-canvas'], }, node: { labelShape: { diff --git a/packages/site/examples/tool/toolbar/demo/toolbar.ts b/packages/site/examples/tool/toolbar/demo/toolbar.ts index ffcab1bb886..2623b8a1a8c 100644 --- a/packages/site/examples/tool/toolbar/demo/toolbar.ts +++ b/packages/site/examples/tool/toolbar/demo/toolbar.ts @@ -21,7 +21,7 @@ new Graph({ data, layout, modes: { - default: ['drag-canvas', 'drag-node', 'zoom-canvas'], + default: ['drag-canvas', 'drag-element', 'zoom-canvas'], }, plugins: [{ type: 'toolbar', key: 'toolbar-1' }], }); diff --git a/packages/site/examples/tool/tooltip/demo/tooltipClick.ts b/packages/site/examples/tool/tooltip/demo/tooltipClick.ts index b6b77e9041a..f18cd148823 100644 --- a/packages/site/examples/tool/tooltip/demo/tooltipClick.ts +++ b/packages/site/examples/tool/tooltip/demo/tooltipClick.ts @@ -18,7 +18,7 @@ const graph = new Graph({ height, data, modes: { - default: ['drag-node'], + default: ['drag-element'], }, }); diff --git a/packages/site/examples/tool/tooltip/demo/tooltipPlugin.ts b/packages/site/examples/tool/tooltip/demo/tooltipPlugin.ts index 509d557c9c6..bb4768a5c94 100644 --- a/packages/site/examples/tool/tooltip/demo/tooltipPlugin.ts +++ b/packages/site/examples/tool/tooltip/demo/tooltipPlugin.ts @@ -16,7 +16,7 @@ const graph = new Graph({ height, data, modes: { - default: ['drag-node'], + default: ['drag-element'], }, }); diff --git a/packages/site/examples/tool/watermarker/demo/imgWaterMarker.ts b/packages/site/examples/tool/watermarker/demo/imgWaterMarker.ts index 6f7c8f8480e..3955cd4da82 100644 --- a/packages/site/examples/tool/watermarker/demo/imgWaterMarker.ts +++ b/packages/site/examples/tool/watermarker/demo/imgWaterMarker.ts @@ -17,7 +17,7 @@ const graph = new Graph({ height, data, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, plugins: [ { @@ -34,4 +34,4 @@ const graph = new Graph({ ], }); -window.graph = graph; \ No newline at end of file +window.graph = graph; diff --git a/packages/site/examples/tool/watermarker/demo/textWaterMarker.ts b/packages/site/examples/tool/watermarker/demo/textWaterMarker.ts index 7d52bb2dac2..7d1e5e4c8c5 100644 --- a/packages/site/examples/tool/watermarker/demo/textWaterMarker.ts +++ b/packages/site/examples/tool/watermarker/demo/textWaterMarker.ts @@ -17,7 +17,7 @@ const graph = new Graph({ height, data, modes: { - default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-node'], + default: ['brush-select', 'zoom-canvas', 'activate-relations', 'drag-canvas', 'drag-element'], }, plugins: [ { @@ -39,4 +39,4 @@ const graph = new Graph({ ], }); -window.graph = graph; \ No newline at end of file +window.graph = graph;