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()}})})