Algorithms for positioning elements in hierarchical, network, and specialized layout patterns including trees, force simulations, and pack layouts.
Functions for working with tree-structured data.
/**
* Create hierarchy from nested data
* @param data - Root data object with children
* @param children - Optional children accessor
* @returns Root hierarchy node
*/
function hierarchy<Datum>(data: Datum, children?: (d: Datum) => Datum[] | null): HierarchyNode<Datum>;
interface HierarchyNode<Datum> {
data: Datum;
depth: number;
height: number;
parent: HierarchyNode<Datum> | null;
children: HierarchyNode<Datum>[] | null;
value?: number;
/**
* Get array of ancestor nodes
* @returns Array from root to this node
*/
descendants(): HierarchyNode<Datum>[];
/**
* Get array of leaf nodes
* @returns Array of leaf nodes
*/
leaves(): HierarchyNode<Datum>[];
/**
* Sum values from leaves upward
* @param value - Value accessor function
* @returns This node for chaining
*/
sum(value: (d: Datum) => number): HierarchyNode<Datum>;
}Algorithm for positioning tree nodes with no overlaps.
/**
* Create tree layout
* @returns Tree layout function
*/
function tree<Datum>(): TreeLayout<Datum>;
interface TreeLayout<Datum> {
/**
* Apply tree layout to hierarchy
* @param root - Root hierarchy node
* @returns Root node with x,y coordinates
*/
(root: HierarchyNode<Datum>): HierarchyNode<Datum>;
/**
* Set layout size
* @param size - [width, height] array
* @returns Layout for chaining
*/
size(size: [number, number]): TreeLayout<Datum>;
/**
* Set uniform node size
* @param size - [width, height] for each node
* @returns Layout for chaining
*/
nodeSize(size: [number, number]): TreeLayout<Datum>;
}Physics-based layout for network data with customizable forces.
/**
* Create force simulation
* @param nodes - Optional initial nodes array
* @returns Force simulation
*/
function forceSimulation<NodeDatum = any>(nodes?: NodeDatum[]): Simulation<NodeDatum, undefined>;
interface Simulation<NodeDatum, LinkDatum> {
/**
* Set nodes array
* @param nodes - Array of node objects
* @returns Simulation for chaining
*/
nodes(nodes: NodeDatum[]): Simulation<NodeDatum, LinkDatum>;
/**
* Add or remove force
* @param name - Force name
* @param force - Force function or null to remove
* @returns Simulation for chaining
*/
force(name: string, force: Force<NodeDatum, LinkDatum> | null): Simulation<NodeDatum, LinkDatum>;
/**
* Set alpha (cooling) parameter
* @param alpha - Alpha value (0-1)
* @returns Simulation for chaining
*/
alpha(alpha: number): Simulation<NodeDatum, LinkDatum>;
/**
* Restart simulation
* @returns Simulation for chaining
*/
restart(): Simulation<NodeDatum, LinkDatum>;
/**
* Stop simulation
* @returns Simulation for chaining
*/
stop(): Simulation<NodeDatum, LinkDatum>;
}
/**
* Create centering force
* @param x - Center x coordinate
* @param y - Center y coordinate
* @returns Centering force
*/
function forceCenter(x?: number, y?: number): ForceCenter;
/**
* Create many-body force (attraction/repulsion)
* @returns Many-body force
*/
function forceManyBody<NodeDatum>(): ForceManyBody<NodeDatum>;
/**
* Create link force for connected nodes
* @param links - Optional links array
* @returns Link force
*/
function forceLink<NodeDatum, LinkDatum>(links?: LinkDatum[]): ForceLink<NodeDatum, LinkDatum>;Rectangular space-filling layout that displays hierarchical data as nested rectangles.
/**
* Create treemap layout generator
* @returns Treemap layout function
*/
function treemap<Datum>(): TreemapLayout<Datum>;
interface TreemapLayout<Datum> {
/** Generate treemap layout for hierarchy */
(root: HierarchyNode<Datum>): HierarchyNode<Datum>;
/** Set layout size */
size(size: [number, number]): TreemapLayout<Datum>;
/** Set tile shape algorithm */
tile(tile: (node: HierarchyNode<Datum>, x0: number, y0: number, x1: number, y1: number) => void): TreemapLayout<Datum>;
/** Set inner and outer padding */
padding(padding: number | ((node: HierarchyNode<Datum>) => number)): TreemapLayout<Datum>;
/** Set outer padding only */
paddingOuter(padding: number | ((node: HierarchyNode<Datum>) => number)): TreemapLayout<Datum>;
/** Set inner padding only */
paddingInner(padding: number | ((node: HierarchyNode<Datum>) => number)): TreemapLayout<Datum>;
/** Set top padding */
paddingTop(padding: number | ((node: HierarchyNode<Datum>) => number)): TreemapLayout<Datum>;
/** Set bottom padding */
paddingBottom(padding: number | ((node: HierarchyNode<Datum>) => number)): TreemapLayout<Datum>;
/** Set left padding */
paddingLeft(padding: number | ((node: HierarchyNode<Datum>) => number)): TreemapLayout<Datum>;
/** Set right padding */
paddingRight(padding: number | ((node: HierarchyNode<Datum>) => number)): TreemapLayout<Datum>;
/** Set rounding function */
round(round: boolean): TreemapLayout<Datum>;
}
/**
* Treemap tiling algorithms
*/
const treemapBinary: TreemapTilingMethod;
const treemapDice: TreemapTilingMethod;
const treemapSlice: TreemapTilingMethod;
const treemapSliceDice: TreemapTilingMethod;
const treemapSquarify: TreemapTilingMethod;
const treemapResquarify: TreemapTilingMethod;
interface TreemapTilingMethod {
(node: HierarchyNode<any>, x0: number, y0: number, x1: number, y1: number): void;
ratio?(ratio: number): TreemapTilingMethod;
}Sunburst and icicle charts showing hierarchical data as nested arcs or rectangles.
/**
* Create partition layout generator
* @returns Partition layout function
*/
function partition<Datum>(): PartitionLayout<Datum>;
interface PartitionLayout<Datum> {
/** Generate partition layout for hierarchy */
(root: HierarchyNode<Datum>): HierarchyNode<Datum>;
/** Set layout size */
size(size: [number, number]): PartitionLayout<Datum>;
/** Set rounding function */
round(round: boolean): PartitionLayout<Datum>;
/** Set inner and outer padding */
padding(padding: number): PartitionLayout<Datum>;
}Circle packing layout for displaying hierarchical data as nested circles.
/**
* Create pack layout generator
* @returns Pack layout function
*/
function pack<Datum>(): PackLayout<Datum>;
interface PackLayout<Datum> {
/** Generate pack layout for hierarchy */
(root: HierarchyNode<Datum>): HierarchyNode<Datum>;
/** Set layout radius accessor */
radius(radius: number | ((node: HierarchyNode<Datum>) => number)): PackLayout<Datum>;
/** Set layout size */
size(size: [number, number]): PackLayout<Datum>;
/** Set padding between circles */
padding(padding: number | ((node: HierarchyNode<Datum>) => number)): PackLayout<Datum>;
}
/**
* Pack siblings (circles) without hierarchy
* @param circles - Array of circle objects with r property
* @returns Array of circles with x, y positions
*/
function packSiblings<T extends {r: number}>(circles: T[]): Array<T & {x: number, y: number}>;
/**
* Enclose circles with smallest enclosing circle
* @param circles - Array of circles with x, y, r properties
* @returns Enclosing circle with x, y, r properties
*/
function packEnclose<T extends {x: number, y: number, r: number}>(circles: T[]): {x: number, y: number, r: number};Dendrogram layout that places all leaf nodes at the same depth.
/**
* Create cluster layout generator
* @returns Cluster layout function
*/
function cluster<Datum>(): ClusterLayout<Datum>;
interface ClusterLayout<Datum> {
/** Generate cluster layout for hierarchy */
(root: HierarchyNode<Datum>): HierarchyNode<Datum>;
/** Set layout size */
size(size: [number, number]): ClusterLayout<Datum>;
/** Set node size */
nodeSize(size: [number, number]): ClusterLayout<Datum>;
/** Set separation function between nodes */
separation(separation: (a: HierarchyNode<Datum>, b: HierarchyNode<Datum>) => number): ClusterLayout<Datum>;
}Convert tabular data into hierarchical structure for use with hierarchy layouts.
/**
* Create stratify operator for converting tabular data to hierarchy
* @returns Stratify operator
*/
function stratify<Datum>(): StratifyOperator<Datum>;
interface StratifyOperator<Datum> {
/** Convert flat data to hierarchy */
(data: Datum[]): HierarchyNode<Datum>;
/** Set node id accessor */
id(id: (d: Datum, i: number, data: Datum[]) => string): StratifyOperator<Datum>;
/** Set parent id accessor */
parentId(parentId: (d: Datum, i: number, data: Datum[]) => string | null | undefined): StratifyOperator<Datum>;
/** Set path accessor for delimited hierarchies */
path(path: (d: Datum, i: number, data: Datum[]) => string): StratifyOperator<Datum>;
}import { hierarchy, tree, forceSimulation, forceManyBody, forceLink, forceCenter } from "d3";
// Tree layout
const data = {
name: "root",
children: [
{ name: "child1" },
{ name: "child2", children: [{ name: "grandchild" }] }
]
};
const root = hierarchy(data);
const treeLayout = tree().size([400, 300]);
treeLayout(root);
// Force simulation
const nodes = [{ id: "a" }, { id: "b" }, { id: "c" }];
const links = [{ source: "a", target: "b" }, { source: "b", target: "c" }];
const simulation = forceSimulation(nodes)
.force("link", forceLink(links).id(d => d.id))
.force("charge", forceManyBody().strength(-300))
.force("center", forceCenter(200, 150));interface HierarchyNode<Datum> {
data: Datum;
depth: number;
height: number;
parent: HierarchyNode<Datum> | null;
children: HierarchyNode<Datum>[] | null;
value?: number;
x?: number;
y?: number;
}
interface Force<NodeDatum, LinkDatum> {
(alpha: number): void;
initialize?(nodes: NodeDatum[]): void;
}
interface SimulationNodeDatum {
index?: number;
x?: number;
y?: number;
vx?: number;
vy?: number;
fx?: number | null;
fy?: number | null;
}
interface SimulationLinkDatum<NodeDatum> {
source: NodeDatum | string | number;
target: NodeDatum | string | number;
index?: number;
}