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

collision.mddocs/

Collision Detection

The collision force treats nodes as circles with configurable radius and prevents overlapping through iterative relaxation. It uses quadtree spatial partitioning for efficient collision detection and supports per-node radius configuration.

Capabilities

Collision Force Factory

Creates a new collision force with specified radius configuration.

/**
 * Creates a new collision force with the specified radius
 * @param radius - Circle radius (number or accessor function, optional, defaults to 1)
 * @returns CollideForce instance with configuration methods
 */
function forceCollide(radius?: number | ((d: Node, i: number, nodes: Node[]) => number)): CollideForce;

Usage Examples:

import { forceCollide } from "d3-force";

// Fixed radius for all nodes
const collideForce = forceCollide(5);

// Variable radius based on node data
const collideForce = forceCollide(d => d.radius || 3);

// Default radius (1)
const collideForce = forceCollide();

// Add to simulation
simulation.force("collide", forceCollide(d => d.size * 2));

Radius Configuration

Configure the collision radius for nodes.

/**
 * Sets or gets the radius accessor for collision detection
 * @param radius - Radius value or accessor function (optional)
 * @returns Current radius accessor or force instance for chaining
 */
radius(radius?: number | ((d: Node, i: number, nodes: Node[]) => number)): ((d: Node, i: number, nodes: Node[]) => number) | CollideForce;

Usage Examples:

const collideForce = forceCollide();

// Set fixed radius
collideForce.radius(10);

// Set variable radius based on node properties
collideForce.radius(d => d.size || 5);

// Complex radius calculation
collideForce.radius((d, i) => {
  return Math.sqrt(d.value) * 3 + 2;
});

// Get current radius accessor
const currentRadius = collideForce.radius();

Strength Configuration

Configure collision resolution strength.

/**
 * Sets or gets the collision force strength
 * @param strength - Strength value in range [0,1] (optional, defaults to 1)
 * @returns Current strength or force instance for chaining
 */
strength(strength?: number): number | CollideForce;

Usage Examples:

const collideForce = forceCollide(5);

// Full collision strength (hard collisions)
collideForce.strength(1);

// Soft collisions for smoother movement
collideForce.strength(0.7);

// Very soft collisions
collideForce.strength(0.3);

Iterations Configuration

Configure the number of collision resolution iterations per simulation tick.

/**
 * Sets or gets the number of iterations per application
 * @param iterations - Number of iterations (optional, defaults to 1)
 * @returns Current iteration count or force instance for chaining
 */
iterations(iterations?: number): number | CollideForce;

Usage Examples:

const collideForce = forceCollide(5);

// Single iteration (default, fastest)
collideForce.iterations(1);

// Multiple iterations for more rigid constraints
collideForce.iterations(3);

// High iteration count for very stable collisions
collideForce.iterations(5);

Common Usage Patterns

Bubble Chart Collision

Create non-overlapping bubble charts with variable sizes:

const bubbleData = [
  { name: "A", value: 100 },
  { name: "B", value: 200 },
  { name: "C", value: 50 }
];

const simulation = forceSimulation(bubbleData)
  .force("collision", forceCollide()
    .radius(d => Math.sqrt(d.value) * 0.5)
    .strength(0.8)
    .iterations(2)
  )
  .force("center", forceCenter(400, 300));

Packed Circle Layout

Create tightly packed circles with minimal gaps:

const simulation = forceSimulation(nodes)
  .force("collision", forceCollide()
    .radius(d => d.radius + 1) // Small padding
    .strength(1)
    .iterations(4) // High iterations for tight packing
  )
  .force("center", forceCenter(width / 2, height / 2));

Node-Link Diagram with Collision

Prevent node overlap in network diagrams:

const simulation = forceSimulation(nodes)
  .force("link", forceLink(links))
  .force("charge", forceManyBody())
  .force("collision", forceCollide()
    .radius(d => (d.children ? 10 : 5)) // Larger radius for parent nodes
    .strength(0.9)
  )
  .force("center", forceCenter(400, 300));

Beeswarm Plot

Create vertical or horizontal strips with collision:

// Horizontal beeswarm
const simulation = forceSimulation(data)
  .force("x", forceX(d => xScale(d.value)).strength(0.8))
  .force("y", forceY(height / 2).strength(0.1))
  .force("collision", forceCollide()
    .radius(3)
    .strength(1)
    .iterations(2)
  );

Dynamic Radius Updates

Update collision radius based on changing data:

const collideForce = forceCollide().radius(d => d.currentRadius);
simulation.force("collision", collideForce);

// Update radius and reheat simulation
function updateRadius(nodes, newRadiusData) {
  nodes.forEach((node, i) => {
    node.currentRadius = newRadiusData[i];
  });
  
  // Re-initialize force with new radius data
  collideForce.radius(d => d.currentRadius);
  
  // Reheat simulation to settle new configuration
  simulation.alpha(0.3).restart();
}

Performance Considerations

  • Quadtree Optimization: Uses d3-quadtree for efficient spatial partitioning, making collision detection O(n log n) instead of O(n²)
  • Iteration Trade-off: More iterations provide more stable collisions but increase computational cost
  • Radius Caching: Radius values are cached when force is initialized, reducing per-tick computation
  • Anticipated Positions: Uses predicted positions (x + vx, y + vy) for more stable collision resolution

Key Characteristics

  • Soft Constraints: Collision resolution is blended with force strength parameter
  • Iterative Relaxation: Multiple iterations per tick can resolve complex overlapping scenarios
  • Per-Node Radius: Each node can have individual collision radius
  • Stable Resolution: Uses velocity modification rather than direct position changes for stability

Default Values

  • radius: 1
  • strength: 1
  • iterations: 1

docs

centering.md

collision.md

index.md

links.md

many-body.md

positioning.md

simulation.md

tile.json