UNPKG

@tanstack/charts

Version:

A chart grammar for TypeScript and JavaScript. Marks consume your data directly, channels describe visual encodings, and the engine compiles them into a renderer-neutral keyed scene. TanStack's compact scales cover common numeric and categorical mappings.

105 lines (104 loc) 6.37 kB
import type { TransformLineage, TransformValue, TransformValueOutput } from './transform.js'; import type { ChartKey } from './types.js'; import type { Force, SimulationLinkDatum, SimulationNodeDatum } from 'd3-force'; export type ForceNumericValue<TDatum> = number | TransformValue<TDatum, number>; export interface ForceLinkDescriptor<TLink> { readonly type: 'link'; readonly distance?: ForceNumericValue<TLink>; readonly strength?: ForceNumericValue<TLink>; } export interface ForceManyBodyDescriptor<TNode> { readonly type: 'manyBody'; readonly strength?: ForceNumericValue<TNode>; } export interface ForceCenterDescriptor { readonly type: 'center'; readonly x?: number; readonly y?: number; } export interface ForceCollideDescriptor<TNode> { readonly type: 'collide'; readonly radius?: ForceNumericValue<TNode>; readonly strength?: number; } export interface ForceXDescriptor<TNode> { readonly type: 'x'; readonly x?: ForceNumericValue<TNode>; readonly strength?: ForceNumericValue<TNode>; } export interface ForceYDescriptor<TNode> { readonly type: 'y'; readonly y?: ForceNumericValue<TNode>; readonly strength?: ForceNumericValue<TNode>; } /** A private node clone initialized and mutated only by the D3 simulation. */ export type ForceLayoutWorkingNode<TNode extends object> = Omit<TNode, keyof SimulationNodeDatum> & SimulationNodeDatum; /** A private link clone whose endpoints may be resolved by a D3 link force. */ export type ForceLayoutWorkingLink<TNode extends object, TLink extends object> = Omit<TLink, keyof SimulationLinkDatum<ForceLayoutWorkingNode<TNode>>> & SimulationLinkDatum<ForceLayoutWorkingNode<TNode>>; export interface ForceFactoryContext<TNode extends object, TLink extends object, TNodeKey extends ChartKey = ChartKey> { readonly nodes: ForceLayoutWorkingNode<TNode>[]; readonly links: ForceLayoutWorkingLink<TNode, TLink>[]; readonly nodeKeys: readonly TNodeKey[]; readonly sourceKeys: readonly ChartKey[]; readonly targetKeys: readonly ChartKey[]; readonly nodeKey: (node: ForceLayoutWorkingNode<TNode>, index: number) => TNodeKey; } export type ForceFactory<TNode extends object, TLink extends object, TNodeKey extends ChartKey = ChartKey> = (context: ForceFactoryContext<TNode, TLink, TNodeKey>) => Force<ForceLayoutWorkingNode<TNode>, ForceLayoutWorkingLink<TNode, TLink>>; export interface ForceFactoryDescriptor<TNode extends object, TLink extends object, TNodeKey extends ChartKey = ChartKey> { readonly type: 'custom'; readonly name: string; readonly create: ForceFactory<TNode, TLink, TNodeKey>; } export type ForceDescriptor<TNode extends object, TLink extends object, TNodeKey extends ChartKey = ChartKey> = ForceLinkDescriptor<TLink> | ForceManyBodyDescriptor<TNode> | ForceCenterDescriptor | ForceCollideDescriptor<TNode> | ForceXDescriptor<TNode> | ForceYDescriptor<TNode> | ForceFactoryDescriptor<TNode, TLink, TNodeKey>; export interface ForceLayoutOptions<TNode extends object, TLink extends object, TNodeKey extends TransformValue<TNode, ChartKey> = TransformValue<TNode, ChartKey>, TSource extends TransformValue<TLink, ChartKey> = TransformValue<TLink, ChartKey>, TTarget extends TransformValue<TLink, ChartKey> = TransformValue<TLink, ChartKey>> { readonly nodeKey: TNodeKey; readonly source: TSource; readonly target: TTarget; /** Number of synchronous simulation ticks. Defaults to D3's natural 300. */ readonly iterations?: number; /** Fraction of each positional span added to both domain ends. Defaults to 0.2. */ readonly domainPadding?: number; /** Forces are initialized and applied in authored order. */ readonly forces: readonly ForceDescriptor<TNode, TLink, Extract<TransformValueOutput<TNode, TNodeKey>, ChartKey>>[]; } export type ForceLayoutNode<TNode> = Omit<TNode, keyof TransformLineage<TNode> | 'x' | 'y' | 'vx' | 'vy'> & TransformLineage<TNode> & { readonly x: number; readonly y: number; readonly vx: number; readonly vy: number; }; /** * Link lineage uses `sourceRows` because `source` remains the raw graph endpoint. * This is the deliberate exception to the ordinary `TransformLineage` field name. */ export interface ForceLinkLineage<TLink> { readonly sourceRows: readonly TLink[]; readonly sourceIndexes: readonly number[]; } type ForceLinkDerivedFields = keyof ForceLinkLineage<unknown> | 'source' | 'target' | 'sourceNode' | 'targetNode' | 'sourceIndex' | 'targetIndex' | 'sourceKey' | 'targetKey' | 'x1' | 'y1' | 'x2' | 'y2'; export type ForceLayoutLink<TNode, TLink, TSourceKey extends ChartKey = ChartKey, TTargetKey extends ChartKey = ChartKey> = Omit<TLink, ForceLinkDerivedFields> & ForceLinkLineage<TLink> & { /** Raw source identifier, preserved after D3 resolves its private clone. */ readonly source: TSourceKey; /** Raw target identifier, preserved after D3 resolves its private clone. */ readonly target: TTargetKey; readonly sourceKey: TSourceKey; readonly targetKey: TTargetKey; readonly sourceIndex: number; readonly targetIndex: number; readonly sourceNode: ForceLayoutNode<TNode>; readonly targetNode: ForceLayoutNode<TNode>; readonly x1: number; readonly y1: number; readonly x2: number; readonly y2: number; }; export interface ForceLayoutResult<TNode, TLink, TSourceKey extends ChartKey = ChartKey, TTargetKey extends ChartKey = ChartKey> { readonly nodes: readonly ForceLayoutNode<TNode>[]; readonly links: readonly ForceLayoutLink<TNode, TLink, TSourceKey, TTargetKey>[]; readonly xDomain: readonly [number, number]; readonly yDomain: readonly [number, number]; } type EndpointKey<TDatum, TValue> = Extract<TransformValueOutput<TDatum, TValue>, ChartKey>; /** Settles a deterministic, synchronous D3 force simulation over private clones. */ export declare function forceLayout<TNode extends object, TLink extends object, const TNodeKey extends TransformValue<TNode, ChartKey>, const TSource extends TransformValue<TLink, ChartKey>, const TTarget extends TransformValue<TLink, ChartKey>>(nodes: Iterable<TNode>, links: Iterable<TLink>, options: ForceLayoutOptions<NoInfer<TNode>, NoInfer<TLink>, TNodeKey, TSource, TTarget>): ForceLayoutResult<TNode, TLink, EndpointKey<TLink, TSource>, EndpointKey<TLink, TTarget>>; export {};