CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-d3-force

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

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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;
}

Install with Tessl CLI

npx tessl i tessl/npm-d3-force
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/d3-force@3.0.x
Publish Source
CLI
Badge
tessl/npm-d3-force badge