or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

centering.mdcollision.mdindex.mdlinks.mdmany-body.mdpositioning.mdsimulation.md
tile.json

tessl/npm-d3-force

Force-directed graph layout using velocity Verlet integration for simulating physical forces on particles

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/d3-force@3.0.x

To install, run

npx @tessl/cli install tessl/npm-d3-force@3.0.0

index.mddocs/

d3-force

d3-force is a JavaScript ES6 module that implements a velocity Verlet numerical integrator for simulating physical forces on particles. It provides a comprehensive force-directed graph layout system specifically designed for information visualization, offering various force types including center forces, collision detection, link forces, many-body forces, and positional forces.

Package Information

  • Package Name: d3-force
  • Package Type: npm
  • Language: JavaScript (ES6 modules)
  • Installation: npm install d3-force

Core Imports

import { forceSimulation, forceCenter, forceCollide, forceLink, forceManyBody, forceRadial, forceX, forceY, x, y } from "d3-force";

For CommonJS:

const { forceSimulation, forceCenter, forceCollide, forceLink, forceManyBody, forceRadial, forceX, forceY, x, y } = require("d3-force");

Basic Usage

import { forceSimulation, forceCenter, forceCollide, forceLink, forceManyBody } from "d3-force";

// Create nodes and links data
const nodes = [
  { id: "A" },
  { id: "B" }, 
  { id: "C" }
];

const links = [
  { source: "A", target: "B" },
  { source: "B", target: "C" }
];

// Create and configure simulation
const simulation = forceSimulation(nodes)
  .force("link", forceLink(links).id(d => d.id))
  .force("charge", forceManyBody())
  .force("center", forceCenter(400, 300));

// Listen for simulation events
simulation.on("tick", () => {
  console.log("Nodes positions updated:", nodes);
});

simulation.on("end", () => {
  console.log("Simulation completed");
});

Architecture

d3-force is built around several key components:

  • Simulation Engine: Core forceSimulation manages the physics loop, alpha cooling, and force application
  • Force System: Modular force functions that modify node positions and velocities
  • Node Management: Automatic initialization of node properties (position, velocity, index)
  • Event System: Tick and end events for rendering integration using d3-dispatch
  • Timer Integration: Automatic simulation timing using d3-timer for smooth animations

Capabilities

Force Simulation

Core simulation engine that manages the physics loop, applies forces, and handles node lifecycle. Essential for all force-directed layouts and physics simulations.

function forceSimulation(nodes?: Node[]): Simulation;

interface Simulation {
  tick(iterations?: number): Simulation;
  restart(): Simulation;
  stop(): Simulation;
  nodes(nodes?: Node[]): Node[] | Simulation;
  alpha(alpha?: number): number | Simulation;
  alphaMin(min?: number): number | Simulation;
  alphaDecay(decay?: number): number | Simulation;
  alphaTarget(target?: number): number | Simulation;
  velocityDecay(decay?: number): number | Simulation;
  randomSource(source?: () => number): (() => number) | Simulation;
  force(name: string, force?: Force): Force | Simulation;
  find(x: number, y: number, radius?: number): Node | undefined;
  on(typenames: string, listener?: (this: Simulation) => void): Simulation | ((this: Simulation) => void);
}

Force Simulation

Centering Forces

Centering force translates nodes uniformly so that the mean position of all nodes is at a given position. Maintains relative positioning while keeping nodes centered in viewport.

function forceCenter(x?: number, y?: number): CenterForce;

interface CenterForce {
  x(x?: number): number | CenterForce;
  y(y?: number): number | CenterForce;
  strength(strength?: number): number | CenterForce;
}

Centering Forces

Collision Detection

Collision force treats nodes as circles with configurable radius and prevents overlapping. Uses quadtree spatial partitioning for efficient collision detection.

function forceCollide(radius?: number | ((d: Node, i: number, nodes: Node[]) => number)): CollideForce;

interface CollideForce {
  radius(radius?: number | ((d: Node, i: number, nodes: Node[]) => number)): ((d: Node, i: number, nodes: Node[]) => number) | CollideForce;
  strength(strength?: number): number | CollideForce;
  iterations(iterations?: number): number | CollideForce;
}

Collision Detection

Link Forces

Link force creates spring-like connections between nodes, maintaining desired distances. Essential for graph layouts and network visualizations.

function forceLink(links?: Link[]): LinkForce;

interface LinkForce {
  links(links?: Link[]): Link[] | LinkForce;
  id(id?: (d: Node, i: number, nodes: Node[]) => string | number): ((d: Node, i: number, nodes: Node[]) => string | number) | LinkForce;
  distance(distance?: number | ((d: Link, i: number, links: Link[]) => number)): ((d: Link, i: number, links: Link[]) => number) | LinkForce;
  strength(strength?: number | ((d: Link, i: number, links: Link[]) => number)): ((d: Link, i: number, links: Link[]) => number) | LinkForce;
  iterations(iterations?: number): number | LinkForce;
}

Link Forces

Many-Body Forces

Many-body force applies mutually among all nodes using Barnes-Hut approximation for efficient n-body simulation. Can simulate gravity (attraction) or electrostatic charge (repulsion).

function forceManyBody(): ManyBodyForce;

interface ManyBodyForce {
  strength(strength?: number | ((d: Node, i: number, nodes: Node[]) => number)): ((d: Node, i: number, nodes: Node[]) => number) | ManyBodyForce;
  theta(theta?: number): number | ManyBodyForce;
  distanceMin(distance?: number): number | ManyBodyForce;
  distanceMax(distance?: number): number | ManyBodyForce;
}

Many-Body Forces

Positioning Forces

Positioning forces push nodes toward desired positions along specific dimensions. Includes x-positioning, y-positioning, and radial positioning for various layout patterns.

function forceX(x?: number | ((d: Node, i: number, nodes: Node[]) => number)): XForce;
function forceY(y?: number | ((d: Node, i: number, nodes: Node[]) => number)): YForce;
function forceRadial(radius: number | ((d: Node, i: number, nodes: Node[]) => number), x?: number, y?: number): RadialForce;

interface XForce {
  strength(strength?: number | ((d: Node, i: number, nodes: Node[]) => number)): ((d: Node, i: number, nodes: Node[]) => number) | XForce;
  x(x?: number | ((d: Node, i: number, nodes: Node[]) => number)): ((d: Node, i: number, nodes: Node[]) => number) | XForce;
}

interface YForce {
  strength(strength?: number | ((d: Node, i: number, nodes: Node[]) => number)): ((d: Node, i: number, nodes: Node[]) => number) | YForce;
  y(y?: number | ((d: Node, i: number, nodes: Node[]) => number)): ((d: Node, i: number, nodes: Node[]) => number) | YForce;
}

interface RadialForce {
  strength(strength?: number | ((d: Node, i: number, nodes: Node[]) => number)): ((d: Node, i: number, nodes: Node[]) => number) | RadialForce;
  radius(radius?: number | ((d: Node, i: number, nodes: Node[]) => number)): ((d: Node, i: number, nodes: Node[]) => number) | RadialForce;
  x(x?: number): number | RadialForce;
  y(y?: number): number | RadialForce;
}

Positioning Forces

Accessor Functions

Default accessor functions for extracting x and y coordinates from nodes.

function x(d: Node): number;
function y(d: Node): number;

Types

interface Node {
  index?: number;
  x?: number;
  y?: number;
  vx?: number;
  vy?: number;
  fx?: number | null;
  fy?: number | null;
  [key: string]: any;
}

interface Link {
  source: Node | string | number;
  target: Node | string | number;
  index?: number;
  [key: string]: any;
}

interface Force {
  (alpha: number): void;
  initialize?(nodes: Node[], random: () => number): void;
}