Loading...
We can implement groups through parent-child combinations and provide a series of methods to get and set these relationships.
From the example above, we can see that:
Sometimes we need to drag one node into another node to make it a child of the other node. In this case, we can enable the embedding option, which allows us to specify a method through findParent to return the parent node when the node is moved. For more detailed configuration, refer to the API.
At times, we need to limit the movement range of child nodes within the parent node. This can be achieved by using the translating.restrict option when creating the Graph instance.
By listening to the node:change:position event, we can automatically expand or shrink the size of the parent node when the child node moves, ensuring that the parent node completely encompasses the child nodes. The code here is a bit complex; you can click the CodeSandbox link below the demo to view the detailed code.
First, we define a custom Group node, which renders an expand/collapse button in 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, we listen for the node:collapse event on the graph, showing or hiding the corresponding child nodes when the parent node is expanded or 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()}})})