Comprehensive layout algorithms for automatic node positioning, from simple grids to complex force-directed layouts. Supports custom layouts, animation, and extensive configuration options.
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;
}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;
}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();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;
}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;
}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;
}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();Places nodes at random positions.
interface RandomLayoutOptions extends BaseLayoutOptions {
name: "random";
}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;
}Placeholder layout that doesn't change positions.
interface NullLayoutOptions extends BaseLayoutOptions {
name: "null";
}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();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();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;