polly-graph 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -233,11 +233,11 @@ type UIColors = typeof DEFAULT_COLORS.ui;
233
233
  * Consolidated icons used across V1, V2, and demo
234
234
  */
235
235
  declare const icons: {
236
- readonly fit: string;
237
- readonly reset: string;
238
- readonly plus: string;
239
- readonly minus: string;
240
- readonly caret: string;
236
+ readonly fit: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M5 9V5H9\" />\n <path d=\"M19 9V5H15\" />\n <path d=\"M5 15V19H9\" />\n <path d=\"M19 15V19H15\" />\n</svg>";
237
+ readonly reset: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M20 12a8 8 0 1 1-2.3-5.7\" />\n <path d=\"M20 4.5v4h-4\" />\n</svg>";
238
+ readonly plus: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M5 12h14m-7-7v14\" />\n</svg>";
239
+ readonly minus: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M5 12h14\" />\n</svg>";
240
+ readonly caret: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M6 9l6 6 6-6\" />\n</svg>";
241
241
  };
242
242
  declare const iconSvg: {
243
243
  readonly fit: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M5 9V5H9\" />\n <path d=\"M19 9V5H15\" />\n <path d=\"M5 15V19H9\" />\n <path d=\"M19 15V19H15\" />\n </svg>";
@@ -261,12 +261,12 @@ interface Coordinates {
261
261
  }
262
262
  type Position = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
263
263
  type Orientation = 'vertical' | 'horizontal';
264
- type GraphControlsPosition = Position;
265
- type GraphControlsOrientation = Orientation;
266
- interface GraphControlsConfig {
264
+ type GraphControlsPosition$1 = Position;
265
+ type GraphControlsOrientation$1 = Orientation;
266
+ interface GraphControlsConfig$1 {
267
267
  readonly enabled: boolean;
268
- readonly position?: GraphControlsPosition;
269
- readonly orientation?: GraphControlsOrientation;
268
+ readonly position?: GraphControlsPosition$1;
269
+ readonly orientation?: GraphControlsOrientation$1;
270
270
  readonly offset?: Coordinates;
271
271
  readonly show?: {
272
272
  readonly zoomIn?: boolean;
@@ -303,6 +303,11 @@ interface SelectionInteractionConfig {
303
303
  readonly nodeStyle?: Partial<NodeStyle>;
304
304
  readonly linkStyle?: Partial<LinkStyle>;
305
305
  }
306
+ interface HighlightInteractionConfig {
307
+ readonly enabled?: boolean;
308
+ readonly nodeStyle?: Partial<NodeStyle>;
309
+ readonly linkStyle?: Partial<LinkStyle>;
310
+ }
306
311
  interface DragInteractionConfig {
307
312
  readonly enabled?: boolean;
308
313
  }
@@ -310,6 +315,7 @@ interface GraphInteractionConfig {
310
315
  readonly drag?: DragInteractionConfig;
311
316
  readonly hover?: HoverInteractionConfig;
312
317
  readonly selection?: SelectionInteractionConfig;
318
+ readonly highlight?: HighlightInteractionConfig;
313
319
  }
314
320
 
315
321
  type LegendPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
@@ -336,7 +342,7 @@ interface BaseGraphConfig {
336
342
  readonly responsive?: boolean;
337
343
  readonly simulation?: SimulationConfig;
338
344
  readonly interaction?: GraphInteractionConfig;
339
- readonly controls?: GraphControlsConfig;
345
+ readonly controls?: GraphControlsConfig$1;
340
346
  readonly legend?: LegendConfig;
341
347
  }
342
348
  interface ControlsController {
@@ -374,9 +380,10 @@ interface V2Link extends SimulationLinkDatum<V2Node> {
374
380
  __indexColor?: string;
375
381
  __indexColorRGB?: [number, number, number];
376
382
  }
377
- interface InteractionConfig {
383
+ interface InteractionConfig$1 {
378
384
  readonly hover?: HoverInteractionConfig;
379
385
  readonly selection?: SelectionInteractionConfig;
386
+ readonly highlight?: HighlightInteractionConfig;
380
387
  }
381
388
  interface V2Config {
382
389
  container: HTMLElement;
@@ -385,8 +392,8 @@ interface V2Config {
385
392
  width?: number;
386
393
  height?: number;
387
394
  backgroundColor?: string;
388
- interaction?: InteractionConfig;
389
- controls?: GraphControlsConfig;
395
+ interaction?: InteractionConfig$1;
396
+ controls?: GraphControlsConfig$1;
390
397
  legend?: LegendConfig;
391
398
  autoFitView?: boolean;
392
399
  cooldownTime?: number;
@@ -406,6 +413,11 @@ interface V2Instance {
406
413
  zoomIn(factor?: number, center?: [number, number]): void;
407
414
  zoomOut(factor?: number, center?: [number, number]): void;
408
415
  clearSelection(): void;
416
+ highlightNode(nodeId: string): void;
417
+ highlightNodes(nodeIds: string[]): void;
418
+ unhighlightNode(nodeId: string): void;
419
+ clearHighlights(): void;
420
+ getHighlightedNodes(): Set<string>;
409
421
  on(event: 'nodeSelect', handler: (node: V2Node, element: HTMLCanvasElement) => void): () => void;
410
422
  on(event: 'nodeDeselect', handler: (node: V2Node, element: HTMLCanvasElement) => void): () => void;
411
423
  on(event: 'linkSelect', handler: (link: V2Link, element: HTMLCanvasElement) => void): () => void;
@@ -623,12 +635,30 @@ declare class PhysicsManager {
623
635
  private hasInitialAutoFitCompleted;
624
636
  private timerManager;
625
637
  private isVisibilityListenerAttached;
626
- private nodeMap;
638
+ private stateManager;
639
+ private isWarmingUp;
640
+ private warmupSteps;
627
641
  constructor(timerManager: TimerManager);
628
642
  /**
629
643
  * Initialize physics simulation
630
644
  */
631
645
  initialize(config: PhysicsConfig): void;
646
+ /**
647
+ * Handle tick with smooth warmup progression
648
+ */
649
+ private handleTick;
650
+ /**
651
+ * Start smooth warmup process for large graphs
652
+ */
653
+ private startSmoothWarmup;
654
+ /**
655
+ * Progress warmup over time for smoother initial animation
656
+ */
657
+ private progressWarmup;
658
+ /**
659
+ * Apply scaled forces during warmup
660
+ */
661
+ private applyWarmupForces;
632
662
  /**
633
663
  * Handle simulation end
634
664
  */
@@ -641,10 +671,6 @@ declare class PhysicsManager {
641
671
  * Setup cooldown timer (force-graph pattern)
642
672
  */
643
673
  private setupCooldownTimer;
644
- /**
645
- * Build node index for O(1) lookups (Step 3 optimization)
646
- */
647
- private buildNodeIndex;
648
674
  /**
649
675
  * Get simulation instance
650
676
  */
@@ -684,7 +710,7 @@ declare class PhysicsManager {
684
710
  */
685
711
  private getLinkArrowLength;
686
712
  /**
687
- * Initialize node positions if not set
713
+ * Initialize node positions with improved distribution for smoother startup
688
714
  */
689
715
  initializePositions(): void;
690
716
  /**
@@ -765,6 +791,7 @@ declare class HoverManager {
765
791
  private flushShadowCanvas?;
766
792
  private hasValidPointerPosition;
767
793
  private containerWarningLogged;
794
+ private boundHandlers;
768
795
  /**
769
796
  * Initialize hover manager with force-graph pattern
770
797
  */
@@ -849,6 +876,10 @@ interface DragConfig {
849
876
  physicsManager: PhysicsManager;
850
877
  hoverManager: HoverManager;
851
878
  onRender: () => void;
879
+ renderer?: {
880
+ setDragState(isDragging: boolean): void;
881
+ setDraggedNode(node: V2Node): void;
882
+ };
852
883
  }
853
884
  interface DragState {
854
885
  isDragging: boolean;
@@ -858,6 +889,9 @@ declare class DragManager {
858
889
  private config?;
859
890
  private state;
860
891
  private readonly DRAG_CLICK_TOLERANCE_PX;
892
+ private dragRenderPending;
893
+ private lastDragRenderTime;
894
+ private pendingAnimationFrame?;
861
895
  /**
862
896
  * Initialize drag behavior
863
897
  */
@@ -874,6 +908,10 @@ declare class DragManager {
874
908
  * Handle drag movement
875
909
  */
876
910
  private handleDrag;
911
+ /**
912
+ * RAF-throttled render during drag (like ZoomManager pattern)
913
+ */
914
+ private throttledDragRender;
877
915
  /**
878
916
  * Handle drag end
879
917
  */
@@ -906,6 +944,10 @@ interface ZoomConfig {
906
944
  canvas: HTMLCanvasElement;
907
945
  canvasManager: CanvasManager;
908
946
  onRender: () => void;
947
+ onZoomEnd?: () => void;
948
+ renderer?: {
949
+ setZoomState(isZooming: boolean): void;
950
+ };
909
951
  minZoom?: number;
910
952
  maxZoom?: number;
911
953
  isOverEntity?: () => boolean;
@@ -913,6 +955,9 @@ interface ZoomConfig {
913
955
  declare class ZoomManager {
914
956
  private config?;
915
957
  private zoomBehavior?;
958
+ private isZooming;
959
+ private zoomRenderPending;
960
+ private isProgrammaticZoom;
916
961
  /**
917
962
  * Initialize zoom behavior
918
963
  */
@@ -926,13 +971,14 @@ declare class ZoomManager {
926
971
  */
927
972
  private handleZoomStart;
928
973
  /**
929
- * Handle zoom events
974
+ * Handle zoom events with RAF throttling for smooth performance
930
975
  */
931
976
  private handleZoom;
932
977
  /**
933
978
  * Handle zoom end (when panning ends)
934
979
  */
935
980
  private handleZoomEnd;
981
+ isCurrentlyZooming(): boolean;
936
982
  /**
937
983
  * Get zoom behavior instance
938
984
  */
@@ -1014,6 +1060,7 @@ declare class SelectionManager {
1014
1060
  private selectionState;
1015
1061
  private eventHandlers;
1016
1062
  private container?;
1063
+ private boundHandlers;
1017
1064
  /**
1018
1065
  * Initialize selection manager
1019
1066
  */
@@ -1081,161 +1128,263 @@ declare class SelectionManager {
1081
1128
  }
1082
1129
 
1083
1130
  /**
1084
- * V2 Canvas Graph - Renderer (Force-Graph Pattern)
1131
+ * V2 Canvas Graph - State Manager
1085
1132
  *
1086
- * Clean implementation following force-graph's exact architecture
1133
+ * Centralized state management for O(1) lookups across all renderers.
1134
+ * Eliminates duplicate Maps and provides consistent caching patterns.
1087
1135
  */
1088
1136
 
1089
- declare class Renderer {
1090
- private config?;
1091
- private canvasState?;
1092
- private hoverManager?;
1093
- private selectionManager?;
1094
- private styleResolver?;
1137
+ interface GraphState {
1138
+ nodes: V2Node[];
1139
+ links: V2Link[];
1140
+ }
1141
+ interface NodeLookupState {
1142
+ isHovered: boolean;
1143
+ isSelected: boolean;
1144
+ isHighlighted: boolean;
1145
+ }
1146
+ interface LinkLookupState {
1147
+ isHovered: boolean;
1148
+ isSelected: boolean;
1149
+ }
1150
+ declare class StateManager {
1095
1151
  private nodeMap;
1096
- private shadowCanvasDirty;
1097
- private lastShadowRenderTime;
1098
- private readonly SHADOW_RENDER_THROTTLE;
1099
- private hasLoggedLargeGraphOptimization;
1100
- private performanceMetrics;
1101
- private linkHoverPrecision;
1152
+ private linkMap;
1153
+ private nodeStateCache;
1154
+ private linkStateCache;
1155
+ private linkIdToLinkMap;
1156
+ private highlightedNodes;
1102
1157
  /**
1103
- * Initialize the renderer
1158
+ * Initialize with graph data
1104
1159
  */
1105
- initialize(config: {
1106
- nodes: V2Node[];
1107
- links: V2Link[];
1108
- interaction?: InteractionConfig;
1109
- }, canvasState: CanvasState, hoverManager: HoverManager, selectionManager?: SelectionManager): void;
1160
+ initialize(state: GraphState): void;
1110
1161
  /**
1111
- * Main render method with performance metrics (Instrumented)
1162
+ * Update with new graph data
1112
1163
  */
1113
- render(): void;
1164
+ updateState(state: GraphState): void;
1114
1165
  /**
1115
- * Render with transform (called during zoom/pan) with shadow canvas dirty marking (Step 6 optimization)
1166
+ * Build node map for O(1) node lookups
1116
1167
  */
1117
- renderWithTransform(): void;
1168
+ private buildNodeMap;
1118
1169
  /**
1119
- * Render shadow canvas for hit detection with throttling (Step 6 optimization)
1170
+ * Build link maps for O(1) link lookups
1120
1171
  */
1121
- renderShadowCanvas(): void;
1172
+ private buildLinkMaps;
1122
1173
  /**
1123
- * Mark shadow canvas as dirty for next render (Step 6 optimization)
1174
+ * Get node by ID (O(1) lookup)
1124
1175
  */
1125
- markShadowCanvasDirty(): void;
1176
+ getNode(nodeId: string): V2Node | undefined;
1126
1177
  /**
1127
- * Force shadow canvas render (Step 6 optimization)
1178
+ * Get link by link ID (O(1) lookup)
1128
1179
  */
1129
- forceShadowCanvasRender(): void;
1180
+ getLink(linkId: string): V2Link | undefined;
1130
1181
  /**
1131
- * Clear canvas context
1182
+ * Get link by source/target IDs (O(1) lookup)
1132
1183
  */
1133
- private clearCanvas;
1184
+ getLinkByNodes(sourceId: string, targetId: string): V2Link | undefined;
1134
1185
  /**
1135
- * Apply transform to canvas context
1186
+ * Get all nodes (returns reference to avoid copying)
1136
1187
  */
1137
- private applyTransform;
1188
+ getAllNodes(): V2Node[];
1138
1189
  /**
1139
- * Get unique link ID for tracking (consistent with LinkLabelsRenderer)
1190
+ * Get all links (returns reference to avoid copying)
1140
1191
  */
1141
- private getLinkId;
1192
+ getAllLinks(): V2Link[];
1142
1193
  /**
1143
- * Render main canvas nodes
1194
+ * Get node map (for renderers that need direct map access)
1144
1195
  */
1145
- private renderNodes;
1196
+ getNodeMap(): Map<string, V2Node>;
1146
1197
  /**
1147
- * Render node labels
1198
+ * Get link ID to link map (for renderers that need direct map access)
1148
1199
  */
1149
- private renderNodeLabels;
1200
+ getLinkIdToLinkMap(): Map<string, V2Link>;
1150
1201
  /**
1151
- * Render shadow links with __indexColor (force-graph pattern)
1202
+ * Cache node state for performance (avoid repeated hover/selection checks)
1152
1203
  */
1153
- private renderShadowLinks;
1204
+ cacheNodeState(nodeId: string, state: NodeLookupState): void;
1154
1205
  /**
1155
- * Render shadow link labels for hit detection
1206
+ * Get cached node state
1156
1207
  */
1157
- private renderShadowLinkLabels;
1208
+ getCachedNodeState(nodeId: string): NodeLookupState | undefined;
1158
1209
  /**
1159
- * Render shadow nodes with __indexColor (force-graph pattern)
1210
+ * Cache link state for performance (avoid repeated hover/selection checks)
1160
1211
  */
1161
- private renderShadowNodes;
1212
+ cacheLinkState(linkId: string, state: LinkLookupState): void;
1162
1213
  /**
1163
- * Get currently hovered node ID directly (Critical Performance Fix)
1214
+ * Get cached link state
1164
1215
  */
1165
- private getCurrentlyHoveredNodeId;
1216
+ getCachedLinkState(linkId: string): LinkLookupState | undefined;
1166
1217
  /**
1167
- * Get currently selected node ID directly (Critical Performance Fix)
1218
+ * Clear state caches (call when hover/selection state changes)
1168
1219
  */
1169
- private getCurrentlySelectedNodeId;
1220
+ clearStateCache(): void;
1170
1221
  /**
1171
- * Get currently hovered link (Critical Performance Fix)
1222
+ * Clear only node state cache
1172
1223
  */
1173
- private getCurrentlyHoveredLink;
1224
+ clearNodeStateCache(): void;
1174
1225
  /**
1175
- * Get currently selected link (Critical Performance Fix)
1226
+ * Clear only link state cache
1176
1227
  */
1177
- private getCurrentlySelectedLink;
1228
+ clearLinkStateCache(): void;
1178
1229
  /**
1179
- * Log performance metrics for analysis
1230
+ * Generate consistent link ID
1180
1231
  */
1181
- private logPerformanceMetrics;
1232
+ getLinkId(link: V2Link): string;
1182
1233
  /**
1183
- * Reset performance metrics
1234
+ * Calculate link midpoint (common utility)
1184
1235
  */
1185
- resetPerformanceMetrics(): void;
1236
+ getLinkMidpoint(link: V2Link): {
1237
+ x: number;
1238
+ y: number;
1239
+ } | null;
1186
1240
  /**
1187
- * Get current performance metrics
1241
+ * Highlight a node by ID
1188
1242
  */
1189
- getPerformanceMetrics(): StatsMetrics;
1243
+ highlightNode(nodeId: string): void;
1190
1244
  /**
1191
- * Force log performance metrics immediately (for debugging)
1245
+ * Highlight multiple nodes by IDs
1192
1246
  */
1193
- forceLogMetrics(): void;
1247
+ highlightNodes(nodeIds: string[]): void;
1194
1248
  /**
1195
- * Check if a node is currently hovered
1249
+ * Remove highlight from a node
1196
1250
  */
1197
- private isNodeHovered;
1251
+ unhighlightNode(nodeId: string): void;
1198
1252
  /**
1199
- * Check if a link is currently hovered (either directly or through associated node hover)
1253
+ * Clear all node highlights
1200
1254
  */
1201
- private isLinkHovered;
1255
+ clearHighlights(): void;
1202
1256
  /**
1203
- * Check if a node is currently selected
1257
+ * Check if a node is highlighted
1204
1258
  */
1205
- private isNodeSelected;
1259
+ isNodeHighlighted(nodeId: string): boolean;
1206
1260
  /**
1207
- * Check if a link is currently selected
1261
+ * Get all highlighted node IDs
1208
1262
  */
1209
- private isLinkSelected;
1263
+ getHighlightedNodes(): Set<string>;
1210
1264
  /**
1211
- * Check if a link's label should be visible due to selection
1212
- * (either the link itself is selected, or its connected node is selected)
1265
+ * Clear state cache for a specific node
1213
1266
  */
1214
- private shouldShowLinkLabelForSelection;
1267
+ private clearSingleNodeStateCache;
1215
1268
  /**
1216
- * Calculate midpoint of a link for label positioning
1269
+ * Get statistics about cached state
1217
1270
  */
1218
- private getLinkMidpoint;
1271
+ getStats(): {
1272
+ nodeCount: number;
1273
+ linkCount: number;
1274
+ cachedNodeStates: number;
1275
+ cachedLinkStates: number;
1276
+ highlightedNodes: number;
1277
+ };
1219
1278
  /**
1220
- * Render directed link with arrow head
1279
+ * Destroy and clean up all maps
1221
1280
  */
1222
- private renderDirectedLink;
1281
+ destroy(): void;
1282
+ }
1283
+
1284
+ /**
1285
+ * V2 Canvas Graph - Renderer (Force-Graph Pattern)
1286
+ *
1287
+ * Clean implementation following force-graph's exact architecture
1288
+ */
1289
+
1290
+ declare class Renderer {
1291
+ private config?;
1292
+ private canvasState?;
1293
+ private hoverManager?;
1294
+ private selectionManager?;
1295
+ private styleResolver?;
1296
+ private stateManager;
1297
+ private metricsManager;
1298
+ private interactionResolver;
1299
+ private dragOptimizer;
1300
+ private zIndexRenderer;
1301
+ private zoomRenderer;
1302
+ private hitDetectionRenderer;
1223
1303
  /**
1224
- * V1-compatible link shortening for source point
1304
+ * Initialize the renderer
1225
1305
  */
1226
- private getShortenedSourcePoint;
1306
+ initialize(config: {
1307
+ nodes: V2Node[];
1308
+ links: V2Link[];
1309
+ interaction?: InteractionConfig$1;
1310
+ }, canvasState: CanvasState, hoverManager: HoverManager, selectionManager?: SelectionManager): void;
1227
1311
  /**
1228
- * V1-compatible link shortening for target point
1312
+ * Initialize the optimized z-index renderer with all required dependencies
1229
1313
  */
1230
- private getShortenedTargetPoint;
1314
+ private initializeZIndexRenderer;
1231
1315
  /**
1232
- * Render arrow head at specific points
1316
+ * Initialize the zoom renderer for zoom-specific optimizations
1233
1317
  */
1234
- private renderArrowAtPoint;
1318
+ private initializeZoomRenderer;
1235
1319
  /**
1236
- * Render arrow head (legacy method for backward compatibility)
1320
+ * Initialize the hit detection renderer for shadow canvas
1237
1321
  */
1238
- private renderArrow;
1322
+ private initializeHitDetectionRenderer;
1323
+ /**
1324
+ * Initialize the drag optimizer for fast drag rendering
1325
+ */
1326
+ private initializeDragOptimizer;
1327
+ /**
1328
+ * Main render method with performance metrics (Instrumented)
1329
+ */
1330
+ render(): void;
1331
+ /**
1332
+ * Render with transform (called during zoom/pan) - OPTIMIZED PATTERN
1333
+ * Fast rendering during zoom, full rendering when stopped
1334
+ */
1335
+ renderWithTransform(): void;
1336
+ /**
1337
+ * Set zoom state for performance optimization (delegates to ZoomRenderer)
1338
+ */
1339
+ setZoomState(isZooming: boolean): void;
1340
+ /**
1341
+ * Set drag state for performance optimization (like setZoomState)
1342
+ */
1343
+ setDragState(isDragging: boolean): void;
1344
+ /**
1345
+ * Set the currently dragged node
1346
+ */
1347
+ setDraggedNode(draggedNode: V2Node): void;
1348
+ /**
1349
+ * Render shadow canvas for hit detection (delegates to HitDetectionRenderer)
1350
+ */
1351
+ renderShadowCanvas(): void;
1352
+ /**
1353
+ * Mark shadow canvas as dirty for next render (delegates to HitDetectionRenderer)
1354
+ */
1355
+ markShadowCanvasDirty(): void;
1356
+ /**
1357
+ * Force shadow canvas render (delegates to HitDetectionRenderer)
1358
+ */
1359
+ forceShadowCanvasRender(): void;
1360
+ /**
1361
+ * Clear canvas context
1362
+ */
1363
+ private clearCanvas;
1364
+ /**
1365
+ * Apply transform to canvas context
1366
+ */
1367
+ private applyTransform;
1368
+ /**
1369
+ * Get unique link ID for tracking (delegates to StateManager)
1370
+ */
1371
+ private getLinkId;
1372
+ /**
1373
+ * Reset performance metrics
1374
+ */
1375
+ resetPerformanceMetrics(): void;
1376
+ /**
1377
+ * Get current performance metrics
1378
+ */
1379
+ getPerformanceMetrics(): StatsMetrics;
1380
+ /**
1381
+ * Force log performance metrics immediately (for debugging)
1382
+ */
1383
+ forceLogMetrics(): void;
1384
+ /**
1385
+ * Calculate midpoint of a link for label positioning (delegates to StateManager)
1386
+ */
1387
+ private getLinkMidpoint;
1239
1388
  /**
1240
1389
  * Initialize node positions if needed
1241
1390
  */
@@ -1260,44 +1409,16 @@ declare class Renderer {
1260
1409
  };
1261
1410
  };
1262
1411
  /**
1263
- * Debug shadow canvas export (force-graph pattern)
1412
+ * Debug shadow canvas export (delegates to HitDetectionRenderer)
1264
1413
  */
1265
1414
  debugShadowCanvas(): void;
1266
- /**
1267
- * Build node index for O(1) lookups (Step 3 optimization)
1268
- */
1269
- private buildNodeIndex;
1270
- /**
1271
- * Get node by ID using O(1) lookup (Step 3 optimization)
1272
- */
1273
- private getNodeById;
1274
- /**
1275
- * Render with z-index layers (for renderWithTransform)
1276
- */
1277
- private renderWithLayers;
1278
- /**
1279
- * Render with z-index layers and performance metrics (for main render)
1280
- */
1281
- private renderWithLayersAndMetrics;
1282
- /**
1283
- * Helper methods for getting current interaction states
1284
- */
1285
- private getHoveredNode;
1286
- private getSelectedNode;
1287
- private getHoveredLink;
1288
- private getSelectedLink;
1289
- /**
1290
- * Layer-specific rendering methods (render subsets of entities)
1291
- */
1292
- private renderNodesWithLabelsLayer;
1293
- /**
1294
- * Helper method to truncate labels (copied from NodeLabelsRenderer)
1295
- */
1296
- private truncateLabel;
1297
1415
  private renderLinksLayer;
1298
- private renderLinkLabelsLayer;
1299
1416
  private renderNodesLayer;
1300
1417
  private renderNodeLabelsLayer;
1418
+ /**
1419
+ * Get the state manager for highlight operations
1420
+ */
1421
+ getStateManager(): StateManager;
1301
1422
  /**
1302
1423
  * Destroy renderer and clean up resources
1303
1424
  */
@@ -1457,6 +1578,26 @@ declare class V2Graph implements V2Instance {
1457
1578
  * Draw legend on export canvas
1458
1579
  */
1459
1580
  private drawLegendOnExportCanvas;
1581
+ /**
1582
+ * Highlight a node by ID
1583
+ */
1584
+ highlightNode(nodeId: string): void;
1585
+ /**
1586
+ * Highlight multiple nodes by IDs
1587
+ */
1588
+ highlightNodes(nodeIds: string[]): void;
1589
+ /**
1590
+ * Remove highlight from a node
1591
+ */
1592
+ unhighlightNode(nodeId: string): void;
1593
+ /**
1594
+ * Clear all node highlights
1595
+ */
1596
+ clearHighlights(): void;
1597
+ /**
1598
+ * Get all highlighted node IDs
1599
+ */
1600
+ getHighlightedNodes(): Set<string>;
1460
1601
  /**
1461
1602
  * Destroy the graph and clean up resources
1462
1603
  */
@@ -1467,4 +1608,951 @@ declare class V2Graph implements V2Instance {
1467
1608
  */
1468
1609
  declare function createV2Graph(config: V2Config): V2Instance;
1469
1610
 
1470
- export { type ArrowRenderStyle, type BaseGraphConfig, CanvasManager, type CanvasRenderConfig, type CanvasState, type ControlsController, type Coordinates, DEFAULT_COLORS, DEFAULT_HOVER_STYLES, DEFAULT_LINK_LABEL_STYLE, DEFAULT_LINK_STYLE, type DragConfig, type DragInteractionConfig, DragManager, type DragState, ErrorHandler, type GraphControlsConfig, type GraphControlsOrientation, type GraphControlsPosition, type GraphInteractionConfig, type GraphLink, type GraphNode, type GraphNodeWithInitial, type GraphTooltipTheme, type HoverEvent, type HoverInteractionConfig, HoverManager, type HoverState, type HoverStyles, type IconName, type IconSvgName, type InteractionColors, type InteractionConfig, type LegendConfig, type LegendPosition, type LinkArrowStyle, type LinkColors, type LinkLabelRenderStyle, type LinkLabelStyle, type LinkRenderStyle, type LinkSelectHandler, type LinkStyle, NeutralColor, type NodeColorPalette, type NodeLabelRenderStyle, type NodeRenderStyle, type NodeSelectHandler, type NodeStyle, type Orientation, type PhysicsConfig, PhysicsManager, PointerManager, type PointerState, type Position, PrimaryColor, type RenderStyles, Renderer, type ResolvedLinkLabelStyle, type ResolvedLinkStyle, SecondaryColor, type SelectionEvent, type SelectionInteractionConfig, SelectionManager, type SelectionState, type SimulationConfig, StandardColor, type TooltipInteractionConfig, type TooltipPlacement, type UIColors, type V2Config, V2Graph, type V2Instance, type V2Link, type V2Node, ValidationError, type ZoomConfig, ZoomManager, createV2Graph, getIcon, getIconSvg, iconSvg, icons, isValidLinkStyle, isValidNodeStyle, mergeLinkStyle, mergeNodeStyle };
1611
+ /**
1612
+ * Force-Graph Wrapper Types
1613
+ *
1614
+ * Minimal overhead generic types with strategic use of 'any'
1615
+ * for force-graph library integration
1616
+ */
1617
+ /**
1618
+ * Base node interface with generic data payload
1619
+ */
1620
+ interface ForceGraphNode<T = Record<string, unknown>> {
1621
+ /** Unique identifier for the node */
1622
+ id: string;
1623
+ /** Optional custom data payload */
1624
+ data?: T;
1625
+ /** Position coordinates (managed by physics simulation) */
1626
+ x?: number;
1627
+ y?: number;
1628
+ vx?: number;
1629
+ vy?: number;
1630
+ /** Node properties for force-graph compatibility */
1631
+ [key: string]: unknown;
1632
+ }
1633
+ /**
1634
+ * Base link interface with generic data payload
1635
+ */
1636
+ interface ForceGraphLink<NodeType = ForceGraphNode, T = Record<string, unknown>> {
1637
+ /** Source node reference - can be string ID or node object */
1638
+ source: string | NodeType;
1639
+ /** Target node reference - can be string ID or node object */
1640
+ target: string | NodeType;
1641
+ /** Optional custom data payload */
1642
+ data?: T;
1643
+ /** Link properties for force-graph compatibility */
1644
+ [key: string]: unknown;
1645
+ }
1646
+ /**
1647
+ * Graph data structure
1648
+ */
1649
+ interface ForceGraphData<NodeType extends ForceGraphNode, LinkType extends ForceGraphLink<NodeType>> {
1650
+ nodes: NodeType[];
1651
+ links: LinkType[];
1652
+ }
1653
+ /**
1654
+ * Event handler types with proper generics
1655
+ */
1656
+ type NodeEventHandler<NodeType> = (node: NodeType, event?: MouseEvent) => void;
1657
+ type LinkEventHandler<LinkType> = (link: LinkType, event?: MouseEvent) => void;
1658
+ type BackgroundEventHandler = (event: MouseEvent) => void;
1659
+ type CanvasRenderHandler = (ctx: CanvasRenderingContext2D, globalScale: number) => void;
1660
+ /**
1661
+ * Accessor types - can be property name or function
1662
+ */
1663
+ type NodeAccessor<NodeType, ReturnType> = ReturnType | keyof NodeType | ((node: NodeType) => ReturnType);
1664
+ type LinkAccessor<LinkType, ReturnType> = ReturnType | keyof LinkType | ((link: LinkType) => ReturnType);
1665
+ /**
1666
+ * Common accessor return types
1667
+ */
1668
+ type ColorAccessor<T> = T extends ForceGraphNode ? NodeAccessor<T, string> : T extends ForceGraphLink<unknown> ? LinkAccessor<T, string> : never;
1669
+ type NumberAccessor<T> = T extends ForceGraphNode ? NodeAccessor<T, number> : T extends ForceGraphLink<unknown> ? LinkAccessor<T, number> : never;
1670
+ type StringAccessor<T> = T extends ForceGraphNode ? NodeAccessor<T, string> : T extends ForceGraphLink<unknown> ? LinkAccessor<T, string> : never;
1671
+ type BooleanAccessor<T> = T extends ForceGraphNode ? NodeAccessor<T, boolean> : T extends ForceGraphLink<unknown> ? LinkAccessor<T, boolean> : never;
1672
+ /**
1673
+ * Canvas custom render modes for nodeCanvasObjectMode and linkCanvasObjectMode
1674
+ */
1675
+ type CanvasCustomRenderMode = 'replace' | 'before' | 'after';
1676
+ /**
1677
+ * Force simulation configuration
1678
+ */
1679
+ interface ForceConfig {
1680
+ /** D3 force simulation parameters */
1681
+ d3AlphaMin?: number;
1682
+ d3AlphaDecay?: number;
1683
+ d3VelocityDecay?: number;
1684
+ /** Simulation control */
1685
+ warmupTicks?: number;
1686
+ cooldownTicks?: number;
1687
+ cooldownTime?: number;
1688
+ }
1689
+ /**
1690
+ * Canvas configuration
1691
+ */
1692
+ interface CanvasConfig {
1693
+ width?: number;
1694
+ height?: number;
1695
+ backgroundColor?: string;
1696
+ /** Zoom and pan controls */
1697
+ enableZoomInteraction?: boolean | ((event: MouseEvent) => boolean);
1698
+ enablePanInteraction?: boolean | ((event: MouseEvent) => boolean);
1699
+ minZoom?: number;
1700
+ maxZoom?: number;
1701
+ /** Rendering optimization */
1702
+ autoPauseRedraw?: boolean;
1703
+ }
1704
+ /**
1705
+ * Interaction configuration
1706
+ */
1707
+ interface InteractionConfig<NodeType, LinkType> {
1708
+ /** Pointer interaction */
1709
+ enablePointerInteraction?: boolean;
1710
+ enableNodeDrag?: boolean;
1711
+ linkHoverPrecision?: number;
1712
+ /** Event handlers */
1713
+ onNodeClick?: NodeEventHandler<NodeType>;
1714
+ onNodeDoubleClick?: NodeEventHandler<NodeType>;
1715
+ onNodeRightClick?: NodeEventHandler<NodeType>;
1716
+ onNodeHover?: NodeEventHandler<NodeType>;
1717
+ onNodeDrag?: NodeEventHandler<NodeType>;
1718
+ onNodeDragEnd?: NodeEventHandler<NodeType>;
1719
+ onLinkClick?: LinkEventHandler<LinkType>;
1720
+ onLinkRightClick?: LinkEventHandler<LinkType>;
1721
+ onLinkHover?: LinkEventHandler<LinkType>;
1722
+ onBackgroundClick?: BackgroundEventHandler;
1723
+ onBackgroundRightClick?: BackgroundEventHandler;
1724
+ /** Canvas rendering hooks */
1725
+ onRenderFramePre?: CanvasRenderHandler;
1726
+ onRenderFramePost?: CanvasRenderHandler;
1727
+ }
1728
+ /**
1729
+ * Node styling configuration with generics
1730
+ */
1731
+ interface NodeStylingConfig<NodeType> {
1732
+ /** Node appearance */
1733
+ nodeRelSize?: number;
1734
+ nodeId?: StringAccessor<NodeType>;
1735
+ nodeLabel?: StringAccessor<NodeType>;
1736
+ nodeVal?: NumberAccessor<NodeType>;
1737
+ nodeVisibility?: BooleanAccessor<NodeType>;
1738
+ nodeColor?: ColorAccessor<NodeType>;
1739
+ nodeAutoColorBy?: StringAccessor<NodeType>;
1740
+ /** Custom node rendering */
1741
+ nodeCanvasObjectMode?: NodeAccessor<NodeType, CanvasCustomRenderMode>;
1742
+ nodeCanvasObject?: (node: NodeType, ctx: CanvasRenderingContext2D, globalScale: number) => void;
1743
+ nodePointerAreaPaint?: (node: NodeType, color: string, ctx: CanvasRenderingContext2D, globalScale: number) => void;
1744
+ }
1745
+ /**
1746
+ * Link styling configuration with generics
1747
+ */
1748
+ interface LinkStylingConfig<LinkType> {
1749
+ /** Link appearance */
1750
+ linkSource?: string;
1751
+ linkTarget?: string;
1752
+ linkLabel?: StringAccessor<LinkType>;
1753
+ linkVisibility?: BooleanAccessor<LinkType>;
1754
+ linkColor?: ColorAccessor<LinkType>;
1755
+ linkAutoColorBy?: StringAccessor<LinkType>;
1756
+ linkWidth?: NumberAccessor<LinkType>;
1757
+ linkLineDash?: LinkAccessor<LinkType, number[]>;
1758
+ linkCurvature?: NumberAccessor<LinkType>;
1759
+ /** Directional arrows */
1760
+ linkDirectionalArrowLength?: NumberAccessor<LinkType>;
1761
+ linkDirectionalArrowColor?: ColorAccessor<LinkType>;
1762
+ linkDirectionalArrowRelPos?: NumberAccessor<LinkType>;
1763
+ /** Directional particles */
1764
+ linkDirectionalParticles?: NumberAccessor<LinkType>;
1765
+ linkDirectionalParticleSpeed?: NumberAccessor<LinkType>;
1766
+ linkDirectionalParticleOffset?: NumberAccessor<LinkType>;
1767
+ linkDirectionalParticleWidth?: NumberAccessor<LinkType>;
1768
+ linkDirectionalParticleColor?: ColorAccessor<LinkType>;
1769
+ linkDirectionalParticleCanvasObject?: (link: LinkType, ctx: CanvasRenderingContext2D, globalScale: number) => void;
1770
+ /** Custom link rendering */
1771
+ linkCanvasObjectMode?: StringAccessor<LinkType>;
1772
+ linkCanvasObject?: (link: LinkType, ctx: CanvasRenderingContext2D, globalScale: number) => void;
1773
+ linkPointerAreaPaint?: (link: LinkType, color: string, ctx: CanvasRenderingContext2D, globalScale: number) => void;
1774
+ }
1775
+ /**
1776
+ * Performance targets for validation
1777
+ */
1778
+ interface PerformanceTargets {
1779
+ creation: number;
1780
+ dataLoad: number;
1781
+ firstRender: number;
1782
+ render?: number;
1783
+ methodCall: number;
1784
+ memoryGrowth: number;
1785
+ }
1786
+ /**
1787
+ * Performance metrics collected during runtime
1788
+ */
1789
+ interface PerformanceMetrics {
1790
+ creation: number;
1791
+ dataLoad: number;
1792
+ firstRender: number;
1793
+ render: number;
1794
+ memoryUsage: number;
1795
+ nodeCount: number;
1796
+ linkCount: number;
1797
+ methodCalls: number;
1798
+ optimizedForNodeCount: number;
1799
+ timestamp: number;
1800
+ }
1801
+
1802
+ /**
1803
+ * Force Graph Wrapper - Controls Component
1804
+ * Simple graph controls UI for zoom/pan/fit operations
1805
+ */
1806
+ type GraphControlsPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
1807
+ type GraphControlsOrientation = 'vertical' | 'horizontal';
1808
+ interface GraphControlsConfig {
1809
+ readonly enabled: boolean;
1810
+ readonly position?: GraphControlsPosition;
1811
+ readonly orientation?: GraphControlsOrientation;
1812
+ readonly offset?: {
1813
+ x: number;
1814
+ y: number;
1815
+ };
1816
+ readonly show?: {
1817
+ readonly zoomIn?: boolean;
1818
+ readonly zoomOut?: boolean;
1819
+ readonly reset?: boolean;
1820
+ readonly fit?: boolean;
1821
+ };
1822
+ }
1823
+
1824
+ /**
1825
+ * Force Graph Wrapper - Legends Component
1826
+ * Graph legends UI showing node types with colored indicators
1827
+ */
1828
+ type GraphLegendsPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
1829
+ interface GraphLegendsConfig {
1830
+ readonly enabled: boolean;
1831
+ readonly position?: GraphLegendsPosition;
1832
+ readonly offset?: {
1833
+ x: number;
1834
+ y: number;
1835
+ };
1836
+ readonly maxItems?: number;
1837
+ readonly showTitle?: boolean;
1838
+ readonly title?: string;
1839
+ }
1840
+
1841
+ /**
1842
+ * Configuration Types for Force-Graph Wrapper
1843
+ *
1844
+ * Complete configuration interface combining all aspects
1845
+ * of the force-graph wrapper functionality
1846
+ */
1847
+
1848
+ /**
1849
+ * Complete configuration for Force-Graph Wrapper
1850
+ */
1851
+ interface ForceGraphConfig<NodeType extends ForceGraphNode = ForceGraphNode, LinkType extends ForceGraphLink<NodeType> = ForceGraphLink<NodeType>> extends ForceConfig, CanvasConfig, InteractionConfig<NodeType, LinkType>, NodeStylingConfig<NodeType>, LinkStylingConfig<LinkType> {
1852
+ /** Container element */
1853
+ container: HTMLElement;
1854
+ /** Graph data */
1855
+ graphData?: ForceGraphData<NodeType, LinkType>;
1856
+ /** Performance monitoring */
1857
+ enablePerformanceMonitoring?: boolean;
1858
+ performanceTargets?: Partial<PerformanceTargets>;
1859
+ /** Page visibility handling for deterministic layouts */
1860
+ handlePageVisibility?: boolean;
1861
+ deterministicLayout?: boolean;
1862
+ /** Graph controls UI */
1863
+ controls?: GraphControlsConfig;
1864
+ /** Graph legends UI */
1865
+ legends?: GraphLegendsConfig;
1866
+ /** Lifecycle callbacks */
1867
+ onEngineTick?: () => void;
1868
+ onEngineStop?: () => void;
1869
+ onZoom?: (transform: {
1870
+ k: number;
1871
+ x: number;
1872
+ y: number;
1873
+ }) => void;
1874
+ onZoomEnd?: (transform: {
1875
+ k: number;
1876
+ x: number;
1877
+ y: number;
1878
+ }) => void;
1879
+ }
1880
+ /**
1881
+ * Minimal configuration for quick setup
1882
+ */
1883
+ interface MinimalForceGraphConfig<NodeType extends ForceGraphNode = ForceGraphNode, LinkType extends ForceGraphLink<NodeType> = ForceGraphLink<NodeType>> {
1884
+ container: HTMLElement;
1885
+ graphData: ForceGraphData<NodeType, LinkType>;
1886
+ width?: number;
1887
+ height?: number;
1888
+ }
1889
+ /**
1890
+ * Performance-focused configuration
1891
+ */
1892
+ interface PerformanceConfig {
1893
+ enablePerformanceMonitoring: true;
1894
+ autoPauseRedraw: boolean;
1895
+ warmupTicks: number;
1896
+ cooldownTime: number;
1897
+ performanceTargets: PerformanceTargets;
1898
+ }
1899
+ /**
1900
+ * Common presets for different use cases
1901
+ */
1902
+ declare const ConfigPresets: {
1903
+ /**
1904
+ * High-performance preset for large graphs (5000+ nodes)
1905
+ */
1906
+ readonly highPerformance: <NodeType extends ForceGraphNode, LinkType extends ForceGraphLink<NodeType>>() => Partial<ForceGraphConfig<NodeType, LinkType>>;
1907
+ /**
1908
+ * Interactive preset for medium graphs (50-1000 nodes)
1909
+ */
1910
+ readonly interactive: <NodeType extends ForceGraphNode, LinkType extends ForceGraphLink<NodeType>>() => Partial<ForceGraphConfig<NodeType, LinkType>>;
1911
+ /**
1912
+ * Minimal preset for small graphs (5-50 nodes)
1913
+ */
1914
+ readonly minimal: <NodeType extends ForceGraphNode, LinkType extends ForceGraphLink<NodeType>>() => Partial<ForceGraphConfig<NodeType, LinkType>>;
1915
+ };
1916
+ /**
1917
+ * Configuration builder for fluent API
1918
+ */
1919
+ declare class ForceGraphConfigBuilder<NodeType extends ForceGraphNode = ForceGraphNode, LinkType extends ForceGraphLink<NodeType> = ForceGraphLink<NodeType>> {
1920
+ private config;
1921
+ constructor(container: HTMLElement);
1922
+ data(graphData: ForceGraphData<NodeType, LinkType>): this;
1923
+ size(width: number, height: number): this;
1924
+ performance(preset: 'highPerformance' | 'interactive' | 'minimal'): this;
1925
+ nodeColor(accessor: NodeStylingConfig<NodeType>['nodeColor']): this;
1926
+ onNodeClick(handler: NodeEventHandler<NodeType>): this;
1927
+ build(): ForceGraphConfig<NodeType, LinkType>;
1928
+ }
1929
+
1930
+ /**
1931
+ * Performance Monitor for Force-Graph Wrapper
1932
+ *
1933
+ * Built-in performance tracking to catch bottlenecks early
1934
+ * and prevent exponential complexity growth
1935
+ */
1936
+
1937
+ declare class PerformanceMonitor {
1938
+ private metrics;
1939
+ private methodCallsDetailed;
1940
+ /**
1941
+ * Track execution time of any operation
1942
+ */
1943
+ track<T>(operation: string, fn: () => T): T;
1944
+ /**
1945
+ * Set specific metric values
1946
+ */
1947
+ setMetric(key: keyof PerformanceMetrics, value: number): void;
1948
+ /**
1949
+ * Get current metrics snapshot
1950
+ */
1951
+ getMetrics(): PerformanceMetrics;
1952
+ /**
1953
+ * Get performance summary with statistics
1954
+ */
1955
+ getSummary(): {
1956
+ averages: Record<string, number>;
1957
+ peaks: Record<string, number>;
1958
+ warnings: string[];
1959
+ nodeScaling: string;
1960
+ };
1961
+ /**
1962
+ * Reset all metrics
1963
+ */
1964
+ reset(): void;
1965
+ /**
1966
+ * Log performance summary to console
1967
+ */
1968
+ logSummary(): void;
1969
+ }
1970
+
1971
+ /**
1972
+ * Core methods available on force-graph instances
1973
+ * These mirror the methods from react-force-graph-2d
1974
+ */
1975
+ interface ForceGraphMethods<NodeType extends ForceGraphNode = ForceGraphNode, LinkType extends ForceGraphLink<NodeType> = ForceGraphLink<NodeType>> {
1976
+ d3ReheatSimulation(): void;
1977
+ stopAnimation(): void;
1978
+ pauseAnimation(): void;
1979
+ resumeAnimation(): void;
1980
+ centerAt(x: number, y: number, duration?: number): void;
1981
+ zoom(): number;
1982
+ zoom(scale: number, duration?: number): void;
1983
+ zoomToFit(padding?: number, duration?: number): void;
1984
+ screen2GraphCoords(screenX: number, screenY: number): {
1985
+ x: number;
1986
+ y: number;
1987
+ };
1988
+ graph2ScreenCoords(graphX: number, graphY: number): {
1989
+ x: number;
1990
+ y: number;
1991
+ };
1992
+ getGraphBbox(nodes?: NodeType[]): {
1993
+ x: [number, number];
1994
+ y: [number, number];
1995
+ };
1996
+ emitParticle(link: LinkType): void;
1997
+ d3Force(forceName: string): unknown;
1998
+ d3Force(forceName: string, forceImpl: unknown): ForceGraphInstance<NodeType, LinkType>;
1999
+ exportGraph(fileName?: string): Promise<void>;
2000
+ }
2001
+ /**
2002
+ * Configuration methods for fluent API
2003
+ */
2004
+ interface ForceGraphConfigMethods<NodeType extends ForceGraphNode = ForceGraphNode, LinkType extends ForceGraphLink<NodeType> = ForceGraphLink<NodeType>> {
2005
+ graphData(): ForceGraphData<NodeType, LinkType>;
2006
+ graphData(data: ForceGraphData<NodeType, LinkType>): ForceGraphInstance<NodeType, LinkType>;
2007
+ width(): number;
2008
+ width(width: number): ForceGraphInstance<NodeType, LinkType>;
2009
+ height(): number;
2010
+ height(height: number): ForceGraphInstance<NodeType, LinkType>;
2011
+ backgroundColor(): string;
2012
+ backgroundColor(color: string): ForceGraphInstance<NodeType, LinkType>;
2013
+ nodeRelSize(): number;
2014
+ nodeRelSize(size: number): ForceGraphInstance<NodeType, LinkType>;
2015
+ nodeColor(): ColorAccessor<NodeType>;
2016
+ nodeColor(color: ColorAccessor<NodeType>): ForceGraphInstance<NodeType, LinkType>;
2017
+ nodeVal(): NumberAccessor<NodeType>;
2018
+ nodeVal(val: NumberAccessor<NodeType>): ForceGraphInstance<NodeType, LinkType>;
2019
+ nodeLabel(): StringAccessor<NodeType>;
2020
+ nodeLabel(label: StringAccessor<NodeType>): ForceGraphInstance<NodeType, LinkType>;
2021
+ nodeVisibility(): BooleanAccessor<NodeType>;
2022
+ nodeVisibility(visibility: BooleanAccessor<NodeType>): ForceGraphInstance<NodeType, LinkType>;
2023
+ nodeCanvasObjectMode(): NodeAccessor<NodeType, CanvasCustomRenderMode>;
2024
+ nodeCanvasObjectMode(mode: NodeAccessor<NodeType, CanvasCustomRenderMode>): ForceGraphInstance<NodeType, LinkType>;
2025
+ linkColor(): ColorAccessor<LinkType>;
2026
+ linkColor(color: ColorAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2027
+ linkWidth(): NumberAccessor<LinkType>;
2028
+ linkWidth(width: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2029
+ linkLabel(): StringAccessor<LinkType>;
2030
+ linkLabel(label: StringAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2031
+ linkVisibility(): BooleanAccessor<LinkType>;
2032
+ linkVisibility(visibility: BooleanAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2033
+ linkDirectionalArrowLength(): NumberAccessor<LinkType>;
2034
+ linkDirectionalArrowLength(length: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2035
+ linkDirectionalArrowColor(): ColorAccessor<LinkType>;
2036
+ linkDirectionalArrowColor(color: ColorAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2037
+ linkDirectionalArrowRelPos(): NumberAccessor<LinkType>;
2038
+ linkDirectionalArrowRelPos(position: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2039
+ linkDirectionalParticles(): NumberAccessor<LinkType>;
2040
+ linkDirectionalParticles(particles: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2041
+ linkDirectionalParticleSpeed(): NumberAccessor<LinkType>;
2042
+ linkDirectionalParticleSpeed(speed: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2043
+ linkDirectionalParticleWidth(): NumberAccessor<LinkType>;
2044
+ linkDirectionalParticleWidth(width: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2045
+ linkDirectionalParticleColor(): ColorAccessor<LinkType>;
2046
+ linkDirectionalParticleColor(color: ColorAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2047
+ linkCurvature(): NumberAccessor<LinkType>;
2048
+ linkCurvature(curvature: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2049
+ linkCanvasObjectMode(): StringAccessor<LinkType>;
2050
+ linkCanvasObjectMode(mode: StringAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2051
+ onNodeClick(): NodeEventHandler<NodeType> | null;
2052
+ onNodeClick(handler: NodeEventHandler<NodeType> | null): ForceGraphInstance<NodeType, LinkType>;
2053
+ onNodeDoubleClick(): NodeEventHandler<NodeType> | null;
2054
+ onNodeDoubleClick(handler: NodeEventHandler<NodeType> | null): ForceGraphInstance<NodeType, LinkType>;
2055
+ onNodeHover(): NodeEventHandler<NodeType> | null;
2056
+ onNodeHover(handler: NodeEventHandler<NodeType> | null): ForceGraphInstance<NodeType, LinkType>;
2057
+ onLinkClick(): LinkEventHandler<LinkType> | null;
2058
+ onLinkClick(handler: LinkEventHandler<LinkType> | null): ForceGraphInstance<NodeType, LinkType>;
2059
+ onLinkHover(): LinkEventHandler<LinkType> | null;
2060
+ onLinkHover(handler: LinkEventHandler<LinkType> | null): ForceGraphInstance<NodeType, LinkType>;
2061
+ onRenderFramePre(): CanvasRenderHandler | null;
2062
+ onRenderFramePre(handler: CanvasRenderHandler | null): ForceGraphInstance<NodeType, LinkType>;
2063
+ onRenderFramePost(): CanvasRenderHandler | null;
2064
+ onRenderFramePost(handler: CanvasRenderHandler | null): ForceGraphInstance<NodeType, LinkType>;
2065
+ cooldownTime(): number;
2066
+ cooldownTime(time: number): ForceGraphInstance<NodeType, LinkType>;
2067
+ cooldownTicks(): number;
2068
+ cooldownTicks(ticks: number): ForceGraphInstance<NodeType, LinkType>;
2069
+ d3AlphaDecay(): number;
2070
+ d3AlphaDecay(decay: number): ForceGraphInstance<NodeType, LinkType>;
2071
+ d3AlphaMin(): number;
2072
+ d3AlphaMin(min: number): ForceGraphInstance<NodeType, LinkType>;
2073
+ d3VelocityDecay(): number;
2074
+ d3VelocityDecay(decay: number): ForceGraphInstance<NodeType, LinkType>;
2075
+ enableNodeDrag(): boolean;
2076
+ enableNodeDrag(enable: boolean): ForceGraphInstance<NodeType, LinkType>;
2077
+ enableZoomInteraction(): boolean;
2078
+ enableZoomInteraction(enable: boolean): ForceGraphInstance<NodeType, LinkType>;
2079
+ enablePanInteraction(): boolean;
2080
+ enablePanInteraction(enable: boolean): ForceGraphInstance<NodeType, LinkType>;
2081
+ autoPauseRedraw(): boolean;
2082
+ autoPauseRedraw(enable: boolean): ForceGraphInstance<NodeType, LinkType>;
2083
+ nodeCanvasObject(): ((node: NodeType, ctx: CanvasRenderingContext2D, globalScale: number) => void) | null;
2084
+ nodeCanvasObject(paintFunction: ((node: NodeType, ctx: CanvasRenderingContext2D, globalScale: number) => void) | null): ForceGraphInstance<NodeType, LinkType>;
2085
+ linkCanvasObject(): ((link: LinkType, ctx: CanvasRenderingContext2D, globalScale: number) => void) | null;
2086
+ linkCanvasObject(paintFunction: ((link: LinkType, ctx: CanvasRenderingContext2D, globalScale: number) => void) | null): ForceGraphInstance<NodeType, LinkType>;
2087
+ onEngineStop(): (() => void) | undefined;
2088
+ onEngineStop(handler: (() => void) | undefined): ForceGraphInstance<NodeType, LinkType>;
2089
+ onEngineTick(): (() => void) | undefined;
2090
+ onEngineTick(handler: (() => void) | undefined): ForceGraphInstance<NodeType, LinkType>;
2091
+ }
2092
+ /**
2093
+ * Performance monitoring methods
2094
+ */
2095
+ interface ForceGraphPerformanceMethods {
2096
+ getPerformanceMetrics(): PerformanceMetrics;
2097
+ resetPerformanceMetrics(): void;
2098
+ logPerformanceSummary(): void;
2099
+ validatePerformance(): {
2100
+ passed: boolean;
2101
+ warnings: string[];
2102
+ recommendations: string[];
2103
+ };
2104
+ }
2105
+ /**
2106
+ * Complete Force-Graph instance interface
2107
+ */
2108
+ interface ForceGraphInstance<NodeType extends ForceGraphNode = ForceGraphNode, LinkType extends ForceGraphLink<NodeType> = ForceGraphLink<NodeType>> extends ForceGraphMethods<NodeType, LinkType>, ForceGraphConfigMethods<NodeType, LinkType>, ForceGraphPerformanceMethods {
2109
+ render(): void;
2110
+ destroy(): void;
2111
+ triggerKapsuleUpdate(): void;
2112
+ _getForceGraphInstance(): unknown;
2113
+ }
2114
+ /**
2115
+ * Factory function type for creating instances
2116
+ */
2117
+ interface CreateForceGraphFunction {
2118
+ <NodeType extends ForceGraphNode = ForceGraphNode, LinkType extends ForceGraphLink<NodeType> = ForceGraphLink<NodeType>>(container: HTMLElement): ForceGraphInstance<NodeType, LinkType>;
2119
+ }
2120
+
2121
+ /**
2122
+ * Step 4: Rendering Performance Monitor
2123
+ *
2124
+ * Monitors canvas rendering performance, frame rates, and optimization metrics
2125
+ * Target: 60fps @ 1000 nodes with smooth animations
2126
+ */
2127
+ interface RenderingMetrics {
2128
+ fps: number;
2129
+ averageFps: number;
2130
+ frameTime: number;
2131
+ averageFrameTime: number;
2132
+ droppedFrames: number;
2133
+ renderCalls: number;
2134
+ canvasOperations: number;
2135
+ nodeCount: number;
2136
+ linkCount: number;
2137
+ lastMeasurement: number;
2138
+ renderingEfficiency: number;
2139
+ memoryUsage: number;
2140
+ }
2141
+
2142
+ /**
2143
+ * Force-Graph Wrapper - Main Implementation
2144
+ *
2145
+ * Framework-independent wrapper around the core force-graph library
2146
+ * with built-in performance monitoring and TypeScript generics
2147
+ */
2148
+
2149
+ /**
2150
+ * Main Force-Graph Wrapper Class
2151
+ *
2152
+ * Step 1: Basic class structure with performance monitoring
2153
+ * Target: Creation time < 1ms
2154
+ */
2155
+ declare class ForceGraphWrapper<NodeType extends ForceGraphNode = ForceGraphNode, LinkType extends ForceGraphLink<NodeType> = ForceGraphLink<NodeType>> implements ForceGraphInstance<NodeType, LinkType> {
2156
+ private forceGraph;
2157
+ private container;
2158
+ private performanceMonitor;
2159
+ private renderingMonitor;
2160
+ private canvasOptimizer;
2161
+ private config;
2162
+ private isInitialized;
2163
+ private isDestroyed;
2164
+ private isRenderingOptimized;
2165
+ private enableVerboseLogging;
2166
+ private wasInitializedHidden;
2167
+ private visibilityChangeHandler;
2168
+ private wasInitializedOutOfView;
2169
+ private intersectionObserver;
2170
+ private webWorkerPhysicsCompleted;
2171
+ private physicsTimeoutId;
2172
+ private lastKnownDimensions;
2173
+ private deferredFitViewParams;
2174
+ private pendingFitView;
2175
+ private performanceTestInterval;
2176
+ private canvasClickHandler;
2177
+ private exportTimeoutId;
2178
+ private controlsInstance;
2179
+ private legendsInstance;
2180
+ /**
2181
+ * Helper method to safely cast and call methods on the force graph instance
2182
+ */
2183
+ private getGraphInstance;
2184
+ /**
2185
+ * Constructor - Step 1 Performance Test
2186
+ * Target: < 1ms creation time
2187
+ */
2188
+ constructor(container: HTMLElement, config?: Partial<ForceGraphConfig<NodeType, LinkType>>);
2189
+ /**
2190
+ * Step 1 Performance Validation
2191
+ */
2192
+ private validateCreationPerformance;
2193
+ /**
2194
+ * Setup automatic page visibility handling for deterministic layouts
2195
+ * Ensures consistent graph layouts regardless of tab visibility during initialization
2196
+ */
2197
+ private setupPageVisibilityHandling;
2198
+ /**
2199
+ * Cleanup page visibility handling
2200
+ */
2201
+ private cleanupPageVisibilityHandling;
2202
+ /**
2203
+ * Setup deterministic physics handling for viewport visibility
2204
+ * Ensures consistent physics timing regardless of element visibility
2205
+ */
2206
+ private setupDeterministicPhysics;
2207
+ /**
2208
+ * Find the scrollable parent container for intersection observer
2209
+ * Similar to Angular component approach but more generic
2210
+ */
2211
+ private findScrollableParent;
2212
+ /**
2213
+ * Setup deferred fitView mechanism using IntersectionObserver
2214
+ * This handles library-level viewport-aware fitView
2215
+ */
2216
+ private setupDeferredFitView;
2217
+ /**
2218
+ * Execute fitView immediately (bypass visibility checks)
2219
+ */
2220
+ private executeFitViewNow;
2221
+ /**
2222
+ * Cleanup deferred fitView intersection observer
2223
+ */
2224
+ private cleanupDeferredFitView;
2225
+ /**
2226
+ * Cleanup performance test interval
2227
+ */
2228
+ private cleanupPerformanceTest;
2229
+ /**
2230
+ * Cleanup export animation timeout
2231
+ */
2232
+ private cleanupExportTimeout;
2233
+ /**
2234
+ * Cleanup canvas event listeners
2235
+ */
2236
+ private cleanupCanvasEventListeners;
2237
+ /**
2238
+ * Check if element is currently visible (even partially) in viewport
2239
+ */
2240
+ private isElementInViewport;
2241
+ /**
2242
+ * Cache container dimensions when they're valid (non-zero)
2243
+ */
2244
+ private cacheContainerDimensions;
2245
+ /**
2246
+ * Check if container has valid dimensions and cache them
2247
+ */
2248
+ private hasValidDimensions;
2249
+ /**
2250
+ * Run deterministic physics using Web Worker for off-screen graphs only
2251
+ */
2252
+ private runWebWorkerPhysics;
2253
+ /**
2254
+ * Apply Web Worker results to force-graph instance WITHOUT disrupting interactions
2255
+ */
2256
+ private applyWebWorkerResults;
2257
+ /**
2258
+ * Cleanup deterministic physics handling
2259
+ */
2260
+ private cleanupDeterministicPhysics;
2261
+ /**
2262
+ * Initialize the underlying force-graph instance
2263
+ * Step 2: Data loading with performance validation
2264
+ * Target: Linear scaling, < 10ms per 1000 nodes
2265
+ */
2266
+ private initializeForceGraph;
2267
+ /**
2268
+ * Apply configuration to force-graph instance
2269
+ * Step 2: Performance-optimized configuration application
2270
+ */
2271
+ private applyConfiguration;
2272
+ /**
2273
+ * Step 2 Performance Validation for Initialization
2274
+ */
2275
+ private validateInitializationPerformance;
2276
+ /**
2277
+ * Validate data loading performance based on node/link count
2278
+ * Step 2: Linear scaling validation
2279
+ */
2280
+ private validateDataLoadingPerformance;
2281
+ d3ReheatSimulation(): void;
2282
+ stopAnimation(): void;
2283
+ pauseAnimation(): void;
2284
+ resumeAnimation(): void;
2285
+ centerAt(x: number, y: number, duration?: number): void;
2286
+ zoom(): number;
2287
+ zoom(scale: number, duration?: number): void;
2288
+ zoomToFit(padding?: number, duration?: number): void;
2289
+ screen2GraphCoords(screenX: number, screenY: number): {
2290
+ x: number;
2291
+ y: number;
2292
+ };
2293
+ graph2ScreenCoords(graphX: number, graphY: number): {
2294
+ x: number;
2295
+ y: number;
2296
+ };
2297
+ getGraphBbox(nodes?: NodeType[]): {
2298
+ x: [number, number];
2299
+ y: [number, number];
2300
+ };
2301
+ emitParticle(link: LinkType): void;
2302
+ d3Force(forceName: string): unknown;
2303
+ d3Force(forceName: string, forceImpl: unknown): ForceGraphInstance<NodeType, LinkType>;
2304
+ graphData(): ForceGraphData<NodeType, LinkType>;
2305
+ graphData(data: ForceGraphData<NodeType, LinkType>): ForceGraphInstance<NodeType, LinkType>;
2306
+ width(): number;
2307
+ width(width: number): ForceGraphInstance<NodeType, LinkType>;
2308
+ height(): number;
2309
+ height(height: number): ForceGraphInstance<NodeType, LinkType>;
2310
+ backgroundColor(): string;
2311
+ backgroundColor(color: string): ForceGraphInstance<NodeType, LinkType>;
2312
+ nodeColor(): ColorAccessor<NodeType>;
2313
+ nodeColor(color: ColorAccessor<NodeType>): ForceGraphInstance<NodeType, LinkType>;
2314
+ nodeVal(): NumberAccessor<NodeType>;
2315
+ nodeVal(val: NumberAccessor<NodeType>): ForceGraphInstance<NodeType, LinkType>;
2316
+ nodeRelSize(): number;
2317
+ nodeRelSize(size: number): ForceGraphInstance<NodeType, LinkType>;
2318
+ nodeLabel(): StringAccessor<NodeType>;
2319
+ nodeLabel(label: StringAccessor<NodeType>): ForceGraphInstance<NodeType, LinkType>;
2320
+ nodeVisibility(): BooleanAccessor<NodeType>;
2321
+ nodeVisibility(visibility: BooleanAccessor<NodeType>): ForceGraphInstance<NodeType, LinkType>;
2322
+ nodeCanvasObjectMode(): NodeAccessor<NodeType, CanvasCustomRenderMode>;
2323
+ nodeCanvasObjectMode(mode: NodeAccessor<NodeType, CanvasCustomRenderMode>): ForceGraphInstance<NodeType, LinkType>;
2324
+ linkColor(): ColorAccessor<LinkType>;
2325
+ linkColor(color: ColorAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2326
+ linkWidth(): NumberAccessor<LinkType>;
2327
+ linkWidth(width: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2328
+ linkLabel(): StringAccessor<LinkType>;
2329
+ linkLabel(label: StringAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2330
+ linkVisibility(): BooleanAccessor<LinkType>;
2331
+ linkVisibility(visibility: BooleanAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2332
+ linkDirectionalArrowLength(): NumberAccessor<LinkType>;
2333
+ linkDirectionalArrowLength(length: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2334
+ linkDirectionalParticles(): NumberAccessor<LinkType>;
2335
+ linkDirectionalParticles(particles: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2336
+ linkDirectionalArrowColor(): ColorAccessor<LinkType>;
2337
+ linkDirectionalArrowColor(color: ColorAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2338
+ linkDirectionalArrowRelPos(): NumberAccessor<LinkType>;
2339
+ linkDirectionalArrowRelPos(position: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2340
+ linkDirectionalParticleSpeed(): NumberAccessor<LinkType>;
2341
+ linkDirectionalParticleSpeed(speed: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2342
+ linkDirectionalParticleWidth(): NumberAccessor<LinkType>;
2343
+ linkDirectionalParticleWidth(width: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2344
+ linkDirectionalParticleColor(): ColorAccessor<LinkType>;
2345
+ linkDirectionalParticleColor(color: ColorAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2346
+ linkCurvature(): NumberAccessor<LinkType>;
2347
+ linkCurvature(curvature: NumberAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2348
+ linkCanvasObjectMode(): StringAccessor<LinkType>;
2349
+ linkCanvasObjectMode(mode: StringAccessor<LinkType>): ForceGraphInstance<NodeType, LinkType>;
2350
+ onNodeClick(): NodeEventHandler<NodeType> | null;
2351
+ onNodeClick(handler: NodeEventHandler<NodeType> | null): ForceGraphInstance<NodeType, LinkType>;
2352
+ onNodeDoubleClick(): NodeEventHandler<NodeType> | null;
2353
+ onNodeDoubleClick(handler: NodeEventHandler<NodeType> | null): ForceGraphInstance<NodeType, LinkType>;
2354
+ onNodeHover(): NodeEventHandler<NodeType> | null;
2355
+ onNodeHover(handler: NodeEventHandler<NodeType> | null): ForceGraphInstance<NodeType, LinkType>;
2356
+ onLinkClick(): LinkEventHandler<LinkType> | null;
2357
+ onLinkClick(handler: LinkEventHandler<LinkType> | null): ForceGraphInstance<NodeType, LinkType>;
2358
+ onLinkHover(): LinkEventHandler<LinkType> | null;
2359
+ onLinkHover(handler: LinkEventHandler<LinkType> | null): ForceGraphInstance<NodeType, LinkType>;
2360
+ onRenderFramePre(): CanvasRenderHandler | null;
2361
+ onRenderFramePre(handler: CanvasRenderHandler | null): ForceGraphInstance<NodeType, LinkType>;
2362
+ onRenderFramePost(): CanvasRenderHandler | null;
2363
+ onRenderFramePost(handler: CanvasRenderHandler | null): ForceGraphInstance<NodeType, LinkType>;
2364
+ cooldownTime(): number;
2365
+ cooldownTime(time: number): ForceGraphInstance<NodeType, LinkType>;
2366
+ d3AlphaDecay(): number;
2367
+ d3AlphaDecay(decay: number): ForceGraphInstance<NodeType, LinkType>;
2368
+ d3VelocityDecay(): number;
2369
+ d3VelocityDecay(decay: number): ForceGraphInstance<NodeType, LinkType>;
2370
+ onEngineStop(): (() => void) | undefined;
2371
+ onEngineStop(handler: (() => void) | undefined): ForceGraphInstance<NodeType, LinkType>;
2372
+ onEngineTick(): (() => void) | undefined;
2373
+ onEngineTick(handler: (() => void) | undefined): ForceGraphInstance<NodeType, LinkType>;
2374
+ getPerformanceMetrics(): PerformanceMetrics;
2375
+ resetPerformanceMetrics(): void;
2376
+ logPerformanceSummary(): void;
2377
+ validatePerformance(): {
2378
+ passed: boolean;
2379
+ warnings: string[];
2380
+ recommendations: string[];
2381
+ };
2382
+ /**
2383
+ * Setup advanced rendering performance monitoring
2384
+ * Target: 60fps @ 1000 nodes with optimizations
2385
+ */
2386
+ private setupRenderingMonitoring;
2387
+ /**
2388
+ * Start advanced rendering performance monitoring
2389
+ */
2390
+ private startRenderingMonitoring;
2391
+ /**
2392
+ * Stop rendering performance monitoring
2393
+ */
2394
+ private stopRenderingMonitoring;
2395
+ /**
2396
+ * Get current rendering performance metrics
2397
+ */
2398
+ getRenderingMetrics(): RenderingMetrics | null;
2399
+ /**
2400
+ * Validate rendering performance against Step 4 targets
2401
+ */
2402
+ validateRenderingPerformance(): {
2403
+ passed: boolean;
2404
+ metrics: RenderingMetrics;
2405
+ validation: {
2406
+ passed: boolean;
2407
+ results: {
2408
+ fpsTarget: {
2409
+ expected: number;
2410
+ actual: number;
2411
+ passed: boolean;
2412
+ };
2413
+ frameTimeTarget: {
2414
+ expected: number;
2415
+ actual: number;
2416
+ passed: boolean;
2417
+ };
2418
+ droppedFramesTarget: {
2419
+ expected: number;
2420
+ actual: number;
2421
+ passed: boolean;
2422
+ };
2423
+ efficiencyTarget: {
2424
+ expected: number;
2425
+ actual: number;
2426
+ passed: boolean;
2427
+ };
2428
+ };
2429
+ overallScore: number;
2430
+ };
2431
+ recommendations: string[];
2432
+ };
2433
+ /**
2434
+ * Optimize rendering for large datasets
2435
+ * Implements performance optimizations based on node count
2436
+ */
2437
+ optimizeForDataset(nodeCount: number): void;
2438
+ /**
2439
+ * Force a rendering performance test
2440
+ * Useful for validation during data loading
2441
+ */
2442
+ testRenderingPerformance(durationMs?: number): Promise<{
2443
+ averageFPS: number;
2444
+ minFPS: number;
2445
+ maxFPS: number;
2446
+ passed: boolean;
2447
+ targetFPS: number;
2448
+ }>;
2449
+ render(): void;
2450
+ cooldownTicks(): number;
2451
+ cooldownTicks(ticks: number): ForceGraphInstance<NodeType, LinkType>;
2452
+ d3AlphaMin(): number;
2453
+ d3AlphaMin(min: number): ForceGraphInstance<NodeType, LinkType>;
2454
+ enableNodeDrag(): boolean;
2455
+ enableNodeDrag(enable: boolean): ForceGraphInstance<NodeType, LinkType>;
2456
+ nodeCanvasObject(): ((node: NodeType, ctx: CanvasRenderingContext2D, globalScale: number) => void) | null;
2457
+ nodeCanvasObject(paintFunction: ((node: NodeType, ctx: CanvasRenderingContext2D, globalScale: number) => void) | null): ForceGraphInstance<NodeType, LinkType>;
2458
+ linkCanvasObject(): ((link: LinkType, ctx: CanvasRenderingContext2D, globalScale: number) => void) | null;
2459
+ linkCanvasObject(paintFunction: ((link: LinkType, ctx: CanvasRenderingContext2D, globalScale: number) => void) | null): ForceGraphInstance<NodeType, LinkType>;
2460
+ autoPauseRedraw(): boolean;
2461
+ autoPauseRedraw(enable: boolean): ForceGraphInstance<NodeType, LinkType>;
2462
+ enableZoomInteraction(): boolean;
2463
+ enableZoomInteraction(enable: boolean): ForceGraphInstance<NodeType, LinkType>;
2464
+ enablePanInteraction(): boolean;
2465
+ enablePanInteraction(enable: boolean): ForceGraphInstance<NodeType, LinkType>;
2466
+ /**
2467
+ * Initialize graph controls if enabled
2468
+ */
2469
+ private initializeControls;
2470
+ /**
2471
+ * Zoom in by a factor of 1.5
2472
+ */
2473
+ private zoomIn;
2474
+ /**
2475
+ * Zoom out by a factor of 0.67
2476
+ */
2477
+ private zoomOut;
2478
+ /**
2479
+ * Fit the graph to the viewport
2480
+ */
2481
+ private fitView;
2482
+ /**
2483
+ * Reset the view to initial state
2484
+ */
2485
+ private resetView;
2486
+ /**
2487
+ * Cleanup graph controls
2488
+ */
2489
+ private cleanupControls;
2490
+ /**
2491
+ * Initialize graph legends if enabled
2492
+ */
2493
+ private initializeLegends;
2494
+ /**
2495
+ * Update legends with current graph data
2496
+ */
2497
+ private updateLegends;
2498
+ /**
2499
+ * Cleanup graph legends
2500
+ */
2501
+ private cleanupLegends;
2502
+ /**
2503
+ * Draw legends on the export canvas (similar to React implementation)
2504
+ */
2505
+ private drawLegendsOnExportCanvas;
2506
+ /**
2507
+ * Draw rounded rectangle helper method
2508
+ */
2509
+ private drawRoundedRect;
2510
+ /**
2511
+ * Export graph as PNG image
2512
+ */
2513
+ exportGraph(fileName?: string): Promise<void>;
2514
+ /**
2515
+ * Setup double-click functionality
2516
+ * - Double-click on node: center and zoom to node
2517
+ * - Double-click on canvas: fit view
2518
+ */
2519
+ private setupDoubleClickHandling;
2520
+ /**
2521
+ * Smooth zoom to fit that animates from current position
2522
+ */
2523
+ private smoothZoomToFit;
2524
+ /**
2525
+ * Trigger Kapsule update to ensure render callbacks continue working
2526
+ * This is essential for onRenderFramePost callbacks after physics simulation stops
2527
+ */
2528
+ triggerKapsuleUpdate(): void;
2529
+ /**
2530
+ * Find node at given graph coordinates
2531
+ */
2532
+ private findNodeAtPosition;
2533
+ destroy(): void;
2534
+ _getForceGraphInstance(): unknown;
2535
+ }
2536
+ /**
2537
+ * Factory function for creating force-graph instances
2538
+ * Step 1 Performance Target: < 1ms total creation time
2539
+ */
2540
+ declare function createForceGraph<NodeType extends ForceGraphNode = ForceGraphNode, LinkType extends ForceGraphLink<NodeType> = ForceGraphLink<NodeType>>(container: HTMLElement, config?: Partial<ForceGraphConfig<NodeType, LinkType>>): ForceGraphInstance<NodeType, LinkType>;
2541
+
2542
+ /**
2543
+ * Force-Graph Wrapper - Main Export
2544
+ *
2545
+ * Framework-independent wrapper around force-graph library
2546
+ * with TypeScript generics and performance monitoring
2547
+ */
2548
+
2549
+ declare const VERSION = "1.0.0-alpha.1";
2550
+ declare const LIBRARY_INFO: {
2551
+ readonly name: "force-graph-wrapper";
2552
+ readonly version: "1.0.0-alpha.1";
2553
+ readonly description: "Framework-independent TypeScript wrapper for force-graph library";
2554
+ readonly performance: "Built-in performance monitoring and optimization";
2555
+ readonly compatibility: "Vanilla JS, React, Angular, Vue.js";
2556
+ };
2557
+
2558
+ export { type ArrowRenderStyle, type BaseGraphConfig, CanvasManager, type CanvasRenderConfig, type CanvasRenderHandler, type CanvasState, ConfigPresets, type ControlsController, type Coordinates, type CreateForceGraphFunction, DEFAULT_COLORS, DEFAULT_HOVER_STYLES, DEFAULT_LINK_LABEL_STYLE, DEFAULT_LINK_STYLE, type DragConfig, type DragInteractionConfig, DragManager, type DragState, ErrorHandler, type ForceGraphConfig, ForceGraphConfigBuilder, type ForceGraphConfigMethods, type ForceGraphData, type ForceGraphInstance, type ForceGraphLink, type ForceGraphMethods, type ForceGraphNode, type ForceGraphPerformanceMethods, ForceGraphWrapper, type GraphControlsConfig$1 as GraphControlsConfig, type GraphControlsOrientation$1 as GraphControlsOrientation, type GraphControlsPosition$1 as GraphControlsPosition, type GraphInteractionConfig, type GraphLink, type GraphNode, type GraphNodeWithInitial, type GraphTooltipTheme, type HighlightInteractionConfig, type HoverEvent, type HoverInteractionConfig, HoverManager, type HoverState, type HoverStyles, type IconName, type IconSvgName, type InteractionColors, type InteractionConfig$1 as InteractionConfig, LIBRARY_INFO, type LegendConfig, type LegendPosition, type LinkArrowStyle, type LinkColors, type LinkEventHandler, type LinkLabelRenderStyle, type LinkLabelStyle, type LinkRenderStyle, type LinkSelectHandler, type LinkStyle, type MinimalForceGraphConfig, NeutralColor, type NodeColorPalette, type NodeEventHandler, type NodeLabelRenderStyle, type NodeRenderStyle, type NodeSelectHandler, type NodeStyle, type Orientation, type PerformanceConfig, type PerformanceMetrics, PerformanceMonitor, type PhysicsConfig, PhysicsManager, PointerManager, type PointerState, type Position, PrimaryColor, type RenderStyles, Renderer, type ResolvedLinkLabelStyle, type ResolvedLinkStyle, SecondaryColor, type SelectionEvent, type SelectionInteractionConfig, SelectionManager, type SelectionState, type SimulationConfig, StandardColor, type TooltipInteractionConfig, type TooltipPlacement, type UIColors, type V2Config, V2Graph, type V2Instance, type V2Link, type V2Node, VERSION, ValidationError, type ZoomConfig, ZoomManager, createForceGraph, createV2Graph, getIcon, getIconSvg, iconSvg, icons, isValidLinkStyle, isValidNodeStyle, mergeLinkStyle, mergeNodeStyle };