logo

G6

  • Docs
  • API
  • Playground
  • Community
  • Productsantv logo arrow
  • 5.0.48
  • Introduction
  • Data
  • Getting Started
    • Quick Start
    • Installation
    • Integration
      • react
      • vue
      • angular
    • Step-by-step guide
  • Graph
    • Extensions En
    • Graph
    • Options
    • extension
  • Element
    • Element Overview
    • Element State
    • Node
      • Node Overview
      • Build-in Node
        • Common Node Configurations
        • Diamond
        • Donut
        • Ellipse
        • Hexagon
        • Html
        • Image
        • Rect
        • Star
        • Triangle
        • Circle
      • Custom Node
      • Define Nodes with React
    • Edge
      • Edge Overview
      • Build-in Edge
        • Common Edge Configurations
        • Cubic Bezier Curve
        • CubicHorizontal Bezier Curve
        • CubicVertical Bezier Curve
        • Line
        • Polyline
        • Quadratic Bezier Curve
      • Custom Edge
    • Combo
      • Combo Overview
      • Build-in Combo
        • Circle
        • Combo Configuration Options
        • Rect
      • Custom Combo
    • Shape
      • Shape and KeyShape
      • Atomic Shapes and Their Properties
      • Design and Implementation of Composite Shape
  • Layout
    • Layout Overview
    • Build-in Layout
      • 3D Force-Directed Layout
      • AntvDagre Layout
      • Circular Layout
      • ComboCombined Layout
      • Common Layout Configuration Options
      • CompactBox
      • Concentric Layout
      • D3 Force-Directed Layout
      • Dagre Layout
      • Dendrogram Layout
      • Fishbone Layout
      • Force Force-directed Layout
      • ForceAtlas2 Force-directed Layout
      • Fruchterman Force-directed Layout
      • Grid Layout
      • Indented Tree
      • MDS High-dimensional Data Dimensionality Reduction Layout
      • Mindmap Tree
      • Radial Layout
      • Random Layout
      • Snake Layout
    • Custom Layout
  • Behavior
    • Behavior Overview
    • Build-in Behavior
      • AutoAdaptLabel
      • BrushSelect
      • ClickSelect
      • CollapseExpand
      • CreateEdge
      • DragCanvas
      • DragElement
      • DragElementForce
      • FixElementSize
      • FocusElement
      • HoverActivate
      • LassoSelect
      • OptimizeViewportTransform
      • ScrollCanvas
      • ZoomCanvas
    • Custom Behavior
  • Plugin
    • Plugin Overview
    • Build-in Plugin
      • Background
      • BubbleSets
      • Contextmenu
      • EdgeBundling
      • EdgeFilterLens
      • Fisheye
      • Fullscreen
      • GridLine
      • History
      • Hull
      • Legend
      • Minimap
      • Snapline
      • Timebar
      • Toolbar
      • Tooltip
      • Watermark
    • Custom Plugin
  • Transform
    • Data Transformation Overview
    • Build-in Transform
      • MapNodeSize
      • PlaceRadialLabels
      • ProcessParallelEdges
    • Custom Transform
  • Theme
    • Theme Overview
    • Custom Theme
    • Palette
    • Custom Palette
  • Animation
    • Animation Overview
    • Custom Animation
  • Further Reading
    • Event
    • renderer
    • coordinate
    • download-image
    • Using Iconfont
    • Use 3D
    • Bundle Project
  • What's new
    • Feature
    • Upgrade To 5.0
  • FAQ
  • contribute

D3 Force-Directed Layout

Previous
Concentric Layout
Next
Dagre Layout

Resources

Ant Design
Galacea Effects
Umi-React Application Framework
Dumi-Component doc generator
ahooks-React Hooks Library

Community

Ant Financial Experience Tech
seeconfSEE Conf-Experience Tech Conference

Help

GitHub
StackOverflow

more productsMore Productions

Ant DesignAnt Design-Enterprise UI design language
yuqueYuque-Knowledge creation and Sharing tool
EggEgg-Enterprise-class Node development framework
kitchenKitchen-Sketch Tool set
GalaceanGalacean-互动图形解决方案
xtechLiven Experience technology
© Copyright 2025 Ant Group Co., Ltd..备案号:京ICP备15032932号-38

Loading...

Overview

The D3Force layout is a force-directed layout based on d3-force. It simulates physical forces (such as attraction, repulsion, collision, etc.) to make the graph reach a stable state with minimal energy.

The main features of this layout are:

  1. Automatic arrangement: No need to manually set node positions, the system will automatically find suitable positions
  2. Real-time adjustment: When you drag a node, other nodes will adjust their positions in real time
  3. Flexible configuration:
    • You can adjust the attraction and repulsion between nodes
    • You can set the ideal length of edges
    • You can fix the positions of important nodes
  4. Animation effect: Nodes move with smooth animation, making changes more natural
D3Force layout diagram

Core Concepts

Force System

The D3Force layout simulates five different forces to achieve automatic layout. Imagine a physical world where these forces act simultaneously and eventually reach equilibrium:

force

Note: The arrows of different colors in the diagram represent different types of forces. In the actual layout, these forces are invisible and also affected by other forces.

  • Link Force: Imagine nodes connected by rubber bands, which pull connected nodes to a suitable distance. The tightness of the rubber band is the force strength, and the ideal length is the distance we set.
  • Many-Body Force: Similar to magnets, it allows all nodes to attract or repel each other. When the force strength is negative, nodes repel each other (like like poles of magnets); when positive, they attract (like opposite poles). This force determines the density of the graph.
  • Center Force: Like all nodes are tied to the center of the canvas by an invisible string. This force prevents nodes from drifting too far and keeps the graph centered.
  • Collision Force: Treats nodes as solid balls. When nodes get too close, they automatically bounce apart. This force mainly prevents node overlap and improves readability.
  • Radial Force: Imagine an invisible ring that attracts nodes to the ring. By setting the radius and force strength, nodes can form a beautiful circular layout.

Iteration System

Layout calculation is an iterative process with two key concepts:

Alpha Value (Energy)

Like the "energy" of the layout, it determines how vigorously nodes move:

  • Initial state: Alpha = 1, nodes move vigorously
  • During calculation: Alpha gradually decreases, node movement slows
  • End state: When Alpha < alphaMin, nodes stop moving

Iterations

Controls the number of times forces are applied in each calculation:

  • Effect: The larger the value, the more precise the layout, but the slower the computation
  • Adjustment:
    • Simple graphs: use the default value
    • Complex graphs: increase the number of iterations as needed
    • Real-time interaction: use fewer iterations

Tip: Iterations and alpha value work together. Increasing iterations makes each step more precise, while alpha controls the overall progress.

Options

PropertyDescriptionTypeDefaultRequired
typeLayout typestring'd3-force'✓
nodeSizeNode size (diameter), for collision detectionnumber | ((node, index, nodes) => number)-
iterationsNumber of force iterations, higher is more precisenumber-
onTickCallback for each iteration, for real-time results(data: LayoutMapping) => void-
forceSimulationCustom force simulation, defaults to d3.js methodSimulation<NodeDatum, EdgeDatum>-
randomSourceFunction to generate random numbers() => number-

Iteration Control

PropertyDescriptionTypeDefaultRequired
alphaCurrent convergence threshold, controls activitynumber1
alphaMinMinimum threshold to stop, when alpha < this, stopnumber0.001
alphaDecayDecay rate of alpha, [0, 1], 0.028 ≈ 300 iterationsnumber0.028
alphaTargetTarget alpha, system tries to converge to this valuenumber0
velocityDecayVelocity decay factor, higher means slower movementnumber0.4

Force Model Options

Link Force (link)

PropertyDescriptionTypeDefaultRequired
link.idFunction to generate edge id(edge, index, edges) => string(e) => e.id
link.distanceIdeal edge lengthnumber | ((edge, index, edges) => number)30
link.strengthForce strength, higher means closer to idealnumber | ((edge, index, edges) => number)1
link.iterationsNumber of link force iterationsnumber1

Many-Body Force (manyBody)

PropertyDescriptionTypeDefaultRequired
manyBody.strengthForce strength, negative for repulsion, positive for attractionnumber | ((node, index, nodes) => number)-30
manyBody.thetaBarnes-Hut accuracy, smaller is more accuratenumber0.9
manyBody.distanceMinMinimum distance, prevents excessive forcenumber1
manyBody.distanceMaxMaximum distance, beyond which no force is appliednumberInfinity

Center Force (center)

PropertyDescriptionTypeDefaultRequired
center.xCenter x coordinatenumber0
center.yCenter y coordinatenumber0
center.strengthForce strength, higher means closer to centernumber1

Collision Force (collide)

PropertyDescriptionTypeDefaultRequired
collide.radiusCollision radius, nodes repel if closernumber | ((node, index, nodes) => number)10
collide.strengthForce strength, higher means stronger repulsionnumber1
collide.iterationsNumber of collision iterationsnumber1

Radial Force (radial)

PropertyDescriptionTypeDefaultRequired
radial.strengthForce strength, higher means closer to radiusnumber | ((node, index, nodes) => number)0.1
radial.radiusTarget radius, nodes are attracted to circlenumber | ((node, index, nodes) => number)100
radial.xCenter x coordinatenumber0
radial.yCenter y coordinatenumber0

X Axis Force (x)

PropertyDescriptionTypeDefaultRequired
x.strengthForce strength in x directionnumber | ((node, index, nodes) => number)-
x.xTarget x coordinate, nodes attracted herenumber | ((node, index, nodes) => number)-

Y Axis Force (y)

PropertyDescriptionTypeDefaultRequired
y.strengthForce strength in y directionnumber | ((node, index, nodes) => number)-
y.yTarget y coordinate, nodes attracted herenumber | ((node, index, nodes) => number)-

Code Examples

Prevent Node Overlap

{
layout: {
type: 'd3-force',
collide: {
// Prevent nodes from overlapping by specifying a collision radius for each node.
radius: (d) => d.size / 2,
},
},
}

See Example - Prevent Node Overlap in Force-Directed Layout

Team Clustering Layout

This example shows how to use force-directed layout for team clustering, where nodes of different teams automatically cluster together.

import { Graph } from '@antv/g6';
const graph = new Graph({
container: 'container',
width: 500,
height: 250,
autoFit: 'view',
data: {
nodes: [
// Team A
{ id: 'A1', team: 'A', label: 'A1', size: 30 },
{ id: 'A2', team: 'A', label: 'A2', size: 20 },
{ id: 'A3', team: 'A', label: 'A3', size: 20 },
{ id: 'A4', team: 'A', label: 'A4', size: 20 },
// Team B
{ id: 'B1', team: 'B', label: 'B1', size: 30 },
{ id: 'B2', team: 'B', label: 'B2', size: 20 },
{ id: 'B3', team: 'B', label: 'B3', size: 20 },
{ id: 'B4', team: 'B', label: 'B4', size: 20 },
// Team C
{ id: 'C1', team: 'C', label: 'C1', size: 30 },
{ id: 'C2', team: 'C', label: 'C2', size: 20 },
{ id: 'C3', team: 'C', label: 'C3', size: 20 },
{ id: 'C4', team: 'C', label: 'C4', size: 20 },
],
edges: [
// Team A internal connections
{ source: 'A1', target: 'A2' },
{ source: 'A1', target: 'A3' },
{ source: 'A1', target: 'A4' },
// Team B internal connections
{ source: 'B1', target: 'B2' },
{ source: 'B1', target: 'B3' },
{ source: 'B1', target: 'B4' },
// Team C internal connections
{ source: 'C1', target: 'C2' },
{ source: 'C1', target: 'C3' },
{ source: 'C1', target: 'C4' },
// Few connections between teams
{ source: 'A1', target: 'B1' },
{ source: 'B1', target: 'C1' },
],
},
node: {
style: {
size: (d) => d.size,
fill: (d) => {
// Different colors for different teams
const colors = {
A: '#FF6B6B',
B: '#4ECDC4',
C: '#45B7D1',
};
return colors[d.team];
},
labelText: (d) => d.label,
labelPlacement: 'center',
labelFill: '#fff',
},
},
edge: {
style: {
stroke: '#aaa',
},
},
layout: {
type: 'd3-force',
// Configure link force - nodes within the same team are closer
link: {
distance: (d) => {
// Shorter distance within the same team
if (d.source.team === d.target.team) return 50;
// Longer distance between teams
return 200;
},
strength: (d) => {
// Stronger connection within the same team
if (d.source.team === d.target.team) return 0.7;
// Weaker connection between teams
return 0.1;
},
},
// Configure many-body force - control repulsion between nodes
manyBody: {
strength: (d) => {
// Team leader nodes (ending with 1) have stronger repulsion
if (d.label.endsWith('1')) return -100;
return -30;
},
},
// Configure collision force - prevent node overlap
collide: {
radius: 35,
strength: 0.8,
},
// Configure center force - keep the graph centered
center: {
strength: 0.05,
},
},
behaviors: ['drag-element-force'],
});
graph.render();
Show full code
import { Graph } from '@antv/g6';
// Create mock data with nodes from different teams
const data = {
nodes: [
// Team A
{ id: 'A1', team: 'A', label: 'A1', size: 30 },
{ id: 'A2', team: 'A', label: 'A2', size: 20 },
{ id: 'A3', team: 'A', label: 'A3', size: 20 },
{ id: 'A4', team: 'A', label: 'A4', size: 20 },
// Team B
{ id: 'B1', team: 'B', label: 'B1', size: 30 },
{ id: 'B2', team: 'B', label: 'B2', size: 20 },
{ id: 'B3', team: 'B', label: 'B3', size: 20 },
{ id: 'B4', team: 'B', label: 'B4', size: 20 },
// Team C
{ id: 'C1', team: 'C', label: 'C1', size: 30 },
{ id: 'C2', team: 'C', label: 'C2', size: 20 },
{ id: 'C3', team: 'C', label: 'C3', size: 20 },
{ id: 'C4', team: 'C', label: 'C4', size: 20 },
],
edges: [
// Team A internal connections
{ source: 'A1', target: 'A2' },
{ source: 'A1', target: 'A3' },
{ source: 'A1', target: 'A4' },
// Team B internal connections
{ source: 'B1', target: 'B2' },
{ source: 'B1', target: 'B3' },
{ source: 'B1', target: 'B4' },
// Team C internal connections
{ source: 'C1', target: 'C2' },
{ source: 'C1', target: 'C3' },
{ source: 'C1', target: 'C4' },
// Few connections between teams
{ source: 'A1', target: 'B1' },
{ source: 'B1', target: 'C1' },
],
};
const graph = new Graph({
container: 'container',
data,
node: {
style: {
size: (d) => d.size,
fill: (d) => {
// Different colors for different teams
const colors = {
A: '#FF6B6B',
B: '#4ECDC4',
C: '#45B7D1',
};
return colors[d.team];
},
labelText: (d) => d.label,
labelPlacement: 'center',
labelFill: '#fff',
},
},
edge: {
style: {
stroke: '#aaa',
},
},
layout: {
type: 'd3-force',
// Configure link force - nodes within the same team are closer
link: {
distance: (d) => {
// Shorter distance within the same team
if (d.source.team === d.target.team) return 50;
// Longer distance between teams
return 200;
},
strength: (d) => {
// Stronger connection within the same team
if (d.source.team === d.target.team) return 0.7;
// Weaker connection between teams
return 0.1;
},
},
// Configure many-body force - control repulsion between nodes
manyBody: {
strength: (d) => {
// Team leader nodes (ending with 1) have stronger repulsion
if (d.label.endsWith('1')) return -100;
return -30;
},
},
// Configure collision force - prevent node overlap
collide: {
radius: 35,
strength: 0.8,
},
// Configure center force - keep the graph centered
center: {
strength: 0.05,
},
},
behaviors: ['drag-element-force'],
});
graph.render();

Main configuration notes:

  • link.distance: Shorter within teams, longer between teams
  • link.strength: Stronger within teams, weaker between teams
  • manyBody.strength: Controls repulsion between nodes
  • collide: Prevents node overlap
  • center: Keeps the layout centered

See also Customize parameters for different nodes.