d3-graph-controller
Version:
A TypeScript library for visualizing and simulating directed, interactive graphs.
735 lines (734 loc) • 22.1 kB
text/typescript
import { Selection } from "d3-selection";
import { ZoomBehavior } from "d3-zoom";
import { D3DragEvent, DragBehavior } from "d3-drag";
import { Simulation, SimulationLinkDatum, SimulationNodeDatum } from "d3-force";
//#region src/model/shared.d.ts
/**
* Label configuration.
*/
interface Label {
/**
* The color of the label.
* Can be any valid CSS expression.
*/
readonly color: string;
/**
* The font size of the label.
* Can be any valid CSS expression.
*/
readonly fontSize: string;
/**
* The text of the label.
*/
readonly text: string;
}
//#endregion
//#region src/model/node.d.ts
/**
* Node representing a datum of a graph.
*/
interface GraphNode<T extends NodeTypeToken = NodeTypeToken> extends SimulationNodeDatum {
/**
* The type of the node.
*/
readonly type: T;
/**
* The ID of the node.
*/
readonly id: string;
/**
* The color of the node.
* Can be any valid CSS expression.
*/
readonly color: string;
/**
* The label of the node.
* Using false will disable the node's label.
*/
readonly label: false | Label;
/**
* The focus state of a node.
* Warning: Used for internal logic. Should not be set manually!
*/
isFocused: boolean;
/**
* The x-coordinate of a node.
*/
x?: number | undefined;
/**
* The y-coordinate of a node.
*/
y?: number | undefined;
/**
* The fixed x-coordinate of a node.
* If set, the node will not be simulated.
*/
fx?: number | undefined;
/**
* The fixed y-coordinate of a node.
* If set, the node will not be simulated.
*/
fy?: number | undefined;
/**
* Timestamp of the node's last interaction.
* Warning: Used for internal logic. Should not be set manually!
*/
lastInteractionTimestamp?: number | undefined;
}
/**
* Define a node with type inference.
* @param data - The data of the node.
*/
declare function defineNode<T extends NodeTypeToken = NodeTypeToken, Node extends GraphNode<T> = GraphNode<T>>(data: Node): Node;
/**
* Define a node with type inference and some default values.
* @param data - The data of the node.
*/
declare function defineNodeWithDefaults<T extends NodeTypeToken = NodeTypeToken>(data: Partial<GraphNode<T>> & Pick<GraphNode, "id" | "type">): GraphNode<T>;
//#endregion
//#region src/model/link.d.ts
/**
* Link defining an edge from one node to another.
*/
interface GraphLink<T extends NodeTypeToken = NodeTypeToken, SourceNode extends GraphNode<T> = GraphNode<T>, TargetNode extends GraphNode<T> = SourceNode> extends SimulationLinkDatum<SourceNode | TargetNode> {
/**
* The source node of the link.
*/
readonly source: SourceNode;
/**
* The target node of the link
*/
readonly target: TargetNode;
/**
* The color of the link.
* Can be any valid CSS expression.
*/
readonly color: string;
/**
* The label of the node.
* Using false will disable the node's label.
*/
readonly label: false | Label;
}
/**
* Define a link with type inference.
* @param data - The data of the link.
*/
declare function defineLink<T extends NodeTypeToken = NodeTypeToken, SourceNode extends GraphNode<T> = GraphNode<T>, TargetNode extends GraphNode<T> = SourceNode, Link extends GraphLink<T, SourceNode, TargetNode> = GraphLink<T, SourceNode, TargetNode>>(data: Link): Link;
//#endregion
//#region src/model/graph.d.ts
/**
* Type token for nodes.
*/
type NodeTypeToken = string;
/**
* Graph containing nodes and links.
*/
interface Graph<T extends NodeTypeToken = NodeTypeToken, Node extends GraphNode<T> = GraphNode<T>, Link extends GraphLink<T, Node> = GraphLink<T, Node>> {
/**
* The nodes of the graph.
*/
readonly nodes: Node[];
/**
* The links of the graph.
*/
readonly links: Link[];
}
/**
* Define a graph with type inference.
* @param data - The nodes and links of the graph. If either are omitted, they default to an empty array.
*/
declare function defineGraph<T extends NodeTypeToken = NodeTypeToken, Node extends GraphNode<T> = GraphNode<T>, Link extends GraphLink<T, Node> = GraphLink<T, Node>>({
nodes,
links
}: Partial<Graph<T, Node, Link>>): Graph<T, Node, Link>;
//#endregion
//#region src/config/alpha.d.ts
/**
* Alpha values when label display changes.
*/
interface LabelAlphas {
/**
* Alpha value when labels are turned off.
*/
readonly hide: number;
/**
* Alpha value when labels are turned on.
*/
readonly show: number;
}
/**
* Context of a resize.
*/
interface ResizeContext {
/**
* The old height.
*/
readonly oldHeight: number;
/**
* The old width.
*/
readonly oldWidth: number;
/**
* The new height.
*/
readonly newHeight: number;
/**
* The new width.
*/
readonly newWidth: number;
}
/**
* Alpha value configuration for controlling simulation activity.
*/
interface AlphaConfig<T extends NodeTypeToken, Node extends GraphNode<T>> {
/**
* Target alpha values for dragging.
*/
readonly drag: {
/**
* Target alpha when a drag starts.
* Should be larger than 0.
*/
readonly start: number;
/**
* Target alpha when a drag stops.
* Should generally be 0.
*/
readonly end: number;
};
/**
* Alpha values for filter changes.
*/
readonly filter: {
/**
* Alpha value when the link filter changes.
*/
readonly link: number;
/**
* Alpha value when the node type filter changes.
*/
readonly type: number;
/**
* Alpha values when the inclusion of unlinked nodes changes.
*/
readonly unlinked: {
/**
* Alpha value when unlinked nodes are included.
*/
readonly include: number;
/**
* Alpha value when unlinked nodes are excluded.
*/
readonly exclude: number;
};
};
/**
* Alpha values when node focus changes.
*/
readonly focus: {
/**
* Alpha value when a node is focused.
* @param node - The focused node.
* @returns The alpha value.
*/
readonly acquire: (node: Node) => number;
/**
* Alpha value when a node is unfocused.
* @param node - The unfocused node.
* @returns The alpha value.
*/
readonly release: (node: Node) => number;
};
/**
* Alpha value when the graph is initialized.
*/
readonly initialize: number;
/**
* Alpha values when label display changes.
*/
readonly labels: {
/**
* Alpha values when link label display changes.
*/
readonly links: LabelAlphas;
/**
* Alpha values when node label display changes.
*/
readonly nodes: LabelAlphas;
};
/**
* Alpha values when the graph is resized.
*/
readonly resize: number | ((context: ResizeContext) => number);
}
/**
* Create the default alpha configuration.
*/
declare function createDefaultAlphaConfig<T extends NodeTypeToken, Node extends GraphNode<T>>(): AlphaConfig<T, Node>;
//#endregion
//#region src/config/callbacks.d.ts
/**
* Callback configuration.
*/
interface Callbacks<T extends NodeTypeToken, Node extends GraphNode<T>> {
/**
* Callback when a node is double-clicked or double-tapped.
* @param node - The node.
*/
readonly nodeClicked?: (node: Node) => void;
}
//#endregion
//#region src/config/filter.d.ts
/**
* Link filter.
* Receives a link and returns whether the link should be included or not.
*/
type LinkFilter<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> = (link: Link) => boolean;
//#endregion
//#region src/config/initial.d.ts
/**
* Initial settings of a controller.
*/
interface InitialGraphSettings<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> {
/**
* Whether nodes without incoming or outgoing links will be shown or not.
*/
readonly includeUnlinked: boolean;
/**
* Link filter that decides whether links should be included or not.
*/
readonly linkFilter: LinkFilter<T, Node, Link>;
/**
* Node types that should be included.
* If undefined, all node types will be included.
*/
readonly nodeTypeFilter?: T[] | undefined;
/**
* Whether link labels are shown or not.
*/
readonly showLinkLabels: boolean;
/**
* Whether node labels are shown or not.
*/
readonly showNodeLabels: boolean;
}
/**
* Create default initial settings.
*/
declare function createDefaultInitialGraphSettings<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>>(): InitialGraphSettings<T, Node, Link>;
//#endregion
//#region src/config/marker.d.ts
/**
* Marker configuration.
*/
interface MarkerConfig {
/**
* Size of the marker's box.
*/
readonly size: number;
/**
* Get padding of the marker for calculating link paths.
* @param node - The node the marker is pointing at.
* @param config - The current config.
* @returns The padding of the marker.
*/
readonly padding: <T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>>(node: Node, config: GraphConfig<T, Node, Link>) => number;
/**
* The ref of the marker.
*/
readonly ref: [number, number];
/**
* The path of the marker.
*/
readonly path: [number, number][];
/**
* The ViewBox of the marker.
*/
readonly viewBox: string;
}
/**
* Collection of built-in markers.
*/
declare const Markers: {
/**
* Create an arrow marker configuration.
* @param size - The size of the arrow
*/
Arrow: (size: number) => MarkerConfig;
};
//#endregion
//#region src/lib/types.d.ts
type Canvas = Selection<SVGGElement, undefined, null, undefined>;
type Drag<T extends NodeTypeToken, Node extends GraphNode<T>> = DragBehavior<SVGGElement, Node, Node>;
type NodeDragEvent<T extends NodeTypeToken, Node extends GraphNode<T>> = D3DragEvent<SVGCircleElement, Node, Node>;
type GraphHost = Selection<HTMLDivElement, undefined, null, undefined>;
type GraphSimulation<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> = Simulation<Node, Link>;
type LinkSelection<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> = Selection<SVGGElement, Link, SVGGElement, undefined>;
type MarkerSelection = Selection<SVGMarkerElement, string, SVGGElement, undefined>;
type NodeSelection<T extends NodeTypeToken, Node extends GraphNode<T>> = Selection<SVGGElement, Node, SVGGElement, undefined>;
type Zoom = ZoomBehavior<SVGSVGElement, undefined>;
//#endregion
//#region src/config/modifiers.d.ts
/**
* Modifier for the drag.
*/
type DragModifier<T extends NodeTypeToken, Node extends GraphNode<T>> = (drag: Drag<T, Node>) => void;
/**
* Modifier for node circles.
*/
type NodeModifier<T extends NodeTypeToken, Node extends GraphNode<T>> = (selection: Selection<SVGCircleElement, Node, SVGGElement, undefined>) => void;
/**
* Modifier for node labels.
*/
type NodeLabelModifier<T extends NodeTypeToken, Node extends GraphNode<T>> = (selection: Selection<SVGTextElement, Node, SVGGElement, undefined>) => void;
/**
* Modifier for link paths.
*/
type LinkModifier<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> = (selection: Selection<SVGPathElement, Link, SVGGElement, undefined>) => void;
/**
* Modifier for link labels.
*/
type LinkLabelModifier<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> = (selection: Selection<SVGTextElement, Link, SVGGElement, undefined>) => void;
/**
* Modifier for the simulation.
*/
type SimulationModifier<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> = (simulation: GraphSimulation<T, Node, Link>) => void;
/**
* Modifier for the zoom.
*/
type ZoomModifier = (zoom: Zoom) => void;
/**
* Low-level callbacks for modifying the underlying d3-selection.wd
*/
interface Modifiers<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> {
/**
* Modify the drag.
* @param drag - The drag.
*/
readonly drag?: DragModifier<T, Node>;
/**
* Modify the node selection.
* @param selection - The selection of nodes.
*/
readonly node?: NodeModifier<T, Node>;
/**
* Modify the node label selection.
* @param selection - The selection of node labels.
*/
readonly nodeLabel?: NodeLabelModifier<T, Node>;
/**
* Modify the link selection.
* @param selection - The selection of links.
*/
readonly link?: LinkModifier<T, Node, Link>;
/**
* Modify the link label selection.
* @param selection - The selection of link labels.
*/
readonly linkLabel?: LinkLabelModifier<T, Node, Link>;
/**
* Modify the simulation.
* @param simulation - The simulation.
*/
readonly simulation?: SimulationModifier<T, Node, Link>;
/**
* Modify the zoom.
* @param zoom - The zoom.
*/
readonly zoom?: ZoomModifier;
}
//#endregion
//#region src/config/position.d.ts
/**
* Initializes a node's position in context of a graph's width and height.
*/
type PositionInitializer<T extends NodeTypeToken, Node extends GraphNode<T>> = (node: Node, width: number, height: number) => [number, number];
declare function Stable<T extends NodeTypeToken, Node extends GraphNode<T>>(previousGraph: Graph<T, Node>): PositionInitializer<T, Node>;
/**
* Collection of built-in position initializers.
*/
declare const PositionInitializers: {
/**
* Initializes node positions to a graph's center.
*/
Centered: PositionInitializer<string, GraphNode<string>>;
/**
* Randomly initializes node positions within the visible area.
*/
Randomized: PositionInitializer<string, GraphNode<string>>;
/**
* Initializes node positions based on other graph.
*/
Stable: typeof Stable;
};
//#endregion
//#region src/config/forces.d.ts
/**
* Simulation force.
*/
interface Force<Subject> {
/**
* Whether the force is enabled.
*/
readonly enabled: boolean;
/**
* The strength of the force.
* Can be a static number or a function receiving the force's subject and returning a number.
*/
readonly strength: number | ((subject: Subject) => number);
}
/**
* Simulation force applied to nodes.
*/
type NodeForce<T extends NodeTypeToken, Node extends GraphNode<T>> = Force<Node>;
/**
* Collision force applied to nodes.
*/
interface CollisionForce<T extends NodeTypeToken, Node extends GraphNode<T>> extends NodeForce<T, Node> {
/**
* Multiplier of the node radius.
* Tip: Large values can drastically reduce link intersection.
*/
readonly radiusMultiplier: number;
}
/**
* Simulation force applied to links.
*/
interface LinkForce<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> extends Force<Link> {
/**
* Define the length of a link for the simulation.
*/
readonly length: number | ((link: Link) => number);
}
/**
* Simulation force configuration.
*/
interface SimulationForceConfig<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> {
/**
* Centering force applied to nodes.
*/
readonly centering: false | NodeForce<T, Node>;
/**
* Charge force applied to nodes.
*/
readonly charge: false | NodeForce<T, Node>;
/**
* Collision force applied to nodes.
*/
readonly collision: false | CollisionForce<T, Node>;
/**
* Link force applied to links.
*/
readonly link: false | LinkForce<T, Node, Link>;
}
/**
* Create the default force configuration.
*/
declare function createDefaultForceConfig<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>>(): SimulationForceConfig<T, Node, Link>;
//#endregion
//#region src/config/simulation.d.ts
interface SimulationConfig<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> {
/**
* Alpha value configuration.
*/
readonly alphas: AlphaConfig<T, Node>;
/**
* Force configuration.
*/
readonly forces: SimulationForceConfig<T, Node, Link>;
}
//#endregion
//#region src/config/zoom.d.ts
/**
* Zoom configuration.
*/
interface ZoomConfig {
/**
* The initial zoom.
* Must be in range [min, max].
*/
readonly initial: number;
/**
* Maximum zoom level.
* May not be smaller than initial zoom.
*/
readonly max: number;
/**
* Minimum zoom level.
* May not be larger than initial zoom or less than or equal to 0.
*/
readonly min: number;
}
//#endregion
//#region src/config/config.d.ts
interface GraphConfig<T extends NodeTypeToken, Node extends GraphNode<T>, Link extends GraphLink<T, Node>> {
/**
* Set to true to enable automatic resizing.
* Warning: Do call shutdown(), once the controller is no longer required.
*/
readonly autoResize: boolean;
/**
* Callback configuration.
*/
readonly callbacks: Callbacks<T, Node>;
readonly hooks: {
afterZoom?: (scale: number, xOffset: number, yOffset: number) => void;
};
/**
* Initial settings of a controller.
*/
readonly initial: InitialGraphSettings<T, Node, Link>;
/**
* Marker configuration.
*/
readonly marker: MarkerConfig;
/**
* Low-level callbacks for modifying the underlying d3-selection.
*/
readonly modifiers: Modifiers<T, Node, Link>;
/**
* Define the radius of a node for the simulation and visualization.
* Can be a static number or a function receiving a node as its parameter.
*/
readonly nodeRadius: number | ((node: Node) => number);
/**
* Initializes a node's position in context of a graph's width and height.
*/
readonly positionInitializer: PositionInitializer<T, Node>;
/**
* Simulation configuration.
*/
readonly simulation: SimulationConfig<T, Node, Link>;
/**
* Zoom configuration.
*/
readonly zoom: ZoomConfig;
}
/**
* Utility type for deeply partial objects.
*/
type DeepPartial<T> = { readonly [P in keyof T]?: DeepPartial<T[P]> };
/**
* Define the configuration of a controller.
* Will be merged with the default configuration.
* @param config - The partial configuration.
* @returns The merged configuration.
*/
declare function defineGraphConfig<T extends NodeTypeToken = NodeTypeToken, Node extends GraphNode<T> = GraphNode<T>, Link extends GraphLink<T, Node> = GraphLink<T, Node>>(config?: DeepPartial<GraphConfig<T, Node, Link>>): GraphConfig<T, Node, Link>;
//#endregion
//#region src/controller.d.ts
/**
* Controller for a graph view.
*/
declare class GraphController<T extends NodeTypeToken = NodeTypeToken, Node extends GraphNode<T> = GraphNode<T>, Link extends GraphLink<T, Node> = GraphLink<T, Node>> {
/**
* Array of all node types included in the controller's graph.
*/
readonly nodeTypes: T[];
private _nodeTypeFilter;
private _includeUnlinked;
private _linkFilter;
private _showLinkLabels;
private _showNodeLabels;
private filteredGraph;
private width;
private height;
private simulation;
private canvas;
private linkSelection;
private nodeSelection;
private markerSelection;
private zoom;
private drag;
private xOffset;
private yOffset;
private scale;
private focusedNode;
private resizeObserver?;
private readonly container;
private readonly graph;
private readonly config;
/**
* Create a new controller and initialize the view.
* @param container - The container the graph will be placed in.
* @param graph - The graph of the controller.
* @param config - The config of the controller.
*/
constructor(container: HTMLDivElement, graph: Graph<T, Node, Link>, config: GraphConfig<T, Node, Link>);
/**
* Get the current node type filter.
* Only nodes whose type is included will be shown.
*/
get nodeTypeFilter(): T[];
/**
* Get whether nodes without incoming or outgoing links will be shown or not.
*/
get includeUnlinked(): boolean;
/**
* Set whether nodes without incoming or outgoing links will be shown or not.
* @param value - The value.
*/
set includeUnlinked(value: boolean);
/**
* Set a new link filter and update the controller's state.
* @param value - The new link filter.
*/
set linkFilter(value: LinkFilter<T, Node, Link>);
/**
* Get the current link filter.
* @returns - The current link filter.
*/
get linkFilter(): LinkFilter<T, Node, Link>;
/**
* Get whether node labels are shown or not.
*/
get showNodeLabels(): boolean;
/**
* Set whether node labels will be shown or not.
* @param value - The value.
*/
set showNodeLabels(value: boolean);
/**
* Get whether link labels are shown or not.
*/
get showLinkLabels(): boolean;
/**
* Set whether link labels will be shown or not.
* @param value - The value.
*/
set showLinkLabels(value: boolean);
private get effectiveWidth();
private get effectiveHeight();
private get effectiveCenter();
/**
* Resize the graph to fit its container.
*/
resize(): void;
/**
* Restart the controller.
* @param alpha - The alpha value of the controller's simulation after the restart.
*/
restart(alpha: number): void;
/**
* Update the node type filter by either including or removing the specified type from the filter.
* @param include - Whether the type will be included or removed from the filter.
* @param nodeType - The type to be added or removed from the filter.
*/
filterNodesByType(include: boolean, nodeType: T): void;
/**
* Shut down the controller's simulation and (optional) automatic resizing.
*/
shutdown(): void;
private initGraph;
private onTick;
private resetView;
private onZoom;
private applyZoom;
private toggleNodeFocus;
private focusNode;
private filterGraph;
}
//#endregion
export { AlphaConfig, Callbacks, Canvas, CollisionForce, DeepPartial, Drag, DragModifier, Force, Graph, GraphConfig, GraphController, GraphHost, GraphLink, GraphNode, GraphSimulation, InitialGraphSettings, Label, LabelAlphas, LinkFilter, LinkForce, LinkLabelModifier, LinkModifier, LinkSelection, MarkerConfig, MarkerSelection, Markers, Modifiers, NodeDragEvent, NodeForce, NodeLabelModifier, NodeModifier, NodeSelection, NodeTypeToken, PositionInitializer, PositionInitializers, ResizeContext, SimulationForceConfig, SimulationModifier, Zoom, ZoomConfig, ZoomModifier, createDefaultAlphaConfig, createDefaultForceConfig, createDefaultInitialGraphSettings, defineGraph, defineGraphConfig, defineLink, defineNode, defineNodeWithDefaults };
//# sourceMappingURL=index.d.mts.map