or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

behaviors.mddata-management.mdelements.mdevents.mdgraph-runtime.mdindex.mdlayouts.mdplugins.mdtypes.md
tile.json

behaviors.mddocs/

Interactive Behaviors

G6's behavior system provides a comprehensive set of interactive behaviors for graph manipulation. Behaviors handle user input events and translate them into graph operations with extensive customization options.

Behavior Configuration

Basic Behavior Setup

import { Graph } from '@antv/g6';
import type { BehaviorOptions, UpdateBehaviorOption } from '@antv/g6';

// Simple behavior configuration
const graph = new Graph({
  behaviors: [
    'drag-canvas',    // String-based configuration
    'zoom-canvas',
    'drag-element'
  ]
});

// Advanced behavior configuration
const graph = new Graph({
  behaviors: [
    {
      key: 'drag-canvas-custom',
      type: 'drag-canvas',
      enable: true,
      direction: 'both'
    },
    {
      key: 'selective-drag',
      type: 'drag-element',
      enable: (event) => event.targetType === 'node'
    }
  ]
});

Dynamic Behavior Management

// Update behaviors at runtime
graph.setBehaviors([
  'drag-canvas',
  'zoom-canvas',
  { key: 'hover', type: 'hover-activate' }
]);

// Update specific behavior
graph.updateBehavior({
  key: 'drag-canvas',
  enable: false
});

// Get current behaviors
const behaviors = graph.getBehaviors();

Built-in Behaviors

Canvas Navigation Behaviors

import type { 
  DragCanvasOptions, 
  ViewportAnimationEffectTiming, 
  ShortcutKey 
} from '@antv/g6';

// Drag Canvas Behavior
interface DragCanvasOptions {
  animation?: ViewportAnimationEffectTiming;
  enable?: boolean | ((event: any) => boolean);
  direction?: 'x' | 'y' | 'both';
  range?: number | number[];           // Draggable viewport range
  trigger?: {                          // Keyboard triggers
    up: ShortcutKey;
    down: ShortcutKey;
    left: ShortcutKey;
    right: ShortcutKey;
  };
  sensitivity?: number;                // Key movement distance
  onFinish?: () => void;              // Completion callback
}

const dragCanvasBehavior = {
  key: 'drag-canvas',
  type: 'drag-canvas',
  direction: 'both',
  range: [-1000, -1000, 1000, 1000],
  trigger: {
    up: ['ArrowUp'],
    down: ['ArrowDown'],
    left: ['ArrowLeft'],
    right: ['ArrowRight']
  },
  sensitivity: 10,
  onFinish: () => console.log('Canvas drag completed')
};

// Zoom Canvas Behavior
const zoomCanvasBehavior = {
  key: 'zoom-canvas',
  type: 'zoom-canvas',
  enable: true,
  sensitivity: 0.5,
  optimizeByTimeSlice: true,
  trigger: {
    zoomIn: ['Control', '='],
    zoomOut: ['Control', '-'],
    reset: ['Control', '0']
  }
};

// Scroll Canvas Behavior
const scrollCanvasBehavior = {
  key: 'scroll-canvas',
  type: 'scroll-canvas',
  enable: true,
  direction: 'both',
  sensitivity: 1
};

Element Interaction Behaviors

// Drag Element Behavior
const dragElementBehavior = {
  key: 'drag-element',
  type: 'drag-element',
  enable: (event) => {
    // Only allow dragging nodes
    return event.targetType === 'node';
  },
  animation: {
    duration: 200,
    easing: 'ease-out'
  },
  shadow: true,                        // Show drag shadow
  updateRelatedEdge: true,             // Update connected edges
  onStart: (event) => console.log('Drag started'),
  onDrag: (event) => console.log('Dragging'),
  onEnd: (event) => console.log('Drag ended')
};

// Drag Element Force Behavior (for force-directed layouts)
const dragElementForceBehavior = {
  key: 'drag-element-force',
  type: 'drag-element-force',
  damping: 0.9,                        // Damping factor for physics
  maxSpeed: 1000,                      // Maximum drag speed
  minMovement: 0.5                     // Minimum movement threshold
};

// Hover Activate Behavior
const hoverActivateBehavior = {
  key: 'hover-activate',
  type: 'hover-activate',
  enable: true,
  activateState: 'hover',              // State to apply on hover
  inactiveState: 'default',            // State to apply when not hovering
  onHover: (event) => console.log('Element hovered'),
  onUnhover: (event) => console.log('Element unhovered')
};

Selection Behaviors

// Click Select Behavior
const clickSelectBehavior = {
  key: 'click-select',
  type: 'click-select',
  enable: true,
  multiple: true,                      // Allow multiple selection
  selectState: 'selected',             // State for selected elements
  unselectState: 'default',            // State for unselected elements
  trigger: 'click',                    // 'click' | 'dblclick'
  onSelect: (event) => console.log('Element selected'),
  onUnselect: (event) => console.log('Element unselected')
};

// Brush Select Behavior
const brushSelectBehavior = {
  key: 'brush-select',
  type: 'brush-select',
  enable: true,
  trigger: 'drag',                     // 'drag' | 'shift+drag'
  mode: 'intersect',                   // 'intersect' | 'contain'
  selectState: 'selected',
  brushStyle: {
    fill: '#EBF2FF',
    stroke: '#DEEAFF',
    lineWidth: 1
  },
  onStart: (event) => console.log('Brush started'),
  onEnd: (event) => console.log('Brush ended')
};

// Lasso Select Behavior
const lassoSelectBehavior = {
  key: 'lasso-select',
  type: 'lasso-select',
  enable: true,
  trigger: 'shift+drag',
  selectState: 'selected',
  lassoStyle: {
    stroke: '#1890FF',
    lineWidth: 2,
    lineDash: [5, 5]
  }
};

Tree Graph Behaviors

import type { CollapseExpandNodeOptions } from '@antv/g6';

// Collapse Expand Behavior
const collapseExpandBehavior = {
  key: 'collapse-expand',
  type: 'collapse-expand',
  enable: true,
  trigger: 'dblclick',                 // 'click' | 'dblclick'
  animate: true,
  duration: 300,
  onCollapse: (event) => console.log('Node collapsed'),
  onExpand: (event) => console.log('Node expanded')
};

// Focus Element Behavior
const focusElementBehavior = {
  key: 'focus-element',
  type: 'focus-element',
  enable: true,
  trigger: 'dblclick',
  animation: {
    duration: 500,
    easing: 'ease-in-out'
  },
  scaleRatio: 1.2                      // Scale factor when focusing
};

Specialized Behaviors

// Create Edge Behavior
const createEdgeBehavior = {
  key: 'create-edge',
  type: 'create-edge',
  enable: true,
  trigger: 'shift+drag',               // Activation trigger
  edgeConfig: {
    type: 'line',
    style: {
      stroke: '#1890FF',
      lineWidth: 2,
      lineDash: [5, 5]              // Preview edge style
    }
  },
  onCreate: (event) => console.log('Edge created'),
  onCancel: (event) => console.log('Edge creation cancelled')
};

// Auto Adapt Label Behavior
const autoAdaptLabelBehavior = {
  key: 'auto-adapt-label',
  type: 'auto-adapt-label',
  enable: true,
  minZoom: 0.5,                        // Minimum zoom to show labels
  maxZoom: 3,                          // Maximum zoom to show labels
  hideRatio: 0.3,                      // Hide labels when zoom < hideRatio
  showRatio: 0.7                       // Show labels when zoom > showRatio
};

// Fix Element Size Behavior
const fixElementSizeBehavior = {
  key: 'fix-element-size',
  type: 'fix-element-size',
  enable: true,
  fixAll: false,                       // Fix all elements or just nodes
  fixLineWidth: true,                  // Fix line width during zoom
  fixLabel: true                       // Fix label size during zoom
};

// Optimize Viewport Transform Behavior
const optimizeViewportBehavior = {
  key: 'optimize-viewport-transform',
  type: 'optimize-viewport-transform',
  enable: true,
  hideEdge: true,                      // Hide edges during transform
  hideLabel: true,                     // Hide labels during transform
  threshold: 16                        // Animation frame threshold
};

Custom Behavior Development

Creating Custom Behaviors

import { BaseBehavior } from '@antv/g6';
import type { BehaviorOptions } from '@antv/g6';

class CustomBehavior extends BaseBehavior {
  static defaultOptions: Partial<BehaviorOptions> = {
    enable: true,
    sensitivity: 1
  };

  constructor(options: BehaviorOptions) {
    super(options);
  }

  onEnable(): void {
    // Setup event listeners
    this.bindEvents({
      'node:click': this.onNodeClick,
      'edge:hover': this.onEdgeHover
    });
  }

  onDisable(): void {
    // Remove event listeners
    this.unbindEvents();
  }

  private onNodeClick = (event: any) => {
    console.log('Custom node click behavior', event);
    // Custom logic here
  };

  private onEdgeHover = (event: any) => {
    console.log('Custom edge hover behavior', event);
    // Custom logic here
  };
}

// Register custom behavior
import { register } from '@antv/g6';

register('behavior', 'custom-behavior', CustomBehavior);

// Use custom behavior
const graph = new Graph({
  behaviors: [
    {
      key: 'my-custom-behavior',
      type: 'custom-behavior',
      sensitivity: 2
    }
  ]
});

Behavior Event Binding

// Event binding patterns in behaviors
class ExampleBehavior extends BaseBehavior {
  onEnable(): void {
    // Single event binding
    this.bindEvents({
      'node:click': this.handleNodeClick
    });

    // Multiple event binding
    this.bindEvents({
      'node:mouseenter': this.handleMouseEnter,
      'node:mouseleave': this.handleMouseLeave,
      'canvas:drag': this.handleCanvasDrag
    });

    // Conditional event binding
    if (this.options.enableKeyboard) {
      this.bindEvents({
        'key:down': this.handleKeyDown
      });
    }
  }

  private handleNodeClick = (event: any) => {
    // Access graph instance
    const graph = this.context.graph;
    
    // Access event properties
    const { target, targetType, client } = event;
    
    // Conditional behavior execution
    if (!this.options.enable(event)) return;
    
    // Behavior logic here
  };
}

Behavior Event System

Common Event Types

// Behavior can listen to these event types
interface BehaviorEvents {
  // Element events
  'node:click': (event: IElementEvent) => void;
  'node:dblclick': (event: IElementEvent) => void;
  'node:mouseenter': (event: IElementEvent) => void;
  'node:mouseleave': (event: IElementEvent) => void;
  'node:dragstart': (event: IElementDragEvent) => void;
  'node:drag': (event: IElementDragEvent) => void;
  'node:dragend': (event: IElementDragEvent) => void;
  
  'edge:click': (event: IElementEvent) => void;
  'edge:hover': (event: IElementEvent) => void;
  
  // Canvas events  
  'canvas:click': (event: IPointerEvent) => void;
  'canvas:drag': (event: IDragEvent) => void;
  'canvas:wheel': (event: IWheelEvent) => void;
  
  // Keyboard events
  'key:down': (event: IKeyboardEvent) => void;
  'key:up': (event: IKeyboardEvent) => void;
  
  // Viewport events
  'viewport:transform': (event: IViewportEvent) => void;
}

Event Properties

interface IElementEvent {
  target: Element;              // Target element
  targetType: ElementType;      // 'node' | 'edge' | 'combo'  
  client: Point;               // Client coordinates
  canvas: Point;               // Canvas coordinates
  viewport: Point;             // Viewport coordinates
  originalEvent: Event;        // Original DOM event
}

interface IDragEvent extends IElementEvent {
  movement: Point;             // Movement delta
  cumulative: Point;           // Cumulative movement
}

interface IKeyboardEvent {
  key: string;                 // Key pressed
  code: string;                // Key code
  ctrlKey: boolean;           // Modifier keys
  shiftKey: boolean;
  altKey: boolean;
  metaKey: boolean;
}

Type Definitions

interface BehaviorOptions {
  key?: string;                        // Unique behavior key
  type: string;                        // Behavior type
  enable?: boolean | ((event: any) => boolean);
  [key: string]: any;                  // Additional options
}

interface UpdateBehaviorOption {
  key: string;                         // Behavior key to update
  [key: string]: any;                  // Options to update
}

type ShortcutKey = string | string[];

interface ViewportAnimationEffectTiming {
  duration?: number;
  easing?: string | ((t: number) => number);
  delay?: number;
  fill?: 'none' | 'forwards' | 'backwards' | 'both';
}

abstract class BaseBehavior {
  protected options: BehaviorOptions;
  protected context: { graph: Graph };
  
  abstract onEnable(): void;
  abstract onDisable(): void;
  
  protected bindEvents(events: Record<string, Function>): void;
  protected unbindEvents(): void;
}