Loading...
Custom behavior allows users to define one or more related interaction behaviors as a complete interaction based on the comprehensive event mechanism provided by G6, thereby achieving interaction logic that fits business scenarios.
Typically:
Listen for user interaction events
Update the canvas or perform other operations based on the events
For example, the DragCanvas
behavior listens for pointer drag events and updates the camera position based on the drag distance.
Due to conceptual distinctions, behavior instances cannot be obtained, while plugin instances can be obtained (getPluginInstance).
Purpose:
When users need to implement interaction logic that fits business scenarios, we usually need to cooperate with G6's event system to respond to related events and execute the required interaction logic.
Without Custom Behavior:
If custom behavior is not used, users need to perform a series of event listening and response processing through graph.on
after creating a Graph instance, making code logic processing and orchestration extremely difficult.
Advantages of Behavior:
Each behavior is an independent code module, and the existence of the behavior system facilitates users to decouple business logic, avoid code bloat, and facilitate subsequent maintenance.
Conclusion:
- When users need to implement any interaction logic, they should first consider custom behavior.
- When built-in behavior cannot fully meet business needs, users can also adjust and modify through custom behavior (inheriting built-in behavior).
(If the features supported by built-in behavior are more general, or if there are bugs in built-in behavior, you are welcome to submit issues or PRs on Github)
The implementation of a behavior is quite flexible, and you can implement your behavior in your preferred style.
Below is a simple custom behavior implementation. When the user clicks on the canvas, a node is added to the canvas (the fill color of the added node can be defined through behavior configuration):
import type { BaseBehaviorOptions, RuntimeContext, IPointerEvent } from '@antv/g6';import { BaseBehavior, CanvasEvent } from '@antv/g6';interface ClickAddNodeOptions extends BaseBehaviorOptions {fill: string;}export class ClickAddNode extends BaseBehavior<ClickAddNodeOptions> {static defaultOptions: Partial<ClickAddNodeOptions> = {fill: 'red',};constructor(context: RuntimeContext, options: ClickAddNodeOptions) {super(context, Object.assign({}, ClickAddNode.defaultOptions, options));this.bindEvents();}private bindEvents() {const { graph } = this.context;graph.on(CanvasEvent.CLICK, this.addNode);}private addNode = (event: IPointerEvent) => {const { graph } = this.context;const { layerX, layerY } = event.nativeEvent as PointerEvent;graph.addNodeData([{id: 'node-' + Date.now(),style: { x: layerX, y: layerY, fill: this.options.fill },},]);graph.draw();};private unbindEvents() {const { graph } = this.context;graph.off(CanvasEvent.CLICK, this.addNode);}public destroy() {// Unbind events when destroyedthis.unbindEvents();super.destroy();}}
ClickAddNode
behavior, which adds an event listener to the Graph in the constructor. When the user clicks on the canvas, a node is added at the click position, and the fill color of the added node can be configured.BaseBehavior
is the base class for all behaviors, and each custom behavior needs to inherit this base class.Click on the blank area of the canvas below to add a node, and switch the right panel to configure the node color.
(async () => {const { BaseBehavior, CanvasEvent, register, ExtensionCategory, Graph } = window.g6;class ClickAddNode extends BaseBehavior {constructor(context, options) {super(context, options);const { graph } = this.context;graph.on(CanvasEvent.CLICK, (event) => {const { layerX, layerY } = event.nativeEvent;graph.addNodeData([{id: 'node-' + Date.now(),style: { x: layerX, y: layerY, fill: options.fill },},]);graph.draw();});}}register(ExtensionCategory.BEHAVIOR, 'click-add-node', ClickAddNode);const wrapEl = await createGraph({data: {nodes: [],},behaviors: [{type: 'click-add-node',key: 'click-add-node',fill: 'red',},],},{ width: 600, height: 300 },(gui, graph) => {const options = {key: 'click-add-node',type: 'click-add-node',fill: 'red',};const optionFolder = gui.addFolder('ClickAddNode Options');optionFolder.add(options, 'fill', ['red','black','blue','green','yellow','purple',]);optionFolder.onChange(({ property, value }) => {graph.updateBehavior({key: 'click-add-node',[property]: value,});graph.render();});},);return wrapEl;})();
The above example is the simplest behavior implementation. In actual development, you may also need to handle logic such as enabling and disabling behaviors.
In addition, there may be event conflicts between multiple behaviors, and you need to handle these conflicts carefully.
Register through the register method provided by G6
import { ExtensionCategory, register } from '@antv/g6';import { ClickAddNode } from 'your-custom-behavior-path';register(ExtensionCategory.BEHAVIOR, 'click-add-node', ClickAddNode);
You can pass in the behavior type name or configuration parameter object in behaviors
, such as the above ClickAddNode. See Configuring Behavior for details.
const graph = new Graph({// Other configurationsbehaviors: [{type: 'click-add-node',fill: 'blue',},],});