UNPKG

netviz

Version:

Network visualization library with multiple layout algorithms and rendering modes. Create interactive, publication-quality network visualizations with a simple, reactive API.

392 lines (360 loc) 10.9 kB
// Type definitions for netviz // Project: https://github.com/john-guerra/node-link // Definitions by: Claude Code <https://claude.ai> import * as d3 from "d3"; /** * Node data structure */ export interface Node { id: string | number; [key: string]: any; } /** * Link data structure * Links can reference nodes by ID (string/number), by object reference, or by array index */ export interface Link { source: string | number | Node; target: string | number | Node; [key: string]: any; } /** * Graph data structure */ export interface GraphData { nodes: Node[]; links: Link[]; } /** * Edge bundling configuration options */ export interface EdgeBundlingOptions { /** Global bundling constant controlling edge stiffness */ bundling_stiffness?: number; /** Initial distance to move points */ step_size?: number; /** Subdivision rate increase */ subdivision_rate?: number; /** Number of cycles to perform */ cycles?: number; /** Initial number of iterations for cycle */ iterations?: number; /** Rate at which iteration number decreases (e.g., 2/3) */ iterations_rate?: number; /** Which pairs of edges should be considered compatible */ compatibility_threshold?: number; /** If your network is large, edge bundling will only apply to these many links */ max_links?: number; /** Minimum alpha value to start bundling */ min_alpha_to_bundle?: number; } /** * Force-in-a-Box configuration options */ export interface ForceInABoxOptions { /** Layout template: "treemap" or "force" */ template?: "treemap" | "force"; /** Strength to foci */ strength?: number; /** Link strength between nodes of different clusters */ linkStrengthInterCluster?: number; /** Link strength between nodes of the same cluster */ linkStrengthIntraCluster?: number; /** Link distance between meta-nodes on the template (Force template only) */ forceLinkDistance?: number; /** Link strength between meta-nodes of the template (Force template only) */ forceLinkStrength?: number; /** Charge between the meta-nodes (Force template only) */ forceCharge?: number; /** Used to compute the template force nodes size (Force template only) */ forceNodeSize?: number; } /** * Smart labels configuration options */ export interface SmartLabelsOptions { /** Label stroke color */ stroke?: string; /** Areas over this size would get labels */ threshold?: number; /** Font specification */ font?: string | ((d: any) => string); /** Show label of the hovered point */ hover?: boolean; /** Callback when hovered, will pass the index of the selected element */ onHover?: (index: number) => any; /** Font for hovered labels */ hoverFont?: string | ((d: any) => string); /** Show labels in centroids */ labelsInCentroids?: boolean; /** Background fill for label rectangles */ backgroundFill?: string; /** Stroke width */ strokeWidth?: number; /** Show Voronoi diagram */ showVoronoi?: boolean; /** Voronoi diagram stroke color */ voronoiStroke?: string; /** Show anchors */ showAnchors?: boolean; /** Anchors stroke color */ anchorsStroke?: string; /** Anchors fill color */ anchorsFill?: string; /** Use occlusion detection */ useOcclusion?: boolean; /** CSS style rules to be used on occluded labels */ occludedStyle?: string; } /** * Configuration options for ForceGraph */ export interface ForceGraphOptions { // Dimensions /** Outer width in pixels */ width?: number; /** Outer height in pixels */ height?: number; // Rendering /** Rendering mode: "svg" or "canvas" */ renderer?: "svg" | "canvas"; /** Only draw links when simulation alpha is below this value (performance optimization) */ drawLinksWhenAlphaIs?: number | null; // Node styling /** Function to extract unique node identifier */ nodeId?: (node: Node) => string | number; /** Function to extract node group for coloring */ nodeGroup?: (node: Node) => string | number; /** Array of ordinal values representing node groups */ nodeGroups?: (string | number)[]; /** Node fill color (if not using group color encoding) */ nodeFill?: string; /** Node stroke color */ nodeStroke?: string | ((node: Node) => string); /** Node stroke width in pixels */ nodeStrokeWidth?: number; /** Node stroke opacity */ nodeStrokeOpacity?: number; /** Node radius in pixels or function */ nodeRadius?: number | ((node: Node) => number); /** Node label text */ nodeLabel?: (node: Node) => string; /** Node label fill color */ nodeLabelFill?: string; /** Node label stroke color */ nodeLabelStroke?: string | null; /** Node label text alignment (canvas) */ nodeLabelTextAlign?: string; /** Node label text anchor (SVG) */ nodeLabelTextAnchor?: string; /** Node label font specification */ nodeLabelFont?: string; /** Label vertical distance from node center */ nodeLabelDy?: number; /** Label horizontal distance from node center */ nodeLabelDx?: number; /** Node charge strength */ nodeStrength?: number; // Link styling /** Function to extract link source node identifier */ linkSource?: (link: Link) => string | number | Node; /** Function to extract link target node identifier */ linkTarget?: (link: Link) => string | number | Node; /** Link stroke color */ linkStroke?: string; /** Link stroke opacity */ linkStrokeOpacity?: number; /** Link stroke width in pixels or function */ linkStrokeWidth?: number | ((link: Link) => number); /** Link stroke linecap style */ linkStrokeLinecap?: string; /** Link force strength */ linkStrength?: number | ((link: Link) => number); /** Link distance */ linkDistance?: number | ((link: Link) => number); /** D3 curve function for links */ linkCurve?: d3.CurveFactory; // Colors /** Array of color strings for node groups */ colors?: string[]; /** Custom D3 color scale */ color?: d3.ScaleOrdinal<string, string> | null; // Forces and simulation /** Custom forces object */ forces?: Record<string, d3.Force<any, any>> | null; /** Boundary extent [[x0, y0], [x1, y1]] */ extent?: [[number, number], [number, number]] | null; /** Boundary force type: "forceBoundary", "forceTransport", or "forceExtent" */ extentForce?: "forceBoundary" | "forceTransport" | "forceExtent"; /** Size of the boundary border */ extentBorder?: number; /** Strength of the boundary force */ extentStrength?: number; /** Alpha value when restarting simulation */ simulationRestartAlpha?: number; /** Force X strength */ forceXStrength?: number; /** Force Y strength */ forceYStrength?: number; /** Centering force strength */ centeringStrength?: number; /** Enable collision detection */ collide?: boolean; /** Collision padding */ collidePadding?: number; /** Collision detection iterations */ collideIterations?: number; /** Set to false if network is heavily connected */ disjoint?: boolean; /** Simulation alpha target */ alphaTarget?: number; // Features /** Enable edge bundling */ useEdgeBundling?: boolean; /** Edge bundling configuration */ edgeBundling?: EdgeBundlingOptions; /** Enable Force-in-a-Box grouping (groups by nodeGroup) */ useForceInABox?: boolean; /** Force-in-a-Box configuration */ forceInABox?: ForceInABoxOptions; /** Enable zoom and pan */ useZoom?: boolean; /** Zoom scale extent [min, max] */ zoomScaleExtent?: [number, number]; /** Minimum distance for drag to activate */ minDistanceForDrag?: number; /** Auto-fit nodes in viewport */ autoFit?: boolean; /** Keep aspect ratio when auto-fitting */ keepAspectRatio?: boolean; /** Enable smart labels with Voronoi placement */ useSmartLabels?: boolean; /** Smart labels configuration */ smartLabels?: SmartLabelsOptions; // Observable compatibility /** Promise that resolves to stop the simulation */ invalidation?: Promise<void> | null; /** Previous graph instance for state preservation */ _this?: ForceGraphElement; // Debug /** Enable debug mode */ debug?: boolean; } /** * HTML Element returned by ForceGraph with additional methods and properties */ export interface ForceGraphElement extends HTMLElement { /** Currently selected nodes/edges (TODO: not yet implemented) */ value: any; /** Update the graph with new data or options */ update(data: GraphData, options?: Partial<ForceGraphOptions>): ForceGraphElement; /** Cleanup and stop the simulation */ destroy(): void; /** Access to the underlying D3 force simulation */ simulation: d3.Simulation<Node, Link>; /** Array of node objects */ nodes: Node[]; /** Array of link objects */ links: Link[]; /** D3 scales used for rendering */ scales: { x: d3.ScaleLinear<number, number>; y: d3.ScaleLinear<number, number>; }; } /** * Create a force-directed graph visualization * * @param data - Graph data with nodes and links * @param options - Configuration options * @returns HTML Element (SVG or Canvas) with additional methods * * @example * ```typescript * import { ForceGraph } from "netviz"; * * const data = { * nodes: [ * { id: "A", group: 1 }, * { id: "B", group: 1 }, * { id: "C", group: 2 } * ], * links: [ * { source: "A", target: "B" }, * { source: "B", target: "C" } * ] * }; * * const graph = ForceGraph(data, { * width: 800, * height: 600, * renderer: "svg" * }); * * document.body.appendChild(graph); * * // Update later * graph.update(newData); * * // Cleanup * graph.destroy(); * ``` */ export function ForceGraph( data: GraphData, options?: ForceGraphOptions ): ForceGraphElement; /** * Alias for ForceGraph - semantic name for node-link diagrams */ export const NodeLink: typeof ForceGraph; /** * Core ForceGraph implementation (advanced usage) */ export function ForceGraphCore( data: GraphData, options?: ForceGraphOptions ): ForceGraphElement; /** * Custom force: Transport nodes within bounds */ export function forceTransport( extent: [[number, number], [number, number]], margin?: number, strength?: number ): d3.Force<Node, Link>; /** * Custom force: Clamp nodes to boundaries */ export function forceExtent( extent: [[number, number], [number, number]], strength?: number ): d3.Force<Node, Link>; /** * Edge bundling force class */ export class ForceEdgeBundling { constructor(); // Add methods as needed } /** * Edge bundling convenience function */ export function edgeBundling( graph: any, options?: EdgeBundlingOptions ): void; /** * Filter network data by nodes/links with ego-network support */ export function filterNetwork( data: GraphData, filter: { nodes?: (node: Node) => boolean; links?: (link: Link) => boolean; ego?: { node: string | number; depth?: number; }; } ): GraphData;