Loading...
You can build groups via parent–child relationships, with methods to get and set them.
From the example above:
Sometimes you need to drag one node into another to make it a child. Enable embedding and implement findParent to return the parent on move. See the API for details.
Limit the movement range of child nodes within the parent by using the translating.restrict option when creating the Graph instance.
Listen to node:change:position to automatically expand/shrink the parent when a child moves, ensuring it fully encompasses the children. The example code is a bit involved; click the demo’s CodeSandbox link to view the full implementation.
First, define a custom Group node that renders an expand/collapse button at the top-left corner and sets a custom event node:collapse on that button:
import { Node } from '@antv/x6'export class Group extends Node {private collapsed: boolean = falseprivate expandSize: { width: number; height: number }protected postprocess() {this.toggleCollapse(false)}isCollapsed() {return this.collapsed}toggleCollapse(collapsed?: boolean) {const target = collapsed == null ? !this.collapsed : collapsedif (target) {this.attr('buttonSign', { d: 'M 1 5 9 5 M 5 1 5 9' })this.expandSize = this.getSize()this.resize(100, 32)} else {this.attr('buttonSign', { d: 'M 2 5 8 5' })if (this.expandSize) {this.resize(this.expandSize.width, this.expandSize.height)}}this.collapsed = target}}Group.config({markup: [{tagName: 'rect',selector: 'body',},{tagName: 'text',selector: 'label',},{tagName: 'g',selector: 'buttonGroup',children: [{tagName: 'rect',selector: 'button',},{tagName: 'path',selector: 'buttonSign',},],},],attrs: {body: { ... },label: { ... },buttonGroup: { ... },button: {...// Custom eventevent: 'node:collapse',},buttonSign: { ... },},})
Then listen for node:collapse on the graph, and show/hide the corresponding child nodes when the parent node is expanded/collapsed:
graph.on('node:collapse', ({ node }: { node: Group }) => {node.toggleCollapse()const collapsed = node.isCollapsed()const cells = node.getDescendants()cells.forEach((node) => {if (collapsed) {node.hide()} else {node.show()}})})