or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

behavior-system.mdcontrollers.mdgraph-management.mdindex.mditem-management.mdshape-system.mdutilities.md
tile.json

shape-system.mddocs/

Shape System

Registration and management system for custom node, edge, and combo shapes with built-in arrow and marker utilities. The shape system provides extensible rendering capabilities with lifecycle hooks, state management, and geometry calculations.

Capabilities

Shape Registration

Register custom shapes for nodes, edges, and combos with the shape factory system.

/**
 * Register custom node shape
 * @param type - Shape type name
 * @param shapeObj - Shape implementation object
 */
function registerNode(type: string, shapeObj: ShapeOptions): void;

/**
 * Register custom edge shape
 * @param type - Shape type name
 * @param shapeObj - Shape implementation object
 */
function registerEdge(type: string, shapeObj: ShapeOptions): void;

/**
 * Register custom combo shape
 * @param type - Shape type name
 * @param shapeObj - Shape implementation object
 */
function registerCombo(type: string, shapeObj: ShapeOptions): void;

Usage Examples:

import { registerNode, registerEdge } from "@antv/g6-core";

// Register custom node shape
registerNode('custom-rect', {
  draw(cfg, group) {
    const rect = group.addShape('rect', {
      attrs: {
        x: -cfg.size[0] / 2,
        y: -cfg.size[1] / 2,
        width: cfg.size[0],
        height: cfg.size[1],
        fill: cfg.color || '#f0f0f0',
        stroke: '#333'
      }
    });
    return rect;
  },
  
  update(cfg, item) {
    const keyShape = item.getKeyShape();
    keyShape.attr({
      width: cfg.size[0],
      height: cfg.size[1],
      fill: cfg.color
    });
  }
});

// Register custom edge shape
registerEdge('custom-line', {
  draw(cfg, group) {
    const line = group.addShape('path', {
      attrs: {
        path: this.getPath(cfg),
        stroke: cfg.color || '#333',
        lineWidth: cfg.lineWidth || 1
      }
    });
    return line;
  },
  
  getPath(cfg) {
    const startPoint = cfg.startPoint;
    const endPoint = cfg.endPoint;
    return [
      ['M', startPoint.x, startPoint.y],
      ['L', endPoint.x, endPoint.y]
    ];
  }
});

Shape Options Interface

Complete interface for implementing custom shapes with all lifecycle methods and configuration options.

/**
 * Shape implementation options interface
 */
interface ShapeOptions {
  options?: ModelConfig;
  type?: string;
  itemType?: string;
  shapeType?: string;
  labelPosition?: string;
  labelAutoRotate?: boolean;
  jsx?: ShapeDefine;
  
  // Core drawing methods
  draw(cfg?: ModelConfig, group?: IGroup): IShape;
  drawShape(cfg?: ModelConfig, group?: IGroup): IShape;
  drawLabel(cfg: ModelConfig, group: IGroup): IShape;
  
  // Configuration methods
  getCustomConfig(cfg: ModelConfig): ModelConfig;
  getLabelStyleByPosition(cfg: ModelConfig, labelCfg: ILabelConfig, group?: IGroup): LabelStyle;
  getLabelStyle(cfg: ModelConfig, labelCfg: ILabelConfig, group: IGroup): LabelStyle;
  
  // Lifecycle hooks
  afterDraw(cfg?: ModelConfig, group?: IGroup, rst?: IShape): void;
  afterUpdate(cfg?: ModelConfig, item?: Item): void;
  
  // State management
  setState(name?: string, value?: string | boolean, item?: Item): void;
  
  // Geometry methods
  getControlPoints(cfg: ModelConfig): IPoint[] | undefined;
  getAnchorPoints(cfg?: ModelConfig): number[][] | undefined;
  getSize(cfg: ModelConfig): number[];
  getPathPoints(cfg: ModelConfig): ModelConfig;
  
  // Update method
  update(cfg: ModelConfig, item: Item): void;
  
  // Text alignment helper
  _getTextAlign(labelPosition: string, angle: number): string;
  
  [key: string]: any;
}

Shape Factory Base

Factory system for managing and accessing registered shapes.

/**
 * Base shape factory for managing shape types
 */
interface ShapeFactoryBase {
  defaultShapeType: string;
  className: string | null;
  
  /**
   * Get shape implementation by type
   * @param type - Shape type name
   * @returns Shape implementation object
   */
  getShape(type?: string): ShapeOptions;
  
  /**
   * Draw shape with specified type and configuration
   * @param type - Shape type name
   * @param cfg - Model configuration
   * @param group - Graphics group
   * @returns Created shape element
   */
  draw(type: string, cfg: ModelConfig, group: IGroup): IShape;
  
  /**
   * Update shape with new configuration
   * @param type - Shape type name
   * @param cfg - Updated configuration
   * @param item - Item instance
   */
  baseUpdate(type: string, cfg: ModelConfig, item: Item): void;
  
  /**
   * Set shape state
   * @param type - Shape type name
   * @param name - State name
   * @param value - State value
   * @param item - Item instance
   */
  setState(type: string, name: string, value: string | boolean, item: Item): void;
  
  /**
   * Check if shape should be updated
   * @param type - Shape type name
   * @returns True if should update
   */
  shouldUpdate(type: string): boolean;
  
  /**
   * Get control points for edge
   * @param type - Shape type name
   * @param cfg - Model configuration
   * @returns Array of control points
   */
  getControlPoints(type: string, cfg: ModelConfig): IPoint[] | undefined;
  
  /**
   * Get anchor points for connections
   * @param type - Shape type name
   * @param cfg - Model configuration
   * @returns Array of anchor points
   */
  getAnchorPoints(type: string, cfg: ModelConfig): number[][] | undefined;
}

Arrow Utilities

Built-in arrow shape generators for edge endpoints.

/**
 * Arrow shape utilities for edge endpoints
 */
declare const Arrow: {
  /**
   * Generate triangle arrow path
   * @param width - Arrow width
   * @param length - Arrow length
   * @param d - Distance from edge end
   * @returns SVG path string
   */
  triangle(width?: number, length?: number, d?: number): string;
  
  /**
   * Generate vee-shaped arrow path
   * @param width - Arrow width
   * @param length - Arrow length
   * @param d - Distance from edge end
   * @returns SVG path string
   */
  vee(width?: number, length?: number, d?: number): string;
  
  /**
   * Generate circular arrow path
   * @param r - Circle radius
   * @param d - Distance from edge end
   * @returns SVG path string
   */
  circle(r?: number, d?: number): string;
  
  /**
   * Generate rectangular arrow path
   * @param width - Rectangle width
   * @param length - Rectangle length
   * @param d - Distance from edge end
   * @returns SVG path string
   */
  rect(width?: number, length?: number, d?: number): string;
  
  /**
   * Generate diamond arrow path
   * @param width - Diamond width
   * @param length - Diamond length
   * @param d - Distance from edge end
   * @returns SVG path string
   */
  diamond(width?: number, length?: number, d?: number): string;
  
  /**
   * Generate combined triangle and rectangle arrow path
   * @param tWidth - Triangle width
   * @param tLength - Triangle length
   * @param rWidth - Rectangle width
   * @param rLength - Rectangle length
   * @param gap - Gap between shapes
   * @param d - Distance from edge end
   * @returns SVG path string
   */
  triangleRect(tWidth?: number, tLength?: number, rWidth?: number, rLength?: number, gap?: number, d?: number): string;
};

Usage Examples:

import { Arrow } from "@antv/g6-core";

// Use in edge configuration
const edgeConfig = {
  startArrow: {
    path: Arrow.triangle(10, 15),
    fill: '#333'
  },
  endArrow: {
    path: Arrow.vee(8, 12),
    fill: '#666'
  }
};

// Custom arrow configurations
const customTriangle = Arrow.triangle(12, 18, 2);
const customCircle = Arrow.circle(5, 1);
const customDiamond = Arrow.diamond(10, 10, 0);

Marker Utilities

Built-in marker shape generators for collapse/expand controls and indicators.

/**
 * Marker shape utilities for UI controls
 */
declare const Marker: {
  /**
   * Generate collapse marker points (minus sign)
   * @param x - Center X coordinate
   * @param y - Center Y coordinate
   * @param r - Marker radius
   * @returns Array of point coordinates
   */
  collapse(x: number, y: number, r: number): number[][];
  
  /**
   * Generate expand marker points (plus sign)
   * @param x - Center X coordinate
   * @param y - Center Y coordinate
   * @param r - Marker radius
   * @returns Array of point coordinates
   */
  expand(x: number, y: number, r: number): number[][];
  
  /**
   * Generate upward triangle marker points
   * @param x - Center X coordinate
   * @param y - Center Y coordinate
   * @param r - Marker radius
   * @returns Array of point coordinates
   */
  upTriangle(x: number, y: number, r: number): number[][];
  
  /**
   * Generate downward triangle marker points
   * @param x - Center X coordinate
   * @param y - Center Y coordinate
   * @param r - Marker radius
   * @returns Array of point coordinates
   */
  downTriangle(x: number, y: number, r: number): number[][];
};

Usage Examples:

import { Marker } from "@antv/g6-core";

// Create collapse/expand controls
const collapsePoints = Marker.collapse(50, 50, 8);
const expandPoints = Marker.expand(50, 50, 8);

// Create directional indicators
const upArrow = Marker.upTriangle(100, 100, 6);
const downArrow = Marker.downTriangle(100, 120, 6);

// Use in shape drawing
registerNode('collapsible-node', {
  draw(cfg, group) {
    // Draw main shape
    const rect = group.addShape('rect', {
      attrs: { /* rect attributes */ }
    });
    
    // Add collapse/expand marker
    const isCollapsed = cfg.collapsed;
    const markerPoints = isCollapsed ? 
      Marker.expand(cfg.x + 20, cfg.y - 10, 4) : 
      Marker.collapse(cfg.x + 20, cfg.y - 10, 4);
      
    group.addShape('polyline', {
      attrs: {
        points: markerPoints,
        stroke: '#666',
        lineWidth: 2
      }
    });
    
    return rect;
  }
});

Label Configuration

Configure label positioning and styling for shapes.

/**
 * Label configuration interface
 */
interface ILabelConfig {
  position?: string;
  offset?: number;
  refX?: number;
  refY?: number;
  autoRotate?: boolean;
  style?: LabelStyle;
}

/**
 * Shape definition type
 */
type ShapeDefine = string | ((cfg: ModelConfig) => string);

Advanced Shape Implementation

Example of a complete custom shape implementation with all features:

// Complete custom node shape example
registerNode('advanced-node', {
  // Shape configuration
  options: {
    size: [100, 60],
    labelCfg: {
      position: 'center',
      style: {
        fill: '#333'
      }
    }
  },
  
  // Main drawing method
  draw(cfg, group) {
    const size = this.getSize(cfg);
    const color = cfg.color || '#f0f0f0';
    
    // Draw main shape
    const rect = group.addShape('rect', {
      attrs: {
        x: -size[0] / 2,
        y: -size[1] / 2,
        width: size[0],
        height: size[1],
        fill: color,
        stroke: '#333',
        radius: 4
      },
      name: 'main-rect'
    });
    
    // Draw label if exists
    if (cfg.label) {
      this.drawLabel(cfg, group);
    }
    
    return rect;
  },
  
  // Update method
  update(cfg, item) {
    const keyShape = item.getKeyShape();
    const size = this.getSize(cfg);
    
    keyShape.attr({
      width: size[0],
      height: size[1],
      fill: cfg.color || '#f0f0f0'
    });
  },
  
  // State management
  setState(name, value, item) {
    const keyShape = item.getKeyShape();
    
    if (name === 'hover') {
      keyShape.attr({
        fill: value ? '#e6f7ff' : item.getModel().color || '#f0f0f0'
      });
    } else if (name === 'selected') {
      keyShape.attr({
        stroke: value ? '#1890ff' : '#333',
        lineWidth: value ? 2 : 1
      });
    }
  },
  
  // Anchor points for connections
  getAnchorPoints() {
    return [
      [0, 0.5],    // left
      [1, 0.5],    // right
      [0.5, 0],    // top
      [0.5, 1]     // bottom
    ];
  },
  
  // Size calculation
  getSize(cfg) {
    let size = cfg.size || this.options.size;
    if (typeof size === 'number') {
      size = [size, size];
    }
    return size;
  },
  
  // After draw hook
  afterDraw(cfg, group, shape) {
    // Add any post-drawing effects
    if (cfg.badge) {
      group.addShape('circle', {
        attrs: {
          x: 30,
          y: -20,
          r: 6,
          fill: '#f04134'
        },
        name: 'badge'
      });
    }
  }
});

Types

interface ModelConfig {
  type?: string;
  label?: string | LabelStyle;
  labelCfg?: ILabelConfig;
  x?: number;
  y?: number;
  size?: number | number[];
  color?: string;
  anchorPoints?: number[][];
  visible?: boolean;
  [key: string]: any;
}

interface LabelStyle {
  fill?: string;
  fontSize?: number;
  fontWeight?: string | number;
  textAlign?: string;
  textBaseline?: string;
  fontFamily?: string;
  [key: string]: any;
}

interface IShape {
  attr(name: string, value?: any): any;
  attr(attrs: object): void;
  remove(): void;
  show(): void;
  hide(): void;
  [key: string]: any;
}

interface IGroup {
  addShape(type: string, config: { attrs: object; name?: string }): IShape;
  getChildren(): IShape[];
  clear(): void;
  [key: string]: any;
}

interface IShapeBase extends IShape {
  // Extended shape interface
}

type ITEM_TYPE = 'node' | 'edge' | 'combo';

interface ArrowConfig {
  path?: string;
  fill?: string;
  stroke?: string;
  lineWidth?: number;
  [key: string]: any;
}