CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-cytoscape

Graph theory library for analysis and visualisation of network data with interactive rendering capabilities

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

layout-system.mddocs/

Layout System

Comprehensive layout algorithms for automatic node positioning, from simple grids to complex force-directed layouts. Supports custom layouts, animation, and extensive configuration options.

Capabilities

Layout Execution

Run layouts on the core instance or specific element collections.

interface Core {
  /**
   * Run a layout on all elements
   * @param options - Layout configuration options
   * @returns Layout instance
   */
  layout(options: LayoutOptions): Layout;
  
  /**
   * Create a layout without running it
   * @param options - Layout configuration options
   * @returns Layout instance
   */
  makeLayout(options: LayoutOptions): Layout;
}

interface Collection {
  /**
   * Run a layout on this collection
   * @param options - Layout configuration options
   * @returns Layout instance
   */
  layout(options: LayoutOptions): Layout;
  
  /**
   * Create a layout for this collection without running it
   * @param options - Layout configuration options
   * @returns Layout instance
   */
  makeLayout(options: LayoutOptions): Layout;
}

interface Layout {
  /**
   * Run the layout
   * @returns Layout instance
   */
  run(): Layout;
  
  /**
   * Stop the layout
   * @returns Layout instance
   */
  stop(): Layout;
  
  /**
   * Bind event handler to layout
   * @param events - Event names
   * @param handler - Event handler function
   * @returns Layout instance
   */
  on(events: string, handler: (event: any) => void): Layout;
  
  /**
   * Unbind event handler from layout
   * @param events - Event names (optional)
   * @param handler - Event handler function (optional)
   * @returns Layout instance
   */
  off(events?: string, handler?: (event: any) => void): Layout;
}

Base Layout Options

Common options available to all layout algorithms.

interface BaseLayoutOptions {
  /**
   * Name of the layout algorithm
   */
  name: string;
  
  /**
   * Whether to fit viewport to graph after layout
   */
  fit?: boolean;
  
  /**
   * Padding around the graph when fitting
   */
  padding?: number;
  
  /**
   * Whether to animate the layout
   */
  animate?: boolean;
  
  /**
   * Duration of layout animation in milliseconds
   */
  animationDuration?: number;
  
  /**
   * Easing function for animation
   */
  animationEasing?: string;
  
  /**
   * Callback when layout is ready
   */
  ready?: () => void;
  
  /**
   * Callback when layout stops
   */
  stop?: () => void;
  
  /**
   * Transform function applied to final positions
   */
  transform?: (node: any, position: Position) => Position;
  
  /**
   * Whether to apply random initial positions
   */
  randomize?: boolean;
  
  /**
   * Bounding box constraint for layout
   */
  boundingBox?: BoundingBox;
}

Grid Layout

Arranges nodes in a grid pattern.

interface GridLayoutOptions extends BaseLayoutOptions {
  name: "grid";
  
  /**
   * Number of rows (auto-calculated if not specified)
   */
  rows?: number;
  
  /**
   * Number of columns (auto-calculated if not specified)
   */
  cols?: number;
  
  /**
   * Sort function for node ordering
   */
  sort?: (a: any, b: any) => number;
  
  /**
   * Spacing between nodes
   */
  spacingFactor?: number;
  
  /**
   * Whether to use original node positions as starting points
   */
  avoidOverlap?: boolean;
  
  /**
   * Node repulsion radius for avoiding overlap
   */
  avoidOverlapPadding?: number;
  
  /**
   * Position nodes along horizontal axis
   */
  position?: (node: any, row: number, col: number) => Position;
}

Usage Examples:

// Basic grid layout
cy.layout({
  name: 'grid',
  rows: 3,
  cols: 4,
  fit: true,
  padding: 20
}).run();

// Grid with custom sorting
cy.layout({
  name: 'grid',
  sort: (a, b) => a.data('weight') - b.data('weight'),
  animate: true,
  animationDuration: 500
}).run();

Circle Layout

Arranges nodes in a circle.

interface CircleLayoutOptions extends BaseLayoutOptions {
  name: "circle";
  
  /**
   * Radius of the circle
   */
  radius?: number;
  
  /**
   * Starting angle in radians
   */
  startAngle?: number;
  
  /**
   * Whether to sweep clockwise
   */
  clockwise?: boolean;
  
  /**
   * Sort function for node ordering around circle
   */
  sort?: (a: any, b: any) => number;
  
  /**
   * Spacing between nodes (overrides radius if specified)
   */
  spacing?: number;
}

Concentric Layout

Arranges nodes in concentric circles based on a metric.

interface ConcentricLayoutOptions extends BaseLayoutOptions {
  name: "concentric";
  
  /**
   * Function to assign concentric level to nodes
   */
  concentric?: (node: any) => number;
  
  /**
   * Function to assign level height
   */
  levelWidth?: (nodes: any[]) => number;
  
  /**
   * Minimum spacing between nodes
   */
  minNodeSpacing?: number;
  
  /**
   * Starting angle in radians
   */
  startAngle?: number;
  
  /**
   * Whether to sweep clockwise
   */
  clockwise?: boolean;
  
  /**
   * Whether to equidistribute nodes
   */
  equidistant?: boolean;
  
  /**
   * Sort function for nodes at same level
   */
  sort?: (a: any, b: any) => number;
}

Breadth-First Layout

Tree layout based on breadth-first traversal.

interface BreadthFirstLayoutOptions extends BaseLayoutOptions {
  name: "breadthfirst";
  
  /**
   * Whether to layout as directed acyclic graph
   */
  directed?: boolean;
  
  /**
   * Whether to create multiple trees from roots
   */
  circle?: boolean;
  
  /**
   * Maximum width of the tree
   */
  maximal?: boolean;
  
  /**
   * Spacing between nodes
   */
  spacing?: number;
  
  /**
   * Radius for circular layout
   */
  radius?: number;
  
  /**
   * Root nodes (if not specified, uses minimal node set)
   */
  roots?: Collection | string;
  
  /**
   * Sort function for children at each level
   */
  sort?: (a: any, b: any) => number;
}

COSE Layout

Physics-based force-directed layout (Compound graph Spring Embedder).

interface CoseLayoutOptions extends BaseLayoutOptions {
  name: "cose";
  
  /**
   * Whether to use ideal edge length as initial edge length
   */
  useMultitasking?: boolean;
  
  /**
   * Ideal edge length
   */
  idealEdgeLength?: number | ((edge: any) => number);
  
  /**
   * Node repulsion range
   */
  nodeRepulsion?: number | ((node: any) => number);
  
  /**
   * Edge elasticity (affects edge attraction)
   */
  edgeElasticity?: number | ((edge: any) => number);
  
  /**
   * Nesting factor for compound graphs
   */
  nestingFactor?: number;
  
  /**
   * Gravity force (attraction to center)
   */
  gravity?: number;
  
  /**
   * Number of iterations
   */
  numIter?: number;
  
  /**
   * Initial temperature (higher = more movement)
   */
  initialTemp?: number;
  
  /**
   * Cooling factor for temperature
   */
  coolingFactor?: number;
  
  /**
   * Minimum temperature (when to stop)
   */
  minTemp?: number;
  
  /**
   * Whether to refresh positions for incremental layout
   */
  refresh?: number;
  
  /**
   * Compound node padding
   */
  componentSpacing?: number;
  
  /**
   * Node overlap removal
   */
  nodeOverlap?: number;
  
  /**
   * Whether to pack disconnected components
   */
  tile?: boolean;
  
  /**
   * Tile padding if tiling
   */
  tilingPaddingVertical?: number;
  tilingPaddingHorizontal?: number;
}

Usage Examples:

// Basic COSE layout
cy.layout({
  name: 'cose',
  idealEdgeLength: 100,
  nodeOverlap: 20,
  refresh: 20,
  animate: true,
  animationDuration: 1000
}).run();

// COSE with custom forces
cy.layout({
  name: 'cose',
  nodeRepulsion: (node) => node.data('size') * 2000,
  edgeElasticity: (edge) => edge.data('strength') || 32,
  gravity: 80,
  numIter: 1000
}).run();

Random Layout

Places nodes at random positions.

interface RandomLayoutOptions extends BaseLayoutOptions {
  name: "random";
}

Preset Layout

Uses predefined node positions.

interface PresetLayoutOptions extends BaseLayoutOptions {
  name: "preset";
  
  /**
   * Function to get position for each node
   */
  positions?: { [id: string]: Position } | ((node: any) => Position);
  
  /**
   * Zoom level after layout
   */
  zoom?: number;
  
  /**
   * Pan position after layout
   */
  pan?: Position;
  
  /**
   * Whether to fit to viewport
   */
  fit?: boolean;
}

Null Layout

Placeholder layout that doesn't change positions.

interface NullLayoutOptions extends BaseLayoutOptions {
  name: "null";
}

Custom Layout Creation

Create custom layout algorithms by extending the base layout.

interface CustomLayoutOptions extends BaseLayoutOptions {
  /**
   * Custom layout name
   */
  name: string;
  
  /**
   * Layout run function
   */
  run?: (layout: Layout) => void;
  
  /**
   * Layout stop function
   */
  stop?: (layout: Layout) => void;
}

/**
 * Register a custom layout
 * @param name - Layout name
 * @param layout - Layout implementation
 */
cytoscape('layout', name: string, layout: any): void;

Usage Examples:

// Register custom layout
cytoscape('layout', 'myLayout', function(options) {
  const layout = this;
  
  layout.run = function() {
    const nodes = layout.options.eles.nodes();
    
    // Custom positioning logic
    nodes.forEach((node, i) => {
      node.position({
        x: i * 100,
        y: Math.sin(i) * 50
      });
    });
    
    layout.emit('layoutready');
    layout.emit('layoutstop');
    
    return layout;
  };
  
  return layout;
});

// Use custom layout
cy.layout({ name: 'myLayout' }).run();

Layout Events

Handle layout lifecycle events.

/**
 * Layout event types
 */
type LayoutEventType = 
  | "layoutstart"    // Layout starts running
  | "layoutready"    // Layout positions calculated
  | "layoutstop";    // Layout stops running

/**
 * Layout event handler
 */
interface LayoutEventHandler {
  (event: {
    type: LayoutEventType;
    layout: Layout;
    cy: Core;
  }): void;
}

Usage Examples:

// Handle layout events on core
cy.on('layoutstart', (event) => {
  console.log('Layout started:', event.layout.options.name);
});

cy.on('layoutstop', (event) => {
  console.log('Layout finished');
});

// Handle events on layout instance
const layout = cy.layout({ name: 'cose' });

layout.on('layoutready', () => {
  console.log('Positions calculated');
});

layout.run();

Layout Utilities

Helper functions for layout development and positioning.

/**
 * Get random position within bounding box
 */
function getRandomPosition(boundingBox: BoundingBox): Position;

/**
 * Check if two positions overlap
 */
function positionsOverlap(pos1: Position, pos2: Position, padding: number): boolean;

/**
 * Calculate distance between positions
 */
function getDistance(pos1: Position, pos2: Position): number;

/**
 * Get center of bounding box
 */
function getBoundingBoxCenter(boundingBox: BoundingBox): Position;

Install with Tessl CLI

npx tessl i tessl/npm-cytoscape

docs

core-management.md

element-collections.md

event-system.md

extensions.md

graph-algorithms.md

index.md

layout-system.md

styling-system.md

tile.json