react-force-graph-2d
Version:
React component for 2D force directed graphs
153 lines (131 loc) • 5.72 kB
TypeScript
import * as React from 'react';
import { ForceGraphInstance } from 'force-graph';
interface GraphData {
nodes: NodeObject[];
links: LinkObject[];
}
type NodeObject = object & {
id?: string | number;
x?: number;
y?: number;
vx?: number;
vy?: number;
fx?: number;
fy?: number;
};
type LinkObject = object & {
source?: string | number | NodeObject;
target?: string | number | NodeObject;
};
type Accessor<In, Out> = Out | string | ((obj: In) => Out);
type NodeAccessor<T> = Accessor<NodeObject, T>;
type LinkAccessor<T> = Accessor<LinkObject, T>;
type CanvasCustomRenderMode = 'replace' | 'before' | 'after';
type CanvasCustomRenderFn<T> = (obj: T, canvasContext: CanvasRenderingContext2D, globalScale: number) => void;
type CanvasPointerAreaPaintFn<T> = (obj: T, paintColor: string, canvasContext: CanvasRenderingContext2D, globalScale: number) => void;
type DagMode = 'td' | 'bu' | 'lr' | 'rl' | 'radialout' | 'radialin';
interface ForceFn {
(alpha: number): void;
initialize?: (nodes: NodeObject[], ...args: any[]) => void;
[key: string]: any;
}
interface ForceGraphProps {
// Data input
graphData?: GraphData;
nodeId?: string;
linkSource?: string;
linkTarget?: string;
// Container layout
width?: number;
height?: number;
backgroundColor?: string;
// Node styling
nodeRelSize?: number;
nodeVal?: NodeAccessor<number>;
nodeLabel?: NodeAccessor<string>;
nodeVisibility?: NodeAccessor<boolean>;
nodeColor?: NodeAccessor<string>;
nodeAutoColorBy?: NodeAccessor<string | null>;
nodeCanvasObjectMode?: string | ((obj: NodeObject) => CanvasCustomRenderMode);
nodeCanvasObject?: CanvasCustomRenderFn<NodeObject>;
nodePointerAreaPaint?: CanvasPointerAreaPaintFn<NodeObject>;
// Link styling
linkLabel?: LinkAccessor<string>;
linkVisibility?: LinkAccessor<boolean>;
linkColor?: LinkAccessor<string>;
linkAutoColorBy?: LinkAccessor<string | null>;
linkLineDash?: LinkAccessor<number[] | null>;
linkWidth?: LinkAccessor<number>;
linkCurvature?: LinkAccessor<number>;
linkCanvasObject?: CanvasCustomRenderFn<LinkObject>;
linkCanvasObjectMode?: string | ((obj: LinkObject) => CanvasCustomRenderMode);
linkDirectionalArrowLength?: LinkAccessor<number>;
linkDirectionalArrowColor?: LinkAccessor<string>;
linkDirectionalArrowRelPos?: LinkAccessor<number>;
linkDirectionalParticles?: LinkAccessor<number>;
linkDirectionalParticleSpeed?: LinkAccessor<number>;
linkDirectionalParticleWidth?: LinkAccessor<number>;
linkDirectionalParticleColor?: LinkAccessor<string>;
linkPointerAreaPaint?: CanvasPointerAreaPaintFn<LinkObject>;
// Render control
autoPauseRedraw?: boolean;
minZoom?: number;
maxZoom?: number;
onRenderFramePre?: (canvasContext: CanvasRenderingContext2D, globalScale: number) => void;
onRenderFramePost?: (canvasContext: CanvasRenderingContext2D, globalScale: number) => void;
// Force engine (d3-force) configuration
dagMode?: DagMode;
dagLevelDistance?: number | null;
dagNodeFilter?: (node: NodeObject) => boolean;
onDagError?: ((loopNodeIds: (string | number)[]) => void) | undefined;
d3AlphaMin?: number;
d3AlphaDecay?: number;
d3VelocityDecay?: number;
ngraphPhysics?: object;
warmupTicks?: number;
cooldownTicks?: number;
cooldownTime?: number;
onEngineTick?: () => void;
onEngineStop?: () => void;
// Interaction
onNodeClick?: (node: NodeObject, event: MouseEvent) => void;
onNodeRightClick?: (node: NodeObject, event: MouseEvent) => void;
onNodeHover?: (node: NodeObject | null, previousNode: NodeObject | null) => void;
onNodeDrag?: (node: NodeObject, translate: { x: number, y: number }) => void;
onNodeDragEnd?: (node: NodeObject, translate: { x: number, y: number }) => void;
onLinkClick?: (link: LinkObject, event: MouseEvent) => void;
onLinkRightClick?: (link: LinkObject, event: MouseEvent) => void;
onLinkHover?: (link: LinkObject | null, previousLink: LinkObject | null) => void;
linkHoverPrecision?: number;
onBackgroundClick?: (event: MouseEvent) => void;
onBackgroundRightClick?: (event: MouseEvent) => void;
onZoom?: (transform: {k: number, x: number, y: number}) => void;
onZoomEnd?: (transform: {k: number, x: number, y: number}) => void;
enableNodeDrag?: boolean;
enableZoomInteraction?: boolean;
enablePanInteraction?: boolean;
enablePointerInteraction?: boolean;
}
interface ForceGraphMethods {
// Link styling
emitParticle(link: LinkObject): ForceGraphInstance;
// Force engine (d3-force) configuration
d3Force(forceName: 'link' | 'charge' | 'center' | string): ForceFn | undefined;
d3Force(forceName: 'link' | 'charge' | 'center' | string, forceFn: ForceFn): ForceGraphInstance;
d3ReheatSimulation(): ForceGraphInstance;
// Render control
pauseAnimation(): ForceGraphInstance;
resumeAnimation(): ForceGraphInstance;
centerAt(): {x: number, y: number};
centerAt(x?: number, y?: number, durationMs?: number): ForceGraphInstance;
zoom(): number;
zoom(scale: number, durationMs?: number): ForceGraphInstance;
zoomToFit(durationMs?: number, padding?: number, nodeFilter?: (node: NodeObject) => boolean): ForceGraphInstance;
// Utility
getGraphBbox(nodeFilter?: (node: NodeObject) => boolean): { x: [number, number], y: [number, number] };
screen2GraphCoords(x: number, y: number): { x: number, y: number };
graph2ScreenCoords(x: number, y: number): { x: number, y: number };
}
type FCwithRef<P = {}, R = {}> = React.FunctionComponent<P & { ref?: React.MutableRefObject<R | undefined> }>;
declare const ForceGraph: FCwithRef<ForceGraphProps, ForceGraphMethods>;
export { ForceGraphMethods, ForceGraphProps, GraphData, LinkObject, NodeObject, ForceGraph as default };