Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generics for nodes and links in typescript #359

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 91 additions & 74 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export interface GraphData {
nodes: NodeObject[];
links: LinkObject[];
export interface TypedGraphData<N extends NodeObject, L extends TypedLinkObject<N>> {
nodes: N[];
links: L[];
}
export interface GraphData extends TypedGraphData<NodeObject, TypedLinkObject<NodeObject>> {}

export interface NodeObject {
id?: string | number;
Expand All @@ -13,14 +14,15 @@ export interface NodeObject {
fy?: number;
}

export interface LinkObject {
source?: string | number | NodeObject;
target?: string | number | NodeObject;
export interface TypedLinkObject<N extends NodeObject> {
source?: string | number | N;
target?: string | number | N;
}
export interface LinkObject extends TypedLinkObject<NodeObject> {}

type Accessor<In, Out> = Out | string | ((obj: In) => Out);
type NodeAccessor<T> = Accessor<NodeObject, T>;
type LinkAccessor<T> = Accessor<LinkObject, T>;
type NodeAccessor<N extends NodeObject, T> = Accessor<N, T>;
type LinkAccessor<N extends NodeObject, L extends TypedLinkObject<N>, T> = Accessor<L, T>;

type CanvasCustomRenderMode = 'replace' | 'before' | 'after';
export type CanvasCustomRenderModeFn<T> = (obj: T) => CanvasCustomRenderMode | any;
Expand All @@ -35,14 +37,19 @@ interface ForceFn {
[key: string]: any;
}

export interface ForceGraphGenericInstance<ChainableInstance> {
export interface FullTypedForceGraphGenericInstance<
N extends NodeObject,
L extends TypedLinkObject<N>,
D extends TypedGraphData<N, L>,
ChainableInstance
> {
(element: HTMLElement): ChainableInstance;
resetProps(): ChainableInstance;
_destructor(): void;

// Data input
graphData(): GraphData;
graphData(data: GraphData): ChainableInstance;
graphData(): D;
graphData(data: D): ChainableInstance;
nodeId(): string;
nodeId(id: string): ChainableInstance;
linkSource(): string;
Expand All @@ -61,59 +68,59 @@ export interface ForceGraphGenericInstance<ChainableInstance> {
// Node styling
nodeRelSize(): number;
nodeRelSize(size: number): ChainableInstance;
nodeVal(): NodeAccessor<number>;
nodeVal(valAccessor: NodeAccessor<number>): ChainableInstance;
nodeLabel(): NodeAccessor<string>;
nodeLabel(labelAccessor: NodeAccessor<string>): ChainableInstance;
nodeVisibility(): NodeAccessor<boolean>;
nodeVisibility(visibilityAccessor: NodeAccessor<boolean>): ChainableInstance;
nodeColor(): NodeAccessor<string>;
nodeColor(colorAccessor: NodeAccessor<string>): ChainableInstance;
nodeAutoColorBy(): NodeAccessor<string | null>;
nodeAutoColorBy(colorByAccessor: NodeAccessor<string | null>): ChainableInstance;
nodeCanvasObject(): CanvasCustomRenderFn<NodeObject>;
nodeCanvasObject(renderFn: CanvasCustomRenderFn<NodeObject>): ChainableInstance;
nodeCanvasObjectMode(): string | CanvasCustomRenderModeFn<NodeObject>;
nodeCanvasObjectMode(modeAccessor: string | CanvasCustomRenderModeFn<NodeObject>): ChainableInstance;
nodePointerAreaPaint(): CanvasPointerAreaPaintFn<NodeObject>;
nodePointerAreaPaint(renderFn: CanvasPointerAreaPaintFn<NodeObject>): ChainableInstance;
nodeVal(): NodeAccessor<N, number>;
nodeVal(valAccessor: NodeAccessor<N, number>): ChainableInstance;
nodeLabel(): NodeAccessor<N, string>;
nodeLabel(labelAccessor: NodeAccessor<N, string>): ChainableInstance;
nodeVisibility(): NodeAccessor<N, boolean>;
nodeVisibility(visibilityAccessor: NodeAccessor<N, boolean>): ChainableInstance;
nodeColor(): NodeAccessor<N, string>;
nodeColor(colorAccessor: NodeAccessor<N, string>): ChainableInstance;
nodeAutoColorBy(): NodeAccessor<N, string | null>;
nodeAutoColorBy(colorByAccessor: NodeAccessor<N, string | null>): ChainableInstance;
nodeCanvasObject(): CanvasCustomRenderFn<N>;
nodeCanvasObject(renderFn: CanvasCustomRenderFn<N>): ChainableInstance;
nodeCanvasObjectMode(): string | CanvasCustomRenderModeFn<N>;
nodeCanvasObjectMode(modeAccessor: string | CanvasCustomRenderModeFn<N>): ChainableInstance;
nodePointerAreaPaint(): CanvasPointerAreaPaintFn<N>;
nodePointerAreaPaint(renderFn: CanvasPointerAreaPaintFn<N>): ChainableInstance;

// Link styling
linkLabel(): LinkAccessor<string>;
linkLabel(labelAccessor: LinkAccessor<string>): ChainableInstance;
linkVisibility(): LinkAccessor<boolean>;
linkVisibility(visibilityAccessor: LinkAccessor<boolean>): ChainableInstance;
linkColor(): LinkAccessor<string>;
linkColor(colorAccessor: LinkAccessor<string>): ChainableInstance;
linkAutoColorBy(): LinkAccessor<string | null>;
linkAutoColorBy(colorByAccessor: LinkAccessor<string | null>): ChainableInstance;
linkLineDash(): LinkAccessor<number[] | null>;
linkLineDash(linkLineDashAccessor: LinkAccessor<number[] | null>): ChainableInstance;
linkWidth(): LinkAccessor<number>;
linkWidth(widthAccessor: LinkAccessor<number>): ChainableInstance;
linkCurvature(): LinkAccessor<number>;
linkCurvature(curvatureAccessor: LinkAccessor<number>): ChainableInstance;
linkCanvasObject(): CanvasCustomRenderFn<LinkObject>;
linkCanvasObject(renderFn: CanvasCustomRenderFn<LinkObject>): ChainableInstance;
linkCanvasObjectMode(): string | CanvasCustomRenderModeFn<LinkObject>;
linkCanvasObjectMode(modeAccessor: string | CanvasCustomRenderModeFn<LinkObject>): ChainableInstance;
linkDirectionalArrowLength(): LinkAccessor<number>;
linkDirectionalArrowLength(lengthAccessor: LinkAccessor<number>): ChainableInstance;
linkDirectionalArrowColor(): LinkAccessor<string>;
linkDirectionalArrowColor(colorAccessor: LinkAccessor<string>): ChainableInstance;
linkDirectionalArrowRelPos(): LinkAccessor<number>;
linkDirectionalArrowRelPos(fractionAccessor: LinkAccessor<number>): ChainableInstance;
linkDirectionalParticles(): LinkAccessor<number>;
linkDirectionalParticles(numParticlesAccessor: LinkAccessor<number>): ChainableInstance;
linkDirectionalParticleSpeed(): LinkAccessor<number>;
linkDirectionalParticleSpeed(relDistancePerFrameAccessor: LinkAccessor<number>): ChainableInstance;
linkDirectionalParticleWidth(): LinkAccessor<number>;
linkDirectionalParticleWidth(widthAccessor: LinkAccessor<number>): ChainableInstance;
linkDirectionalParticleColor(): LinkAccessor<string>;
linkDirectionalParticleColor(colorAccessor: LinkAccessor<string>): ChainableInstance;
emitParticle(link: LinkObject): ChainableInstance;
linkPointerAreaPaint(): CanvasPointerAreaPaintFn<LinkObject>;
linkPointerAreaPaint(renderFn: CanvasPointerAreaPaintFn<LinkObject>): ChainableInstance;
linkLabel(): LinkAccessor<N, L, string>;
linkLabel(labelAccessor: LinkAccessor<N, L, string>): ChainableInstance;
linkVisibility(): LinkAccessor<N, L, boolean>;
linkVisibility(visibilityAccessor: LinkAccessor<N, L, boolean>): ChainableInstance;
linkColor(): LinkAccessor<N, L, string>;
linkColor(colorAccessor: LinkAccessor<N, L, string>): ChainableInstance;
linkAutoColorBy(): LinkAccessor<N, L, string | null>;
linkAutoColorBy(colorByAccessor: LinkAccessor<N, L, string | null>): ChainableInstance;
linkLineDash(): LinkAccessor<N, L, number[] | null>;
linkLineDash(linkLineDashAccessor: LinkAccessor<N, L, number[] | null>): ChainableInstance;
linkWidth(): LinkAccessor<N, L, number>;
linkWidth(widthAccessor: LinkAccessor<N, L, number>): ChainableInstance;
linkCurvature(): LinkAccessor<N, L, number>;
linkCurvature(curvatureAccessor: LinkAccessor<N, L, number>): ChainableInstance;
linkCanvasObject(): CanvasCustomRenderFn<L>;
linkCanvasObject(renderFn: CanvasCustomRenderFn<L>): ChainableInstance;
linkCanvasObjectMode(): string | CanvasCustomRenderModeFn<L>;
linkCanvasObjectMode(modeAccessor: string | CanvasCustomRenderModeFn<L>): ChainableInstance;
linkDirectionalArrowLength(): LinkAccessor<N, L, number>;
linkDirectionalArrowLength(lengthAccessor: LinkAccessor<N, L, number>): ChainableInstance;
linkDirectionalArrowColor(): LinkAccessor<N, L, string>;
linkDirectionalArrowColor(colorAccessor: LinkAccessor<N, L, string>): ChainableInstance;
linkDirectionalArrowRelPos(): LinkAccessor<N, L, number>;
linkDirectionalArrowRelPos(fractionAccessor: LinkAccessor<N, L, number>): ChainableInstance;
linkDirectionalParticles(): LinkAccessor<N, L, number>;
linkDirectionalParticles(numParticlesAccessor: LinkAccessor<N, L, number>): ChainableInstance;
linkDirectionalParticleSpeed(): LinkAccessor<N, L, number>;
linkDirectionalParticleSpeed(relDistancePerFrameAccessor: LinkAccessor<N, L, number>): ChainableInstance;
linkDirectionalParticleWidth(): LinkAccessor<N, L, number>;
linkDirectionalParticleWidth(widthAccessor: LinkAccessor<N, L, number>): ChainableInstance;
linkDirectionalParticleColor(): LinkAccessor<N, L, string>;
linkDirectionalParticleColor(colorAccessor: LinkAccessor<N, L, string>): ChainableInstance;
emitParticle(link: L): ChainableInstance;
linkPointerAreaPaint(): CanvasPointerAreaPaintFn<L>;
linkPointerAreaPaint(renderFn: CanvasPointerAreaPaintFn<L>): ChainableInstance;

// Render control
autoPauseRedraw(): boolean;
Expand All @@ -124,7 +131,7 @@ export interface ForceGraphGenericInstance<ChainableInstance> {
centerAt(x?: number, y?: number, durationMs?: number): ChainableInstance;
zoom(): number;
zoom(scale: number, durationMs?: number): ChainableInstance;
zoomToFit(durationMs?: number, padding?: number, nodeFilter?: (node: NodeObject) => boolean): ChainableInstance;
zoomToFit(durationMs?: number, padding?: number, nodeFilter?: (node: N) => boolean): ChainableInstance;
minZoom(): number;
minZoom(scale: number): ChainableInstance;
maxZoom(): number;
Expand All @@ -137,8 +144,8 @@ export interface ForceGraphGenericInstance<ChainableInstance> {
dagMode(mode: DagMode | null): ChainableInstance;
dagLevelDistance(): number | null;
dagLevelDistance(distance: number): ChainableInstance;
dagNodeFilter(): (node: NodeObject) => boolean;
dagNodeFilter(filterFn: (node: NodeObject) => boolean): ChainableInstance;
dagNodeFilter(): (node: N) => boolean;
dagNodeFilter(filterFn: (node: N) => boolean): ChainableInstance;
onDagError(): (loopNodeIds: (string | number)[]) => void;
onDagError(errorHandleFn: (loopNodeIds: (string | number)[]) => void): ChainableInstance;
d3AlphaMin(): number;
Expand All @@ -160,14 +167,14 @@ export interface ForceGraphGenericInstance<ChainableInstance> {
onEngineStop(callback: () => void): ChainableInstance;

// Interaction
onNodeClick(callback: (node: NodeObject, event: MouseEvent) => void): ChainableInstance;
onNodeRightClick(callback: (node: NodeObject, event: MouseEvent) => void): ChainableInstance;
onNodeHover(callback: (node: NodeObject | null, previousNode: NodeObject | null) => void): ChainableInstance;
onNodeDrag(callback: (node: NodeObject, translate: { x: number, y: number }) => void): ChainableInstance;
onNodeDragEnd(callback: (node: NodeObject, translate: { x: number, y: number }) => void): ChainableInstance;
onLinkClick(callback: (link: LinkObject, event: MouseEvent) => void): ChainableInstance;
onLinkRightClick(callback: (link: LinkObject, event: MouseEvent) => void): ChainableInstance;
onLinkHover(callback: (link: LinkObject | null, previousLink: LinkObject | null) => void): ChainableInstance;
onNodeClick(callback: (node: N, event: MouseEvent) => void): ChainableInstance;
onNodeRightClick(callback: (node: N, event: MouseEvent) => void): ChainableInstance;
onNodeHover(callback: (node: N | null, previousNode: N | null) => void): ChainableInstance;
onNodeDrag(callback: (node: N, translate: { x: number, y: number }) => void): ChainableInstance;
onNodeDragEnd(callback: (node: N, translate: { x: number, y: number }) => void): ChainableInstance;
onLinkClick(callback: (link: L, event: MouseEvent) => void): ChainableInstance;
onLinkRightClick(callback: (link: L, event: MouseEvent) => void): ChainableInstance;
onLinkHover(callback: (link: L | null, previousLink: L | null) => void): ChainableInstance;
linkHoverPrecision(): number;
linkHoverPrecision(precision: number): ChainableInstance;
onBackgroundClick(callback: (event: MouseEvent) => void): ChainableInstance;
Expand All @@ -184,13 +191,23 @@ export interface ForceGraphGenericInstance<ChainableInstance> {
enablePointerInteraction(enable?: boolean): ChainableInstance;

// Utility
getGraphBbox(nodeFilter?: (node: NodeObject) => boolean): { x: [number, number], y: [number, number] };
getGraphBbox(nodeFilter?: (node: N) => 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 };
}

export interface TypedForceGraphGenericInstance<
N extends NodeObject,
L extends TypedLinkObject<N>,
ChainableInstance
> extends FullTypedForceGraphGenericInstance<N, L, TypedGraphData<N, L>, ChainableInstance> {}
export interface ForceGraphGenericInstance<ChainableInstance> extends FullTypedForceGraphGenericInstance<NodeObject, LinkObject, GraphData, ChainableInstance> {}

export type TypedForceGraphInstance<N extends NodeObject, L extends TypedLinkObject<N>> = TypedForceGraphGenericInstance<N, L, TypedForceGraphInstance<N, L>>;
export type ForceGraphInstance = ForceGraphGenericInstance<ForceGraphInstance>;

declare function TypedForceGraph<N extends NodeObject, L extends TypedLinkObject<N>>(): TypedForceGraphInstance<N, L>;
declare function ForceGraph(): ForceGraphInstance;

export {TypedForceGraph};
export default ForceGraph;
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import './force-graph.css';
import ForceGraph from './force-graph';

export { default } from "./force-graph";
export {ForceGraph as TypedForceGraph};
export default ForceGraph;