Force-directed graph layout using velocity Verlet integration for simulating physical forces on particles
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core simulation engine that manages the physics loop, applies forces, and handles node lifecycle. The simulation uses velocity Verlet integration with configurable alpha cooling to create smooth, stable animations.
Creates a new force simulation with specified nodes and no forces.
/**
* Creates a new force simulation with the specified array of nodes
* @param nodes - Array of node objects (optional, defaults to empty array)
* @returns Simulation instance with methods for control and configuration
*/
function forceSimulation(nodes?: Node[]): Simulation;Usage Example:
import { forceSimulation } from "d3-force";
const nodes = [{ id: "A" }, { id: "B" }, { id: "C" }];
const simulation = forceSimulation(nodes);Methods for controlling simulation execution and timing.
/**
* Manually steps the simulation by specified number of iterations
* @param iterations - Number of iterations to step (optional, defaults to 1)
* @returns Simulation instance for method chaining
*/
tick(iterations?: number): Simulation;
/**
* Restarts the simulation's internal timer
* @returns Simulation instance for method chaining
*/
restart(): Simulation;
/**
* Stops the simulation's internal timer
* @returns Simulation instance for method chaining
*/
stop(): Simulation;Usage Examples:
// Manual stepping for static layouts
simulation.stop();
for (let i = 0; i < 300; ++i) simulation.tick();
// Restart simulation after user interaction
simulation.alphaTarget(0.3).restart();Methods for managing the simulation's nodes.
/**
* Sets or gets the simulation's array of nodes
* @param nodes - Array of node objects (optional)
* @returns Array of nodes or simulation instance for chaining
*/
nodes(nodes?: Node[]): Node[] | Simulation;Usage Example:
// Set new nodes
simulation.nodes(newNodesArray);
// Get current nodes
const currentNodes = simulation.nodes();Alpha controls the simulation's "temperature" and cooling schedule.
/**
* Sets or gets the current alpha value (simulation temperature)
* @param alpha - Alpha value in range [0,1] (optional)
* @returns Current alpha value or simulation instance for chaining
*/
alpha(alpha?: number): number | Simulation;
/**
* Sets or gets the minimum alpha threshold for stopping simulation
* @param min - Minimum alpha value in range [0,1] (optional)
* @returns Current alphaMin value or simulation instance for chaining
*/
alphaMin(min?: number): number | Simulation;
/**
* Sets or gets the alpha decay rate
* @param decay - Decay rate in range [0,1] (optional)
* @returns Current alphaDecay value or simulation instance for chaining
*/
alphaDecay(decay?: number): number | Simulation;
/**
* Sets or gets the target alpha value
* @param target - Target alpha value in range [0,1] (optional)
* @returns Current alphaTarget value or simulation instance for chaining
*/
alphaTarget(target?: number): number | Simulation;Usage Example:
// Configure cooling schedule
simulation
.alpha(1) // Start hot
.alphaMin(0.001) // Stop when very cool
.alphaDecay(0.02) // Cool slowly
.alphaTarget(0); // Cool to zeroControls velocity decay (friction) in the simulation.
/**
* Sets or gets the velocity decay factor (atmospheric friction)
* @param decay - Decay factor in range [0,1] (optional)
* @returns Current velocityDecay value or simulation instance for chaining
*/
velocityDecay(decay?: number): number | Simulation;Methods for adding, removing, and configuring forces.
/**
* Sets or gets a named force
* @param name - Force identifier string
* @param force - Force function (optional, pass null to remove)
* @returns Force instance or simulation instance for chaining
*/
force(name: string, force?: Force | null): Force | Simulation;Usage Examples:
import { forceCenter, forceManyBody, forceLink } from "d3-force";
// Add forces
simulation
.force("center", forceCenter(400, 300))
.force("charge", forceManyBody())
.force("link", forceLink(links));
// Remove a force
simulation.force("charge", null);
// Get a force
const centerForce = simulation.force("center");Method for finding nodes by position.
/**
* Finds the node closest to the specified position within search radius
* @param x - X coordinate to search around
* @param y - Y coordinate to search around
* @param radius - Search radius (optional, defaults to Infinity)
* @returns Closest node within radius or undefined if none found
*/
find(x: number, y: number, radius?: number): Node | undefined;Usage Example:
// Find node near mouse position
const mouseX = 100, mouseY = 150;
const hoveredNode = simulation.find(mouseX, mouseY, 20);
if (hoveredNode) {
console.log("Hovering over:", hoveredNode);
}Configure the random number generator for deterministic simulations.
/**
* Sets or gets the random number generator function
* @param source - Function returning random number in [0,1) (optional)
* @returns Current random source function or simulation instance for chaining
*/
randomSource(source?: () => number): (() => number) | Simulation;Event listeners for simulation lifecycle events.
/**
* Sets or gets event listeners for simulation events
* @param typenames - Event type names ("tick", "end", or "tick.name end.name")
* @param listener - Event listener function (optional)
* @returns Listener function or simulation instance for chaining
*/
on(typenames: string, listener?: (this: Simulation) => void): Simulation | ((this: Simulation) => void);Usage Examples:
// Listen for simulation events
simulation
.on("tick", function() {
// Update visualization on each tick
updateNodes(this.nodes());
})
.on("end", () => {
console.log("Simulation completed");
});
// Multiple listeners with names
simulation
.on("tick.render", renderNodes)
.on("tick.log", logProgress);