@fusefactory/fuse-three-forcegraph 1.0.7 → 1.0.8

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.
Files changed (3) hide show
  1. package/dist/index.d.mts +1551 -1551
  2. package/dist/index.mjs +4535 -4535
  3. package/package.json +46 -46
package/dist/index.d.mts CHANGED
@@ -1,1552 +1,1552 @@
1
- import CameraControls from "camera-controls";
2
- import * as THREE from "three";
3
-
4
- //#region core/Clock.d.ts
5
- /**
6
- * Clock - Unified timing for the force graph package
7
- */
8
- declare class Clock {
9
- private previousTime;
10
- private elapsedTime;
11
- private deltaTime;
12
- private isRunning;
13
- private maxDeltaTime;
14
- constructor();
15
- /**
16
- * Start the clock
17
- */
18
- start(): void;
19
- /**
20
- * Stop the clock
21
- */
22
- stop(): void;
23
- /**
24
- * Update the clock - call once per frame
25
- * @returns delta time in seconds
26
- */
27
- update(): number;
28
- /**
29
- * Get delta time in seconds
30
- */
31
- getDeltaTime(): number;
32
- /**
33
- * Get total elapsed time in seconds
34
- */
35
- getElapsedTime(): number;
36
- /**
37
- * Check if clock is running
38
- */
39
- getIsRunning(): boolean;
40
- }
41
- //#endregion
42
- //#region types/iCameraMode.d.ts
43
- declare enum CameraMode {
44
- Orbit = "orbit",
45
- Map = "map",
46
- }
47
- //#endregion
48
- //#region rendering/CameraController.d.ts
49
- interface CameraConfig {
50
- fov?: number;
51
- aspect?: number;
52
- near?: number;
53
- far?: number;
54
- position?: THREE.Vector3;
55
- target?: THREE.Vector3;
56
- minDistance?: number;
57
- maxDistance?: number;
58
- }
59
- interface ControlsConfig {
60
- smoothTime?: number;
61
- dollyToCursor?: boolean;
62
- infinityDolly?: boolean;
63
- enableZoom?: boolean;
64
- enableRotation?: boolean;
65
- enablePan?: boolean;
66
- minDistance?: number;
67
- maxDistance?: number;
68
- maxPolarAngle?: number;
69
- minPolarAngle?: number;
70
- minAzimuthAngle?: number;
71
- maxAzimuthAngle?: number;
72
- }
73
- declare class CameraController {
74
- camera: THREE.PerspectiveCamera;
75
- controls: CameraControls;
76
- private sceneBounds;
77
- private domElement;
78
- private autorotateEnabled;
79
- private autorotateSpeed;
80
- private userIsActive;
81
- constructor(domelement: HTMLElement, config?: CameraConfig);
82
- private handleWheel;
83
- private setupDefaultControls;
84
- /**
85
- * Set camera control mode
86
- */
87
- setMode(mode: CameraMode): void;
88
- /**
89
- * Set camera boundary
90
- */
91
- setBoundary(box: THREE.Box3): void;
92
- /**
93
- * Update camera controls (should be called in render loop)
94
- * Only autorotate if enabled and user is inactive
95
- */
96
- update(delta: number): boolean;
97
- /**
98
- * Set autorotate enabled/disabled
99
- */
100
- setAutorotate(enabled: boolean, speed?: number): void;
101
- /**
102
- * Set user activity state
103
- */
104
- setUserIsActive(isActive: boolean): void;
105
- /**
106
- * Configure camera controls
107
- */
108
- configureControls(config: ControlsConfig): void;
109
- /**
110
- * Resize camera when window resizes
111
- */
112
- resize(width: number, height: number): void;
113
- /**
114
- * Animate camera to look at a specific target from a specific position
115
- */
116
- setLookAt(position: THREE.Vector3, target: THREE.Vector3, enableTransition?: boolean): Promise<void>;
117
- /**
118
- * Reset camera to default position
119
- */
120
- reset(position?: THREE.Vector3, target?: THREE.Vector3, enableTransition?: boolean): Promise<void>;
121
- /**
122
- * Enable/disable controls
123
- */
124
- setEnabled(enabled: boolean): void;
125
- /**
126
- * Get current camera target (look-at point)
127
- */
128
- getTarget(out?: THREE.Vector3): THREE.Vector3;
129
- /**
130
- * Dispose camera manager and clean up
131
- */
132
- dispose(): void;
133
- /**
134
- * Clear camera bounds (remove boundary restrictions)
135
- */
136
- clearBounds(): void;
137
- /**
138
- * Get current scene bounds
139
- */
140
- getSceneBounds(): THREE.Box3 | null;
141
- /**
142
- * Update scene bounds used by the camera manager.
143
- * Stores the bounds for future use (e.g. constraining controls).
144
- */
145
- updateBounds(box: THREE.Box3): void;
146
- /**
147
- * Unified configuration method
148
- */
149
- setOptions(options: {
150
- controls?: ControlsConfig;
151
- autoRotate?: boolean;
152
- autoRotateSpeed?: number;
153
- }): void;
154
- }
155
- //#endregion
156
- //#region rendering/PostProcessing.d.ts
157
- type AntialiasingMode = 'msaa' | 'smaa' | 'fxaa' | 'none';
158
- //#endregion
159
- //#region types/iGraphLink.d.ts
160
- interface GraphLink {
161
- source: string;
162
- target: string;
163
- }
164
- //#endregion
165
- //#region types/iGraphNode.d.ts
166
- interface GraphNode {
167
- id: string;
168
- label?: string;
169
- description?: string;
170
- thumbnailUrl?: string;
171
- category?: string;
172
- x?: number;
173
- y?: number;
174
- z?: number;
175
- fx?: number;
176
- fy?: number;
177
- fz?: number;
178
- state?: NodeState;
179
- metadata?: any;
180
- }
181
- declare enum NodeState {
182
- Hidden = 0,
183
- // = 0 not rendered
184
- Passive = 1,
185
- // = 1 rendered, not influencing simulation,
186
- Fixed = 2,
187
- // = 2 rendered, influencing simulation, but not moving
188
- Active = 3,
189
- }
190
- //#endregion
191
- //#region types/iGraphData.d.ts
192
- interface GraphData {
193
- nodes: GraphNode[];
194
- links: GraphLink[];
195
- metadata?: any;
196
- }
197
- //#endregion
198
- //#region types/iForceConfig.d.ts
199
- interface ForceConfig {
200
- collisionStrength: number;
201
- collisionRadius: number;
202
- collisionMaxDistance: number;
203
- enableCollision: boolean;
204
- manyBodyStrength: number;
205
- manyBodyMinDistance: number;
206
- manyBodyMaxDistance: number;
207
- enableManyBody: boolean;
208
- springStrength: number;
209
- springLength: number;
210
- springDamping: number;
211
- maxLinks: number;
212
- enableLinks: boolean;
213
- gravity: number;
214
- enableGravity: boolean;
215
- attractorStrength: number;
216
- enableAttractors: boolean;
217
- elasticStrength: number;
218
- enableElastic: boolean;
219
- dragStrength: number;
220
- damping: number;
221
- alpha: number;
222
- alphaDecay: number;
223
- deltaTime: number;
224
- spaceSize: number;
225
- maxVelocity: number;
226
- is3D: boolean;
227
- }
228
- //#endregion
229
- //#region types/iGraphPreset.d.ts
230
- interface GraphPreset {
231
- name: string;
232
- force?: Partial<ForceConfig>;
233
- camera?: {
234
- mode?: CameraMode;
235
- position?: {
236
- x: number;
237
- y: number;
238
- z: number;
239
- };
240
- target?: {
241
- x: number;
242
- y: number;
243
- z: number;
244
- };
245
- zoom?: number;
246
- transitionDuration?: number;
247
- minDistance?: number;
248
- maxDistance?: number;
249
- boundary?: {
250
- min: {
251
- x: number;
252
- y: number;
253
- z: number;
254
- };
255
- max: {
256
- x: number;
257
- y: number;
258
- z: number;
259
- };
260
- } | null;
261
- };
262
- nodes?: {
263
- state?: (node: GraphNode) => NodeState;
264
- };
265
- links?: {
266
- opacity?: number;
267
- noiseStrength?: number;
268
- };
269
- }
270
- //#endregion
271
- //#region ui/Tooltips.d.ts
272
- /**
273
- * Renderer function type for custom tooltip rendering
274
- * Can mount React, Vue, or any other framework component
275
- */
276
- type TooltipRenderer = (container: HTMLElement, node: GraphNode, type: 'preview' | 'full', x: number, y: number, onPositionUpdate?: (callback: (x: number, y: number) => void) => void) => void | (() => void);
277
- /**
278
- * Cursor handler for custom cursor behavior
279
- */
280
- type CursorHandler = (canvas: HTMLCanvasElement | null, state: 'default' | 'pointer' | 'grab') => void;
281
- interface TooltipConfig {
282
- /** Custom renderer for tooltips (React, Vue, etc.) */
283
- renderer?: TooltipRenderer;
284
- /** Custom cursor handler */
285
- cursorHandler?: CursorHandler;
286
- }
287
- //#endregion
288
- //#region textures/PickBuffer.d.ts
289
- /**
290
- * Manages GPU picking buffer for mouse interaction
291
- * Separate from simulation buffers as it has different lifecycle
292
- */
293
- declare class PickBuffer {
294
- private renderer;
295
- private pickTarget;
296
- constructor(renderer: THREE.WebGLRenderer);
297
- /**
298
- * Ensure pick buffer matches viewport size
299
- */
300
- resize(width: number, height: number): void;
301
- private createPickBuffer;
302
- /**
303
- * Read node ID at pixel coordinates
304
- */
305
- readIdAt(x: number, y: number): number;
306
- /**
307
- * Render scene to pick buffer
308
- */
309
- render(scene: THREE.Scene, camera: THREE.Camera): void;
310
- getTarget(): THREE.WebGLRenderTarget | null;
311
- dispose(): void;
312
- }
313
- //#endregion
314
- //#region textures/SimulationBuffers.d.ts
315
- /**
316
- * Manages dynamic render targets updated by force simulation
317
- * Uses ping-pong technique for GPU computation
318
- * Buffers are created lazily when data is initialized
319
- */
320
- declare class SimulationBuffers {
321
- private renderer;
322
- private textureSize;
323
- private positionBuffers;
324
- private velocityBuffers;
325
- private isInitialized;
326
- constructor(renderer: THREE.WebGLRenderer);
327
- /**
328
- * Check if buffers are initialized
329
- */
330
- isReady(): boolean;
331
- /**
332
- * Initialize buffers with point count and initial positions
333
- */
334
- init(pointsCount: number, initialPositions?: Float32Array): void;
335
- /**
336
- * Resize buffers (re-initializes with new size)
337
- */
338
- resize(pointsCount: number, preserveData?: boolean): void;
339
- private calculateTextureSize;
340
- private createDynamicBuffer;
341
- /**
342
- * Initialize position buffers from initial data
343
- */
344
- setInitialPositions(positionArray: Float32Array): void;
345
- /**
346
- * Update current and previous positions, but keep original positions intact
347
- */
348
- updateCurrentPositions(positionArray: Float32Array): void;
349
- /**
350
- * Set original positions (anchors) separately from current positions
351
- */
352
- setOriginalPositions(positionArray: Float32Array): void;
353
- /**
354
- * Initialize velocity buffers (usually to zero)
355
- */
356
- initVelocities(): void;
357
- /**
358
- * Swap position buffers (ping-pong)
359
- */
360
- swapPositions(): void;
361
- /**
362
- * Swap velocity buffers (ping-pong)
363
- */
364
- swapVelocities(): void;
365
- /**
366
- * Reset positions to original state
367
- */
368
- resetPositions(): void;
369
- /**
370
- * Read current positions back from GPU (expensive operation)
371
- * Returns RGBA float array (x, y, z, state)
372
- */
373
- readPositions(): Float32Array;
374
- getCurrentPositionTarget(): THREE.WebGLRenderTarget | null;
375
- getPreviousPositionTarget(): THREE.WebGLRenderTarget | null;
376
- getCurrentPositionTexture(): THREE.Texture<unknown>;
377
- getPreviousPositionTexture(): THREE.Texture | null;
378
- getOriginalPositionTexture(): THREE.Texture | null;
379
- getCurrentVelocityTarget(): THREE.WebGLRenderTarget | null;
380
- getPreviousVelocityTarget(): THREE.WebGLRenderTarget | null;
381
- getCurrentVelocityTexture(): THREE.Texture | null;
382
- getPreviousVelocityTexture(): THREE.Texture | null;
383
- getTextureSize(): number;
384
- private arrayToTextureData;
385
- private createDataTexture;
386
- private copyTextureToBuffer;
387
- private copyBufferToBuffer;
388
- dispose(): void;
389
- }
390
- //#endregion
391
- //#region rendering/links/LinksRenderer.d.ts
392
- /**
393
- * LinksRenderer - Renders links as line segments
394
- * Uses shared SimulationBuffers for node positions
395
- * Manages link-specific opacity and highlighting
396
- */
397
- declare class LinksRenderer {
398
- private scene;
399
- private renderer;
400
- private lines;
401
- private links;
402
- private nodeIndexMap;
403
- private linkIndexMap;
404
- private interpolationSteps;
405
- params: {
406
- noiseStrength: number;
407
- defaultAlpha: number;
408
- highlightAlpha: number;
409
- dimmedAlpha: number;
410
- is2D: boolean;
411
- };
412
- private linkOpacity;
413
- private simulationBuffers;
414
- constructor(scene: THREE.Scene, renderer: THREE.WebGLRenderer);
415
- /**
416
- * Create link geometry and materials
417
- * Receives shared buffers as dependencies
418
- */
419
- create(links: GraphLink[], nodes: GraphNode[], simulationBuffers: SimulationBuffers): void;
420
- /**
421
- * Update position texture from simulation
422
- * This is the SHARED texture used by both nodes and links
423
- */
424
- setPositionTexture(positionTexture: THREE.Texture): void;
425
- /**
426
- * Update shader uniforms (called each frame)
427
- */
428
- update(time: number): void;
429
- /**
430
- * Update link opacity (called every frame)
431
- */
432
- updateOpacity(): void;
433
- /**
434
- * Highlight links connected to a specific node
435
- */
436
- highlightConnectedLinks(nodeId: string, step?: number): void;
437
- /**
438
- * Highlight links connected to any of the given nodes
439
- */
440
- highlightConnectedToNodes(nodeIds: Set<string>, step?: number): void;
441
- /**
442
- * Clear all highlights (return to defaultAlpha)
443
- */
444
- clearHighlights(step?: number): void;
445
- /**
446
- * Update noise strength parameter
447
- */
448
- setNoiseStrength(strength: number): void;
449
- /**
450
- * Update alpha parameters
451
- */
452
- setAlphaParams(params: {
453
- defaultAlpha?: number;
454
- highlightAlpha?: number;
455
- dimmedAlpha?: number;
456
- }): void;
457
- /**
458
- * Unified configuration method
459
- */
460
- setOptions(options: LinkOptions): void;
461
- /**
462
- * Refresh shader uniforms when params change
463
- */
464
- refreshUniforms(): void;
465
- /**
466
- * Handle window resize
467
- */
468
- resize(width: number, height: number): void;
469
- /**
470
- * Set visibility of links
471
- */
472
- setVisible(visible: boolean): void;
473
- /**
474
- * Check if links are visible
475
- */
476
- isVisible(): boolean;
477
- /**
478
- * Cleanup
479
- */
480
- dispose(): void;
481
- /**
482
- * Build node index mapping
483
- */
484
- private buildNodeMapping;
485
- /**
486
- * Builds the instanced link geometry and per-link attribute buffers used by the renderer.
487
- *
488
- * This method:
489
- * - Creates a line-segment template with interpolation parameter `t` for each vertex pair.
490
- * - Encodes link endpoints as texture-space coordinates (`instanceLinkA` / `instanceLinkB`)
491
- * so shaders can fetch node positions from a node texture.
492
- * - Derives endpoint colors from source/target node categories.
493
- * - Assigns a stable per-instance alpha lookup index.
494
- * - Computes a category-based visibility rank from the **target node category**.
495
- *
496
- * Rank/alpha behavior:
497
- * - Categories are ranked by `groupOrder` (unknown categories are appended).
498
- * - The rank is converted to an attenuation factor with inverted weighting:
499
- * `instanceRank = 1.0 - 0.75 * (rank / maxRank)`.
500
- * - This means rank `0` keeps full weight (`1.0`), while the highest rank trends to `0.25`.
501
- *
502
- * Also returns a `linkIndexMap` keyed as `"sourceId-targetId"` for quick instance lookup.
503
- *
504
- * @param links - Graph links to encode as geometry instances.
505
- * @param nodes - Graph nodes used for category/color lookup.
506
- * @param nodeTextureSize - Width/height of the square node data texture used for index-to-UV conversion.
507
- * @param groupOrder - Preferred category ordering for rank assignment (earlier = stronger visibility).
508
- * @returns An object containing:
509
- * - `geometry`: the populated `THREE.InstancedBufferGeometry`
510
- * - `linkIndexMap`: map from link id (`"sourceId-targetId"`) to instance index
511
- */
512
- private createLinkGeometry;
513
- /**
514
- * Build all link-related textures for simulation
515
- * - linkIndicesData: child node INDEX per link entry (organized by parent)
516
- * - linkPropertiesData: strength/distance per link entry
517
- * - nodeLinkMapData: per-node metadata (startX, startY, count, hasLinks)
518
- */
519
- private buildLinkTextures;
520
- /**
521
- * Create render material with all uniforms
522
- */
523
- private createRenderMaterial;
524
- }
525
- interface LinkOptions {
526
- visible?: boolean;
527
- noiseStrength?: number;
528
- alpha?: {
529
- default?: number;
530
- highlight?: number;
531
- dimmed?: number;
532
- };
533
- }
534
- //#endregion
535
- //#region rendering/nodes/NodesRenderer.d.ts
536
- declare class NodesRenderer {
537
- private scene;
538
- private renderer;
539
- private points;
540
- private pickMaterial;
541
- private nodeIndexMap;
542
- private idArray;
543
- private nodeOpacity;
544
- private targets;
545
- params: {
546
- defaultAlpha: number;
547
- highlightAlpha: number;
548
- dimmedAlpha: number;
549
- };
550
- private simulationBuffers;
551
- private pickBuffer;
552
- constructor(scene: THREE.Scene, renderer: THREE.WebGLRenderer);
553
- create(nodes: GraphNode[], simulationBuffers: SimulationBuffers, pickBuffer: PickBuffer): void;
554
- setPositionTexture(positionTexture: THREE.Texture): void;
555
- pick(pixelX: number, pixelY: number, camera: THREE.Camera): number;
556
- highlight(nodeIds: string[], step?: number): void;
557
- clearHighlights(step?: number): void;
558
- /**
559
- * Update node opacity (called every frame)
560
- */
561
- updateOpacity(): void;
562
- resize(width: number, height: number): void;
563
- dispose(): void;
564
- private buildNodeMapping;
565
- /**
566
- * Create all node data in one pass
567
- * Returns: colors, sizes, radii, nodeIds, pointIndices, alphaIndex
568
- */
569
- private createNodeData;
570
- private createGeometry;
571
- private createRenderMaterial;
572
- private createPickMaterial;
573
- }
574
- //#endregion
575
- //#region rendering/GraphScene.d.ts
576
- /**
577
- * GraphScene - Manages the 3D scene, camera, and renderers
578
- * Responsibilities:
579
- * - Scene setup and lifecycle
580
- * - Node and link rendering
581
- * - Camera control
582
- * - Tooltip management
583
- * - Mode application (visual changes)
584
- */
585
- declare class GraphScene {
586
- readonly scene: THREE.Scene;
587
- readonly renderer: THREE.WebGLRenderer;
588
- readonly camera: CameraController;
589
- private nodeRenderer;
590
- private clock;
591
- private linkRenderer;
592
- private postProcessing;
593
- private antialiasingMode;
594
- constructor(canvas: HTMLCanvasElement, cameraConfig?: CameraConfig, antialiasing?: AntialiasingMode);
595
- /**
596
- * Initialize scene with nodes and links
597
- */
598
- create(nodes: GraphNode[], links: GraphLink[], simulationBuffers: SimulationBuffers, pickBuffer: PickBuffer, groupOrder?: string[]): void;
599
- /**
600
- * Apply visual mode (colors, sizes, camera position)
601
- */
602
- applyMode(mode: string, options?: {
603
- transitionDuration?: number;
604
- cameraTransitionDuration?: number;
605
- }): void;
606
- /**
607
- * Update position textures from simulation
608
- */
609
- updatePositions(positionTexture: THREE.Texture): void;
610
- /**
611
- * Update time-based uniforms (called each frame with elapsed time)
612
- */
613
- update(elapsedTime: number): void;
614
- /**
615
- * GPU picking at canvas coordinates
616
- */
617
- pick(pixelX: number, pixelY: number): number;
618
- /**
619
- * Render the scene
620
- */
621
- render(): void;
622
- /**
623
- * Handle window resize
624
- */
625
- resize(width: number, height: number): void;
626
- /**
627
- * Cleanup all resources
628
- */
629
- dispose(): void;
630
- /**
631
- * Switch antialiasing mode at runtime.
632
- * Cannot switch to 'msaa' at runtime (requires renderer recreation).
633
- * For 'smaa', 'fxaa', or 'none': creates or updates the post-processing pipeline.
634
- */
635
- setAntialiasing(mode: AntialiasingMode): void;
636
- private applyDefaultMode;
637
- getCamera(): CameraController;
638
- getNodeRenderer(): NodesRenderer | null;
639
- getLinkRenderer(): LinksRenderer | null;
640
- }
641
- //#endregion
642
- //#region types/iAttractor.d.ts
643
- /**
644
- * Simple 3D vector type
645
- */
646
- interface Vec3 {
647
- x: number;
648
- y: number;
649
- z: number;
650
- }
651
- /**
652
- * Attractor - A point in space that attracts nodes of specific groups
653
- */
654
- interface Attractor {
655
- /** Unique identifier */
656
- id: string;
657
- /** Position in world space */
658
- position: Vec3;
659
- /** Radius of attraction (default: 0.0) - nodes within this radius are not pulled further */
660
- radius?: number;
661
- /** Groups of nodes attracted to this attractor (empty = attracts all) */
662
- groups: string[];
663
- /** Strength of attraction (default: 1.0) */
664
- strength?: number;
665
- }
666
- /**
667
- * Resolved attractor with defaults applied
668
- */
669
- interface ResolvedAttractor {
670
- id: string;
671
- position: Vec3;
672
- groups: string[];
673
- strength: number;
674
- radius: number;
675
- }
676
- //#endregion
677
- //#region textures/StaticAssets.d.ts
678
- /**
679
- * Manages read-only GPU textures created at initialization
680
- * These never change during simulation (except for mode changes)
681
- *
682
- * Node data: radii, colors
683
- * Link data: source/target indices, properties
684
- */
685
- declare class StaticAssets {
686
- private nodeRadiiTexture;
687
- private nodeColorsTexture;
688
- private linkIndicesTexture;
689
- private linkPropertiesTexture;
690
- private nodeLinkMapTexture;
691
- private nodeTextureSize;
692
- private linkTextureSize;
693
- constructor();
694
- /**
695
- * Set/update node radii texture
696
- */
697
- setNodeRadii(radii: Float32Array, textureSize: number): void;
698
- /**
699
- * Set/update node colors texture
700
- */
701
- setNodeColors(colors: Float32Array, textureSize: number): void;
702
- /**
703
- * Set link indices (source/target pairs)
704
- * Format: [sourceX, sourceY, targetX, targetY] per link
705
- */
706
- setLinkIndices(linkIndices: Float32Array, textureSize: number): void;
707
- /**
708
- * Set link properties (strength, distance, etc.)
709
- */
710
- setLinkProperties(linkProperties: Float32Array, textureSize: number): void;
711
- setNodeLinkMap(linkMap: Float32Array, textureSize: number): void;
712
- /**
713
- * Create a data texture with proper settings for GPU compute
714
- */
715
- private createTexture;
716
- getNodeRadiiTexture(): THREE.DataTexture | null;
717
- getNodeColorsTexture(): THREE.DataTexture | null;
718
- getLinkIndicesTexture(): THREE.DataTexture | null;
719
- getLinkPropertiesTexture(): THREE.DataTexture | null;
720
- getLinkMapTexture(): THREE.DataTexture | null;
721
- getNodeTextureSize(): number;
722
- getLinkTextureSize(): number;
723
- /**
724
- * Check if assets are ready
725
- */
726
- hasNodeAssets(): boolean;
727
- hasLinkAssets(): boolean;
728
- /**
729
- * Cleanup
730
- */
731
- dispose(): void;
732
- }
733
- declare const staticAssets: StaticAssets;
734
- //#endregion
735
- //#region simulation/BasePass.d.ts
736
- interface PassContext {
737
- scene: THREE.Scene;
738
- camera: THREE.Camera;
739
- quad: THREE.BufferGeometry;
740
- simBuffers: SimulationBuffers;
741
- assets: StaticAssets;
742
- renderer: THREE.WebGLRenderer;
743
- config: ForceConfig;
744
- textureSize: number;
745
- }
746
- /**
747
- * Base class for GPU force simulation passes
748
- * Each pass operates on simulation buffers and can read from static assets
749
- */
750
- declare abstract class BasePass {
751
- protected material: THREE.ShaderMaterial | null;
752
- protected enabled: boolean;
753
- /**
754
- * Get the name/identifier for this pass
755
- */
756
- abstract getName(): string;
757
- /**
758
- * Initialize the shader material for this pass
759
- */
760
- abstract initMaterial(context: PassContext): void;
761
- /**
762
- * Update uniforms before executing the pass
763
- */
764
- abstract updateUniforms(context: PassContext): void;
765
- /**
766
- * Execute the pass (renders to current velocity target)
767
- */
768
- execute(context: PassContext): void;
769
- /**
770
- * Render the compute shader
771
- */
772
- protected render(context: PassContext): void;
773
- /**
774
- * Create a shader material helper
775
- */
776
- protected createMaterial(vertexShader: string, fragmentShader: string, uniforms: {
777
- [uniform: string]: THREE.IUniform;
778
- }): THREE.ShaderMaterial;
779
- /**
780
- * Safe uniform setter - avoids TypeScript strict null check issues
781
- */
782
- protected setUniform(name: string, value: unknown): void;
783
- /**
784
- * Enable or disable this pass
785
- */
786
- setEnabled(enabled: boolean): void;
787
- /**
788
- * Check if pass is enabled
789
- */
790
- isEnabled(): boolean;
791
- /**
792
- * Get the material for external access
793
- */
794
- getMaterial(): THREE.ShaderMaterial | null;
795
- /**
796
- * Cleanup resources
797
- */
798
- dispose(): void;
799
- }
800
- //#endregion
801
- //#region simulation/passes/AttractorPass.d.ts
802
- /**
803
- * Attractor force pass - attracts nodes to attractor points based on group membership
804
- *
805
- * Usage:
806
- * attractorPass.setAttractors([
807
- * { id: 'center', position: { x: 0, y: 0, z: 0 }, categories: ['root'] }, // categories acts as groups
808
- * { id: 'left', position: { x: -100, y: 0, z: 0 }, categories: ['artwork', 'series'] }
809
- * ])
810
- */
811
- declare class AttractorPass extends BasePass {
812
- private attractors;
813
- private groupMap;
814
- private attractorsTexture;
815
- private attractorGroupsTexture;
816
- private attractorParamsTexture;
817
- private nodeGroupsTexture;
818
- getName(): string;
819
- initMaterial(context: PassContext): void;
820
- updateUniforms(context: PassContext): void;
821
- /**
822
- * Set attractors for the simulation
823
- */
824
- setAttractors(attractors: Attractor[]): void;
825
- /**
826
- * Add a single attractor
827
- */
828
- addAttractor(attractor: Attractor): void;
829
- /**
830
- * Remove an attractor by ID
831
- */
832
- removeAttractor(id: string): void;
833
- /**
834
- * Update an existing attractor's position
835
- */
836
- updateAttractorPosition(id: string, position: Vec3): void;
837
- /**
838
- * Get current attractors
839
- */
840
- getAttractors(): ResolvedAttractor[];
841
- /**
842
- * Set node groups from graph data
843
- * Call this when graph data changes or grouping criteria changes
844
- */
845
- setNodeGroups(groups: string[][], textureSize: number): void;
846
- /**
847
- * Get the group map (group name -> index)
848
- */
849
- getGroupMap(): Map<string, number>;
850
- private createAttractorTextures;
851
- private updateAttractorTextures;
852
- dispose(): void;
853
- }
854
- //#endregion
855
- //#region simulation/ForceSimulation.d.ts
856
- /**
857
- * ForceSimulation - GPU-based force simulation
858
- *
859
- * Simple architecture:
860
- * - Single shared config object (ForceConfig)
861
- * - All passes read directly from config via PassContext
862
- * - Enable flags control which passes execute
863
- * - No manual syncing required
864
- */
865
- declare class ForceSimulation {
866
- private renderer;
867
- private simulationBuffers;
868
- private computeScene;
869
- private computeCamera;
870
- private computeQuad;
871
- private velocityCarryPass;
872
- private collisionPass;
873
- private manyBodyPass;
874
- private gravityPass;
875
- private linkPass;
876
- private elasticPass;
877
- private attractorPass;
878
- private dragPass;
879
- private integratePass;
880
- private forcePasses;
881
- readonly config: ForceConfig;
882
- private isInitialized;
883
- private iterationCount;
884
- private readonly FIXED_DT;
885
- private readonly MAX_STEPS_PER_FRAME;
886
- private timeAccumulator;
887
- constructor(renderer: THREE.WebGLRenderer);
888
- private createComputeQuad;
889
- /**
890
- * Initialize simulation with buffers
891
- */
892
- initialize(simulationBuffers: SimulationBuffers): void;
893
- private createContext;
894
- /**
895
- * Check if a pass should execute based on config
896
- */
897
- private shouldExecutePass;
898
- /**
899
- * Run simulation steps using a fixed timestep accumulator.
900
- * Regardless of monitor refresh rate, physics always steps at 1/60s intervals.
901
- */
902
- step(deltaTime?: number): void;
903
- /**
904
- * Execute one fixed-rate physics step (always at 1/60s)
905
- */
906
- private fixedStep;
907
- /**
908
- * Get config for GUI binding
909
- * Modify this object directly - changes take effect on next step()
910
- */
911
- getConfig(): ForceConfig;
912
- /**
913
- * Re-heat the simulation (set alpha to 1)
914
- */
915
- reheat(amt?: number): void;
916
- startDrag(index: number, targetWorldPos: THREE.Vector3): void;
917
- updateDrag(targetWorldPos: THREE.Vector3): void;
918
- endDrag(): void;
919
- /**
920
- * Set attractors for category-based attraction
921
- * @param attractors Array of attractor definitions
922
- */
923
- setAttractors(attractors: Attractor[]): void;
924
- /**
925
- * Add a single attractor
926
- */
927
- addAttractor(attractor: Attractor): void;
928
- /**
929
- * Remove an attractor by ID
930
- */
931
- removeAttractor(id: string): void;
932
- /**
933
- * Update an attractor's position (useful for animated attractors)
934
- */
935
- updateAttractorPosition(id: string, position: Vec3): void;
936
- /**
937
- * Get current attractors
938
- */
939
- getAttractors(): Attractor[];
940
- /**
941
- * Set node logic for attractor matching
942
- * Call this when graph data changes
943
- */
944
- setNodeGroups(groups: (string | string[])[]): void;
945
- setNodeGroupsFromData<T>(data: T[], accessor: (item: T, index: number) => string | string[] | undefined): void;
946
- /**
947
- * Get the attractor pass for direct access
948
- */
949
- getAttractorPass(): AttractorPass;
950
- getAlpha(): number;
951
- getIterationCount(): number;
952
- reset(): void;
953
- dispose(): void;
954
- }
955
- //#endregion
956
- //#region ui/TooltipManager.d.ts
957
- declare class TooltipManager {
958
- private container;
959
- private canvas;
960
- private mainTooltip;
961
- private previewTooltip;
962
- private chainTooltips;
963
- private config;
964
- private closeButton;
965
- private onCloseCallback?;
966
- constructor(container: HTMLElement, canvas: HTMLCanvasElement, config?: TooltipConfig);
967
- /**
968
- * Show grab cursor when hovering over a node
969
- */
970
- showGrabIcon(x: number, y: number, progress: number): void;
971
- hideGrabIcon(): void;
972
- /**
973
- * Show preview tooltip (triggered by pop event when hover reaches 1.0)
974
- */
975
- showPreview(node: GraphNode, x: number, y: number): void;
976
- hidePreview(): void;
977
- /**
978
- * Show full tooltip (triggered by click)
979
- */
980
- showFull(node: GraphNode, x: number, y: number): void;
981
- hideFull(): void;
982
- /**
983
- * Set callback for when tooltip is closed
984
- */
985
- setOnCloseCallback(callback: () => void): void;
986
- /**
987
- * Add close button to tooltip
988
- */
989
- private addCloseButton;
990
- /**
991
- * Remove close button from tooltip
992
- */
993
- private removeCloseButton;
994
- /**
995
- * Hide all tooltips
996
- */
997
- hideAll(): void;
998
- showMainTooltip(content: string, x: number, y: number): void;
999
- hideMainTooltip(): void;
1000
- showChainTooltip(nodeId: string, content: string, x: number, y: number): void;
1001
- hideChainTooltips(): void;
1002
- updateMainTooltipPos(x: number, y: number): void;
1003
- /**
1004
- * Set main tooltip visibility (doesn't affect open state or content)
1005
- */
1006
- setMainTooltipVisibility(visible: boolean): void;
1007
- dispose(): void;
1008
- }
1009
- //#endregion
1010
- //#region core/EventEmitter.d.ts
1011
- declare class EventEmitter {
1012
- private listeners;
1013
- protected listenerCount(event: string): number;
1014
- on(event: string, listener: Function): () => void;
1015
- off(event: string, listener: Function): void;
1016
- emit(event: string, ...args: any[]): void;
1017
- }
1018
- //#endregion
1019
- //#region controls/handlers/ClickHandler.d.ts
1020
- declare class ClickHandler extends EventEmitter {
1021
- private getNodeByIndex;
1022
- constructor(getNodeByIndex: (index: number) => GraphNode | null);
1023
- private handleClick;
1024
- dispose(): void;
1025
- }
1026
- //#endregion
1027
- //#region controls/handlers/DragHandler.d.ts
1028
- declare class DragHandler extends EventEmitter {
1029
- private getNodeByIndex;
1030
- private cameraController?;
1031
- private forceSimulation?;
1032
- private viewport?;
1033
- private isDragging;
1034
- private raycaster;
1035
- private dragPlane;
1036
- private pointer;
1037
- constructor(getNodeByIndex: (index: number) => GraphNode | null, cameraController?: CameraController, forceSimulation?: ForceSimulation, viewport?: {
1038
- width: number;
1039
- height: number;
1040
- });
1041
- /**
1042
- * Set up drag plane perpendicular to camera, passing through a world point
1043
- */
1044
- private setupDragPlane;
1045
- private handleDragStart;
1046
- private handleDrag;
1047
- private handleDragEnd;
1048
- /**
1049
- * Convert screen coordinates to world position on drag plane
1050
- */
1051
- private screenToWorld;
1052
- /**
1053
- * Update viewport dimensions on resize
1054
- */
1055
- resize(width: number, height: number): void;
1056
- dispose(): void;
1057
- }
1058
- //#endregion
1059
- //#region controls/handlers/HoverHandler.d.ts
1060
- declare class HoverHandler extends EventEmitter {
1061
- private getNodeByIndex;
1062
- constructor(getNodeByIndex: (index: number) => GraphNode | null);
1063
- private handleHoverStart;
1064
- private handleHover;
1065
- private handlePop;
1066
- private handleHoverEnd;
1067
- dispose(): void;
1068
- }
1069
- //#endregion
1070
- //#region controls/InputProcessor.d.ts
1071
- /**
1072
- * Manages pointer/mouse input and emits interaction events
1073
- * Uses GPU picking for efficient node detection
1074
- */
1075
- declare class InputProcessor extends EventEmitter {
1076
- private pickFn;
1077
- private canvas;
1078
- private viewport;
1079
- private readonly CLICK_THRESHOLD;
1080
- private readonly HOVER_TO_POP_MS;
1081
- private pointer;
1082
- private canvasPointer;
1083
- private isPointerDown;
1084
- private isDragging;
1085
- private mouseDownTime;
1086
- private draggedIndex;
1087
- private currentHoverIndex;
1088
- private hoverStartTime;
1089
- private hoverProgress;
1090
- private hasPopped;
1091
- private isTouch;
1092
- private readonly TOUCH_MOVE_THRESHOLD;
1093
- private pointerDownX;
1094
- private pointerDownY;
1095
- private lastClientX;
1096
- private lastClientY;
1097
- constructor(pickFn: (x: number, y: number) => number, // Injected
1098
- canvas: HTMLCanvasElement, viewport: {
1099
- width: number;
1100
- height: number;
1101
- });
1102
- private setupEventListeners;
1103
- private handlePointerMove;
1104
- private handlePointerDown;
1105
- private handlePointerUp;
1106
- private handlePointerLeave;
1107
- private updateHover;
1108
- /**
1109
- * Update hover state even when pointer is stationary
1110
- * Called from render loop
1111
- */
1112
- update(): void;
1113
- private updatePointer;
1114
- /**
1115
- * Update viewport dimensions on resize
1116
- */
1117
- resize(width: number, height: number): void;
1118
- dispose(): void;
1119
- }
1120
- //#endregion
1121
- //#region controls/InteractionManager.d.ts
1122
- declare class InteractionManager {
1123
- private graphScene?;
1124
- private getConnectedNodeIds?;
1125
- private pointerInput;
1126
- private hoverHandler;
1127
- private clickHandler;
1128
- private dragHandler;
1129
- tooltipManager: TooltipManager;
1130
- private isDragging;
1131
- isTooltipSticky: boolean;
1132
- stickyNodeId: string | null;
1133
- searchHighlightIds: string[];
1134
- constructor(pickFunction: (x: number, y: number) => number, canvas: HTMLCanvasElement, viewport: {
1135
- width: number;
1136
- height: number;
1137
- }, getNodeByIndex: (index: number) => GraphNode | null, cameraController?: CameraController, forceSimulation?: ForceSimulation, tooltipConfig?: TooltipConfig, graphScene?: GraphScene, getConnectedNodeIds?: (nodeId: string) => string[]);
1138
- private wireEvents;
1139
- private wireTooltipEvents;
1140
- /**
1141
- * Wire visual feedback events (opacity, highlighting)
1142
- * Centralized control of visual responses to interactions
1143
- */
1144
- private wireVisualFeedbackEvents;
1145
- getPointerInput(): InputProcessor;
1146
- getHoverHandler(): HoverHandler;
1147
- getClickHandler(): ClickHandler;
1148
- getDragHandler(): DragHandler;
1149
- getTooltipManager(): TooltipManager;
1150
- isTooltipStickyOpen(): boolean;
1151
- /**
1152
- * Update viewport dimensions on resize
1153
- */
1154
- resize(width: number, height: number): void;
1155
- cleanup(): void;
1156
- dispose(): void;
1157
- }
1158
- //#endregion
1159
- //#region core/GraphStore.d.ts
1160
- /**
1161
- * GraphStore - Central data management
1162
- * Responsibilities:
1163
- * - Store raw graph data (nodes, links)
1164
- * - Node/Link CRUD operations
1165
- * - ID mapping and lookups
1166
- * - Data validation
1167
- * - Change notifications
1168
- */
1169
- declare class GraphStore {
1170
- private nodes;
1171
- private links;
1172
- private nodeArray;
1173
- private linkArray;
1174
- private nodeIdToIndex;
1175
- private linkIdToIndex;
1176
- private nodeToLinks;
1177
- constructor();
1178
- /**
1179
- * Set graph data (replaces all)
1180
- */
1181
- setData(data: GraphData): void;
1182
- /**
1183
- * Add nodes
1184
- */
1185
- addNodes(nodes: GraphNode[]): void;
1186
- /**
1187
- * Remove nodes (and connected links)
1188
- */
1189
- removeNodes(nodeIds: string[]): void;
1190
- /**
1191
- * Add links
1192
- */
1193
- addLinks(links: GraphLink[]): void;
1194
- /**
1195
- * Remove links
1196
- */
1197
- removeLinks(linkIds: string[]): void;
1198
- /**
1199
- * Get all nodes as array
1200
- */
1201
- getNodes(): GraphNode[];
1202
- /**
1203
- * Get all links as array
1204
- */
1205
- getLinks(): GraphLink[];
1206
- /**
1207
- * Get connected node IDs for a given node
1208
- */
1209
- getConnectedNodeIds(nodeId: string): string[];
1210
- /**
1211
- * Get node by ID
1212
- */
1213
- getNodeById(id: string): GraphNode | null;
1214
- /**
1215
- * Get node by index
1216
- */
1217
- getNodeByIndex(index: number): GraphNode | null;
1218
- /**
1219
- * Get node index
1220
- */
1221
- getNodeIndex(id: string): number;
1222
- /**
1223
- * Get link by ID
1224
- */
1225
- getLinkById(id: string): GraphLink | null;
1226
- /**
1227
- * Get links connected to node
1228
- */
1229
- getNodeLinks(nodeId: string): GraphLink[];
1230
- /**
1231
- * Get node count
1232
- */
1233
- getNodeCount(): number;
1234
- /**
1235
- * Get link count
1236
- */
1237
- getLinkCount(): number;
1238
- /**
1239
- * Clear all data
1240
- */
1241
- clear(): void;
1242
- private getLinkId;
1243
- private addLinkConnectivity;
1244
- private removeLinkConnectivity;
1245
- private rebuildNodeArrays;
1246
- private rebuildLinkArrays;
1247
- }
1248
- //#endregion
1249
- //#region core/Engine.d.ts
1250
- interface EngineOptions {
1251
- width?: number;
1252
- height?: number;
1253
- backgroundColor?: string;
1254
- tooltipConfig?: TooltipConfig;
1255
- groupOrder?: string[];
1256
- antialiasing?: AntialiasingMode;
1257
- }
1258
- /**
1259
- * Engine - Main orchestrator
1260
- * Responsibilities:
1261
- * - Owns all shared buffers (StaticAssets, SimulationBuffers, PickBuffer)
1262
- * - Coordinates GraphStore, GraphScene, ForceSimulation
1263
- * - Manages render loop
1264
- * - Handles user interaction
1265
- */
1266
- declare class Engine {
1267
- readonly canvas: HTMLCanvasElement;
1268
- readonly graphStore: GraphStore;
1269
- private graphScene;
1270
- private forceSimulation;
1271
- interactionManager: InteractionManager;
1272
- private clock;
1273
- private simulationBuffers;
1274
- private pickBuffer;
1275
- private animationFrameId;
1276
- private isRunning;
1277
- private boundResizeHandler;
1278
- private groupOrder?;
1279
- private smoothedTooltipPos;
1280
- constructor(canvas: HTMLCanvasElement, options?: EngineOptions);
1281
- /**
1282
- * Handle window resize event
1283
- */
1284
- private handleWindowResize;
1285
- /**
1286
- * Set graph data
1287
- */
1288
- setData(data: GraphData): void;
1289
- /**
1290
- * Update node states based on a callback
1291
- * This allows changing visibility/behavior without resetting the simulation
1292
- */
1293
- updateNodeStates(callback: (node: GraphNode) => NodeState): void;
1294
- /**
1295
- * Set target positions for elastic force (tree layout, etc.)
1296
- * Writes positions into the "original positions" GPU buffer that ElasticPass reads from,
1297
- * without touching current positions or node states.
1298
- * Must be called AFTER applyPreset() since updateNodeStates() overwrites original positions.
1299
- */
1300
- setTargetPositions(targets: Map<string, {
1301
- x: number;
1302
- y: number;
1303
- z: number;
1304
- }>): void;
1305
- /**
1306
- * Reheat the simulation
1307
- */
1308
- reheat(alpha?: number): void;
1309
- /**
1310
- * Set alpha decay
1311
- */
1312
- setAlphaDecay(decay: number): void;
1313
- /**
1314
- * Get current alpha
1315
- */
1316
- getAlpha(): number;
1317
- /**
1318
- Apply a preset to the graph
1319
- */
1320
- applyPreset(preset: GraphPreset): void;
1321
- /**
1322
- *
1323
- * Start render loop
1324
- */
1325
- start(): void;
1326
- /**
1327
- * Stop render loop
1328
- */
1329
- stop(): void;
1330
- /**
1331
- * Render loop
1332
- */
1333
- private animate;
1334
- /**
1335
- * GPU pick node at canvas coordinates
1336
- */
1337
- pickNode(x: number, y: number): string | null;
1338
- /**
1339
- * Get node by ID
1340
- */
1341
- getNodeById(id: string): GraphNode | null;
1342
- /**
1343
- * Highlight nodes
1344
- */
1345
- highlightNodes(nodeIds: string[]): void;
1346
- /**
1347
- * Clear highlights
1348
- */
1349
- clearHighlights(): void;
1350
- /**
1351
- * Get node position in 3D space
1352
- */
1353
- getNodePosition(nodeId: string): THREE.Vector3 | null;
1354
- /**
1355
- * Get node screen position from world position
1356
- * Returns position and visibility info (whether node is on screen and in front of camera)
1357
- */
1358
- getNodeScreenPosition(nodeId: string): {
1359
- x: number;
1360
- y: number;
1361
- visible: boolean;
1362
- } | null;
1363
- /**
1364
- * Update sticky tooltip position to follow node during camera movement
1365
- * Uses lerp smoothing to filter out micro-jitter from force simulation
1366
- */
1367
- private updateStickyTooltipPosition;
1368
- /**
1369
- * Programmatically select a node (highlight + tooltip)
1370
- */
1371
- selectNode(nodeId: string): void;
1372
- /**
1373
- * Resize canvas and all dependent components
1374
- */
1375
- resize(width: number, height: number): void;
1376
- /**
1377
- * Get the unified clock for timing information
1378
- */
1379
- getClock(): Clock;
1380
- /**
1381
- * Get all nodes
1382
- */
1383
- get nodes(): GraphNode[];
1384
- /**
1385
- * Get all links
1386
- */
1387
- get links(): GraphLink[];
1388
- /**
1389
- * Get force simulation for external configuration (GUI binding)
1390
- */
1391
- get simulation(): ForceSimulation;
1392
- /**
1393
- * Get camera controller for external configuration
1394
- */
1395
- get camera(): CameraController;
1396
- /**
1397
- * Set camera mode (Orbit, Map, Fly)
1398
- */
1399
- setCameraMode(mode: CameraMode): void;
1400
- /**
1401
- * Set antialiasing mode at runtime.
1402
- * Supports switching between 'smaa', 'fxaa', and 'none'.
1403
- * Cannot switch to 'msaa' at runtime (requires renderer recreation).
1404
- */
1405
- setAntialiasing(mode: AntialiasingMode): void;
1406
- /**
1407
- * Animate camera to look at a specific target from a specific position
1408
- */
1409
- setCameraLookAt(position: {
1410
- x: number;
1411
- y: number;
1412
- z: number;
1413
- }, target: {
1414
- x: number;
1415
- y: number;
1416
- z: number;
1417
- }, transitionDuration?: number): Promise<void>;
1418
- /**
1419
- * Focus camera on a specific target node
1420
- */
1421
- setCameraFocus(target: {
1422
- x: number;
1423
- y: number;
1424
- z: number;
1425
- }, distance: number, transitionDuration?: number): Promise<void>;
1426
- /**
1427
- * Cleanup
1428
- */
1429
- dispose(): void;
1430
- private calculateTextureSize;
1431
- }
1432
- //#endregion
1433
- //#region core/StyleRegistry.d.ts
1434
- /** Color input - can be THREE.Color, hex number, or CSS color string */
1435
- type ColorInput = THREE.Color | number | string;
1436
- /**
1437
- * Visual properties for a node category (input)
1438
- */
1439
- interface NodeStyle {
1440
- color: ColorInput;
1441
- size: number;
1442
- }
1443
- /**
1444
- * Visual properties for a link category (input)
1445
- */
1446
- interface LinkStyle {
1447
- color: ColorInput;
1448
- }
1449
- /**
1450
- * Resolved node style with THREE.Color
1451
- */
1452
- interface ResolvedNodeStyle {
1453
- color: THREE.Color;
1454
- size: number;
1455
- }
1456
- /**
1457
- * Resolved link style with THREE.Color
1458
- */
1459
- interface ResolvedLinkStyle {
1460
- color: THREE.Color;
1461
- }
1462
- /**
1463
- * StyleRegistry - Manages visual styles for node and link categories
1464
- *
1465
- * Usage:
1466
- * styleRegistry.setNodeStyle('person', { color: 0xff0000, size: 20 })
1467
- * styleRegistry.setLinkStyle('friendship', { color: '#00ff00', width: 2 })
1468
- *
1469
- * const style = styleRegistry.getNodeStyle('person')
1470
- */
1471
- declare class StyleRegistry {
1472
- private nodeStyles;
1473
- private linkStyles;
1474
- private defaultNodeStyle;
1475
- private defaultLinkStyle;
1476
- /**
1477
- * Convert color input to THREE.Color
1478
- */
1479
- private toColor;
1480
- /**
1481
- * Set the default style for nodes without a category
1482
- */
1483
- setDefaultNodeStyle(style: Partial<NodeStyle>): void;
1484
- /**
1485
- * Set the default style for links without a category
1486
- */
1487
- setDefaultLinkStyle(style: Partial<LinkStyle>): void;
1488
- /**
1489
- * Register a style for a node category
1490
- */
1491
- setNodeStyle(category: string, style: NodeStyle): void;
1492
- /**
1493
- * Register multiple node styles at once
1494
- */
1495
- setNodeStyles(styles: Record<string, NodeStyle>): void;
1496
- /**
1497
- * Register a style for a link category
1498
- */
1499
- setLinkStyle(category: string, style: LinkStyle): void;
1500
- /**
1501
- * Register multiple link styles at once
1502
- */
1503
- setLinkStyles(styles: Record<string, LinkStyle>): void;
1504
- /**
1505
- * Get the resolved style for a node category
1506
- */
1507
- getNodeStyle(category?: string): ResolvedNodeStyle;
1508
- /**
1509
- * Get the resolved style for a link category
1510
- */
1511
- getLinkStyle(category?: string): ResolvedLinkStyle;
1512
- /**
1513
- * Check if a node category exists
1514
- */
1515
- hasNodeStyle(category: string): boolean;
1516
- /**
1517
- * Check if a link category exists
1518
- */
1519
- hasLinkStyle(category: string): boolean;
1520
- /**
1521
- * Remove a node style
1522
- */
1523
- removeNodeStyle(category: string): void;
1524
- /**
1525
- * Remove a link style
1526
- */
1527
- removeLinkStyle(category: string): void;
1528
- /**
1529
- * Clear all styles
1530
- */
1531
- clear(): void;
1532
- /**
1533
- * Get all registered node categories
1534
- */
1535
- getNodeCategories(): string[];
1536
- /**
1537
- * Get all registered link categories
1538
- */
1539
- getLinkCategories(): string[];
1540
- }
1541
- declare const styleRegistry: StyleRegistry;
1542
- //#endregion
1543
- //#region types/iEngineConfig.d.ts
1544
- interface EngineConfig {
1545
- container: HTMLElement;
1546
- width?: number;
1547
- height?: number;
1548
- antialias?: boolean;
1549
- alpha?: boolean;
1550
- }
1551
- //#endregion
1
+ import CameraControls from "camera-controls";
2
+ import * as THREE from "three";
3
+
4
+ //#region core/Clock.d.ts
5
+ /**
6
+ * Clock - Unified timing for the force graph package
7
+ */
8
+ declare class Clock {
9
+ private previousTime;
10
+ private elapsedTime;
11
+ private deltaTime;
12
+ private isRunning;
13
+ private maxDeltaTime;
14
+ constructor();
15
+ /**
16
+ * Start the clock
17
+ */
18
+ start(): void;
19
+ /**
20
+ * Stop the clock
21
+ */
22
+ stop(): void;
23
+ /**
24
+ * Update the clock - call once per frame
25
+ * @returns delta time in seconds
26
+ */
27
+ update(): number;
28
+ /**
29
+ * Get delta time in seconds
30
+ */
31
+ getDeltaTime(): number;
32
+ /**
33
+ * Get total elapsed time in seconds
34
+ */
35
+ getElapsedTime(): number;
36
+ /**
37
+ * Check if clock is running
38
+ */
39
+ getIsRunning(): boolean;
40
+ }
41
+ //#endregion
42
+ //#region types/iCameraMode.d.ts
43
+ declare enum CameraMode {
44
+ Orbit = "orbit",
45
+ Map = "map",
46
+ }
47
+ //#endregion
48
+ //#region rendering/CameraController.d.ts
49
+ interface CameraConfig {
50
+ fov?: number;
51
+ aspect?: number;
52
+ near?: number;
53
+ far?: number;
54
+ position?: THREE.Vector3;
55
+ target?: THREE.Vector3;
56
+ minDistance?: number;
57
+ maxDistance?: number;
58
+ }
59
+ interface ControlsConfig {
60
+ smoothTime?: number;
61
+ dollyToCursor?: boolean;
62
+ infinityDolly?: boolean;
63
+ enableZoom?: boolean;
64
+ enableRotation?: boolean;
65
+ enablePan?: boolean;
66
+ minDistance?: number;
67
+ maxDistance?: number;
68
+ maxPolarAngle?: number;
69
+ minPolarAngle?: number;
70
+ minAzimuthAngle?: number;
71
+ maxAzimuthAngle?: number;
72
+ }
73
+ declare class CameraController {
74
+ camera: THREE.PerspectiveCamera;
75
+ controls: CameraControls;
76
+ private sceneBounds;
77
+ private domElement;
78
+ private autorotateEnabled;
79
+ private autorotateSpeed;
80
+ private userIsActive;
81
+ constructor(domelement: HTMLElement, config?: CameraConfig);
82
+ private handleWheel;
83
+ private setupDefaultControls;
84
+ /**
85
+ * Set camera control mode
86
+ */
87
+ setMode(mode: CameraMode): void;
88
+ /**
89
+ * Set camera boundary
90
+ */
91
+ setBoundary(box: THREE.Box3): void;
92
+ /**
93
+ * Update camera controls (should be called in render loop)
94
+ * Only autorotate if enabled and user is inactive
95
+ */
96
+ update(delta: number): boolean;
97
+ /**
98
+ * Set autorotate enabled/disabled
99
+ */
100
+ setAutorotate(enabled: boolean, speed?: number): void;
101
+ /**
102
+ * Set user activity state
103
+ */
104
+ setUserIsActive(isActive: boolean): void;
105
+ /**
106
+ * Configure camera controls
107
+ */
108
+ configureControls(config: ControlsConfig): void;
109
+ /**
110
+ * Resize camera when window resizes
111
+ */
112
+ resize(width: number, height: number): void;
113
+ /**
114
+ * Animate camera to look at a specific target from a specific position
115
+ */
116
+ setLookAt(position: THREE.Vector3, target: THREE.Vector3, enableTransition?: boolean): Promise<void>;
117
+ /**
118
+ * Reset camera to default position
119
+ */
120
+ reset(position?: THREE.Vector3, target?: THREE.Vector3, enableTransition?: boolean): Promise<void>;
121
+ /**
122
+ * Enable/disable controls
123
+ */
124
+ setEnabled(enabled: boolean): void;
125
+ /**
126
+ * Get current camera target (look-at point)
127
+ */
128
+ getTarget(out?: THREE.Vector3): THREE.Vector3;
129
+ /**
130
+ * Dispose camera manager and clean up
131
+ */
132
+ dispose(): void;
133
+ /**
134
+ * Clear camera bounds (remove boundary restrictions)
135
+ */
136
+ clearBounds(): void;
137
+ /**
138
+ * Get current scene bounds
139
+ */
140
+ getSceneBounds(): THREE.Box3 | null;
141
+ /**
142
+ * Update scene bounds used by the camera manager.
143
+ * Stores the bounds for future use (e.g. constraining controls).
144
+ */
145
+ updateBounds(box: THREE.Box3): void;
146
+ /**
147
+ * Unified configuration method
148
+ */
149
+ setOptions(options: {
150
+ controls?: ControlsConfig;
151
+ autoRotate?: boolean;
152
+ autoRotateSpeed?: number;
153
+ }): void;
154
+ }
155
+ //#endregion
156
+ //#region rendering/PostProcessing.d.ts
157
+ type AntialiasingMode = 'msaa' | 'smaa' | 'fxaa' | 'none';
158
+ //#endregion
159
+ //#region types/iGraphLink.d.ts
160
+ interface GraphLink {
161
+ source: string;
162
+ target: string;
163
+ }
164
+ //#endregion
165
+ //#region types/iGraphNode.d.ts
166
+ interface GraphNode {
167
+ id: string;
168
+ label?: string;
169
+ description?: string;
170
+ thumbnailUrl?: string;
171
+ category?: string;
172
+ x?: number;
173
+ y?: number;
174
+ z?: number;
175
+ fx?: number;
176
+ fy?: number;
177
+ fz?: number;
178
+ state?: NodeState;
179
+ metadata?: any;
180
+ }
181
+ declare enum NodeState {
182
+ Hidden = 0,
183
+ // = 0 not rendered
184
+ Passive = 1,
185
+ // = 1 rendered, not influencing simulation,
186
+ Fixed = 2,
187
+ // = 2 rendered, influencing simulation, but not moving
188
+ Active = 3,
189
+ }
190
+ //#endregion
191
+ //#region types/iGraphData.d.ts
192
+ interface GraphData {
193
+ nodes: GraphNode[];
194
+ links: GraphLink[];
195
+ metadata?: any;
196
+ }
197
+ //#endregion
198
+ //#region types/iForceConfig.d.ts
199
+ interface ForceConfig {
200
+ collisionStrength: number;
201
+ collisionRadius: number;
202
+ collisionMaxDistance: number;
203
+ enableCollision: boolean;
204
+ manyBodyStrength: number;
205
+ manyBodyMinDistance: number;
206
+ manyBodyMaxDistance: number;
207
+ enableManyBody: boolean;
208
+ springStrength: number;
209
+ springLength: number;
210
+ springDamping: number;
211
+ maxLinks: number;
212
+ enableLinks: boolean;
213
+ gravity: number;
214
+ enableGravity: boolean;
215
+ attractorStrength: number;
216
+ enableAttractors: boolean;
217
+ elasticStrength: number;
218
+ enableElastic: boolean;
219
+ dragStrength: number;
220
+ damping: number;
221
+ alpha: number;
222
+ alphaDecay: number;
223
+ deltaTime: number;
224
+ spaceSize: number;
225
+ maxVelocity: number;
226
+ is3D: boolean;
227
+ }
228
+ //#endregion
229
+ //#region types/iGraphPreset.d.ts
230
+ interface GraphPreset {
231
+ name: string;
232
+ force?: Partial<ForceConfig>;
233
+ camera?: {
234
+ mode?: CameraMode;
235
+ position?: {
236
+ x: number;
237
+ y: number;
238
+ z: number;
239
+ };
240
+ target?: {
241
+ x: number;
242
+ y: number;
243
+ z: number;
244
+ };
245
+ zoom?: number;
246
+ transitionDuration?: number;
247
+ minDistance?: number;
248
+ maxDistance?: number;
249
+ boundary?: {
250
+ min: {
251
+ x: number;
252
+ y: number;
253
+ z: number;
254
+ };
255
+ max: {
256
+ x: number;
257
+ y: number;
258
+ z: number;
259
+ };
260
+ } | null;
261
+ };
262
+ nodes?: {
263
+ state?: (node: GraphNode) => NodeState;
264
+ };
265
+ links?: {
266
+ opacity?: number;
267
+ noiseStrength?: number;
268
+ };
269
+ }
270
+ //#endregion
271
+ //#region ui/Tooltips.d.ts
272
+ /**
273
+ * Renderer function type for custom tooltip rendering
274
+ * Can mount React, Vue, or any other framework component
275
+ */
276
+ type TooltipRenderer = (container: HTMLElement, node: GraphNode, type: 'preview' | 'full', x: number, y: number, onPositionUpdate?: (callback: (x: number, y: number) => void) => void) => void | (() => void);
277
+ /**
278
+ * Cursor handler for custom cursor behavior
279
+ */
280
+ type CursorHandler = (canvas: HTMLCanvasElement | null, state: 'default' | 'pointer' | 'grab') => void;
281
+ interface TooltipConfig {
282
+ /** Custom renderer for tooltips (React, Vue, etc.) */
283
+ renderer?: TooltipRenderer;
284
+ /** Custom cursor handler */
285
+ cursorHandler?: CursorHandler;
286
+ }
287
+ //#endregion
288
+ //#region textures/PickBuffer.d.ts
289
+ /**
290
+ * Manages GPU picking buffer for mouse interaction
291
+ * Separate from simulation buffers as it has different lifecycle
292
+ */
293
+ declare class PickBuffer {
294
+ private renderer;
295
+ private pickTarget;
296
+ constructor(renderer: THREE.WebGLRenderer);
297
+ /**
298
+ * Ensure pick buffer matches viewport size
299
+ */
300
+ resize(width: number, height: number): void;
301
+ private createPickBuffer;
302
+ /**
303
+ * Read node ID at pixel coordinates
304
+ */
305
+ readIdAt(x: number, y: number): number;
306
+ /**
307
+ * Render scene to pick buffer
308
+ */
309
+ render(scene: THREE.Scene, camera: THREE.Camera): void;
310
+ getTarget(): THREE.WebGLRenderTarget | null;
311
+ dispose(): void;
312
+ }
313
+ //#endregion
314
+ //#region textures/SimulationBuffers.d.ts
315
+ /**
316
+ * Manages dynamic render targets updated by force simulation
317
+ * Uses ping-pong technique for GPU computation
318
+ * Buffers are created lazily when data is initialized
319
+ */
320
+ declare class SimulationBuffers {
321
+ private renderer;
322
+ private textureSize;
323
+ private positionBuffers;
324
+ private velocityBuffers;
325
+ private isInitialized;
326
+ constructor(renderer: THREE.WebGLRenderer);
327
+ /**
328
+ * Check if buffers are initialized
329
+ */
330
+ isReady(): boolean;
331
+ /**
332
+ * Initialize buffers with point count and initial positions
333
+ */
334
+ init(pointsCount: number, initialPositions?: Float32Array): void;
335
+ /**
336
+ * Resize buffers (re-initializes with new size)
337
+ */
338
+ resize(pointsCount: number, preserveData?: boolean): void;
339
+ private calculateTextureSize;
340
+ private createDynamicBuffer;
341
+ /**
342
+ * Initialize position buffers from initial data
343
+ */
344
+ setInitialPositions(positionArray: Float32Array): void;
345
+ /**
346
+ * Update current and previous positions, but keep original positions intact
347
+ */
348
+ updateCurrentPositions(positionArray: Float32Array): void;
349
+ /**
350
+ * Set original positions (anchors) separately from current positions
351
+ */
352
+ setOriginalPositions(positionArray: Float32Array): void;
353
+ /**
354
+ * Initialize velocity buffers (usually to zero)
355
+ */
356
+ initVelocities(): void;
357
+ /**
358
+ * Swap position buffers (ping-pong)
359
+ */
360
+ swapPositions(): void;
361
+ /**
362
+ * Swap velocity buffers (ping-pong)
363
+ */
364
+ swapVelocities(): void;
365
+ /**
366
+ * Reset positions to original state
367
+ */
368
+ resetPositions(): void;
369
+ /**
370
+ * Read current positions back from GPU (expensive operation)
371
+ * Returns RGBA float array (x, y, z, state)
372
+ */
373
+ readPositions(): Float32Array;
374
+ getCurrentPositionTarget(): THREE.WebGLRenderTarget | null;
375
+ getPreviousPositionTarget(): THREE.WebGLRenderTarget | null;
376
+ getCurrentPositionTexture(): THREE.Texture<unknown>;
377
+ getPreviousPositionTexture(): THREE.Texture | null;
378
+ getOriginalPositionTexture(): THREE.Texture | null;
379
+ getCurrentVelocityTarget(): THREE.WebGLRenderTarget | null;
380
+ getPreviousVelocityTarget(): THREE.WebGLRenderTarget | null;
381
+ getCurrentVelocityTexture(): THREE.Texture | null;
382
+ getPreviousVelocityTexture(): THREE.Texture | null;
383
+ getTextureSize(): number;
384
+ private arrayToTextureData;
385
+ private createDataTexture;
386
+ private copyTextureToBuffer;
387
+ private copyBufferToBuffer;
388
+ dispose(): void;
389
+ }
390
+ //#endregion
391
+ //#region rendering/links/LinksRenderer.d.ts
392
+ /**
393
+ * LinksRenderer - Renders links as line segments
394
+ * Uses shared SimulationBuffers for node positions
395
+ * Manages link-specific opacity and highlighting
396
+ */
397
+ declare class LinksRenderer {
398
+ private scene;
399
+ private renderer;
400
+ private lines;
401
+ private links;
402
+ private nodeIndexMap;
403
+ private linkIndexMap;
404
+ private interpolationSteps;
405
+ params: {
406
+ noiseStrength: number;
407
+ defaultAlpha: number;
408
+ highlightAlpha: number;
409
+ dimmedAlpha: number;
410
+ is2D: boolean;
411
+ };
412
+ private linkOpacity;
413
+ private simulationBuffers;
414
+ constructor(scene: THREE.Scene, renderer: THREE.WebGLRenderer);
415
+ /**
416
+ * Create link geometry and materials
417
+ * Receives shared buffers as dependencies
418
+ */
419
+ create(links: GraphLink[], nodes: GraphNode[], simulationBuffers: SimulationBuffers): void;
420
+ /**
421
+ * Update position texture from simulation
422
+ * This is the SHARED texture used by both nodes and links
423
+ */
424
+ setPositionTexture(positionTexture: THREE.Texture): void;
425
+ /**
426
+ * Update shader uniforms (called each frame)
427
+ */
428
+ update(time: number): void;
429
+ /**
430
+ * Update link opacity (called every frame)
431
+ */
432
+ updateOpacity(): void;
433
+ /**
434
+ * Highlight links connected to a specific node
435
+ */
436
+ highlightConnectedLinks(nodeId: string, step?: number): void;
437
+ /**
438
+ * Highlight links connected to any of the given nodes
439
+ */
440
+ highlightConnectedToNodes(nodeIds: Set<string>, step?: number): void;
441
+ /**
442
+ * Clear all highlights (return to defaultAlpha)
443
+ */
444
+ clearHighlights(step?: number): void;
445
+ /**
446
+ * Update noise strength parameter
447
+ */
448
+ setNoiseStrength(strength: number): void;
449
+ /**
450
+ * Update alpha parameters
451
+ */
452
+ setAlphaParams(params: {
453
+ defaultAlpha?: number;
454
+ highlightAlpha?: number;
455
+ dimmedAlpha?: number;
456
+ }): void;
457
+ /**
458
+ * Unified configuration method
459
+ */
460
+ setOptions(options: LinkOptions): void;
461
+ /**
462
+ * Refresh shader uniforms when params change
463
+ */
464
+ refreshUniforms(): void;
465
+ /**
466
+ * Handle window resize
467
+ */
468
+ resize(width: number, height: number): void;
469
+ /**
470
+ * Set visibility of links
471
+ */
472
+ setVisible(visible: boolean): void;
473
+ /**
474
+ * Check if links are visible
475
+ */
476
+ isVisible(): boolean;
477
+ /**
478
+ * Cleanup
479
+ */
480
+ dispose(): void;
481
+ /**
482
+ * Build node index mapping
483
+ */
484
+ private buildNodeMapping;
485
+ /**
486
+ * Builds the instanced link geometry and per-link attribute buffers used by the renderer.
487
+ *
488
+ * This method:
489
+ * - Creates a line-segment template with interpolation parameter `t` for each vertex pair.
490
+ * - Encodes link endpoints as texture-space coordinates (`instanceLinkA` / `instanceLinkB`)
491
+ * so shaders can fetch node positions from a node texture.
492
+ * - Derives endpoint colors from source/target node categories.
493
+ * - Assigns a stable per-instance alpha lookup index.
494
+ * - Computes a category-based visibility rank from the **target node category**.
495
+ *
496
+ * Rank/alpha behavior:
497
+ * - Categories are ranked by `groupOrder` (unknown categories are appended).
498
+ * - The rank is converted to an attenuation factor with inverted weighting:
499
+ * `instanceRank = 1.0 - 0.75 * (rank / maxRank)`.
500
+ * - This means rank `0` keeps full weight (`1.0`), while the highest rank trends to `0.25`.
501
+ *
502
+ * Also returns a `linkIndexMap` keyed as `"sourceId-targetId"` for quick instance lookup.
503
+ *
504
+ * @param links - Graph links to encode as geometry instances.
505
+ * @param nodes - Graph nodes used for category/color lookup.
506
+ * @param nodeTextureSize - Width/height of the square node data texture used for index-to-UV conversion.
507
+ * @param groupOrder - Preferred category ordering for rank assignment (earlier = stronger visibility).
508
+ * @returns An object containing:
509
+ * - `geometry`: the populated `THREE.InstancedBufferGeometry`
510
+ * - `linkIndexMap`: map from link id (`"sourceId-targetId"`) to instance index
511
+ */
512
+ private createLinkGeometry;
513
+ /**
514
+ * Build all link-related textures for simulation
515
+ * - linkIndicesData: child node INDEX per link entry (organized by parent)
516
+ * - linkPropertiesData: strength/distance per link entry
517
+ * - nodeLinkMapData: per-node metadata (startX, startY, count, hasLinks)
518
+ */
519
+ private buildLinkTextures;
520
+ /**
521
+ * Create render material with all uniforms
522
+ */
523
+ private createRenderMaterial;
524
+ }
525
+ interface LinkOptions {
526
+ visible?: boolean;
527
+ noiseStrength?: number;
528
+ alpha?: {
529
+ default?: number;
530
+ highlight?: number;
531
+ dimmed?: number;
532
+ };
533
+ }
534
+ //#endregion
535
+ //#region rendering/nodes/NodesRenderer.d.ts
536
+ declare class NodesRenderer {
537
+ private scene;
538
+ private renderer;
539
+ private points;
540
+ private pickMaterial;
541
+ private nodeIndexMap;
542
+ private idArray;
543
+ private nodeOpacity;
544
+ private targets;
545
+ params: {
546
+ defaultAlpha: number;
547
+ highlightAlpha: number;
548
+ dimmedAlpha: number;
549
+ };
550
+ private simulationBuffers;
551
+ private pickBuffer;
552
+ constructor(scene: THREE.Scene, renderer: THREE.WebGLRenderer);
553
+ create(nodes: GraphNode[], simulationBuffers: SimulationBuffers, pickBuffer: PickBuffer): void;
554
+ setPositionTexture(positionTexture: THREE.Texture): void;
555
+ pick(pixelX: number, pixelY: number, camera: THREE.Camera): number;
556
+ highlight(nodeIds: string[], step?: number): void;
557
+ clearHighlights(step?: number): void;
558
+ /**
559
+ * Update node opacity (called every frame)
560
+ */
561
+ updateOpacity(): void;
562
+ resize(width: number, height: number): void;
563
+ dispose(): void;
564
+ private buildNodeMapping;
565
+ /**
566
+ * Create all node data in one pass
567
+ * Returns: colors, sizes, radii, nodeIds, pointIndices, alphaIndex
568
+ */
569
+ private createNodeData;
570
+ private createGeometry;
571
+ private createRenderMaterial;
572
+ private createPickMaterial;
573
+ }
574
+ //#endregion
575
+ //#region rendering/GraphScene.d.ts
576
+ /**
577
+ * GraphScene - Manages the 3D scene, camera, and renderers
578
+ * Responsibilities:
579
+ * - Scene setup and lifecycle
580
+ * - Node and link rendering
581
+ * - Camera control
582
+ * - Tooltip management
583
+ * - Mode application (visual changes)
584
+ */
585
+ declare class GraphScene {
586
+ readonly scene: THREE.Scene;
587
+ readonly renderer: THREE.WebGLRenderer;
588
+ readonly camera: CameraController;
589
+ private nodeRenderer;
590
+ private clock;
591
+ private linkRenderer;
592
+ private postProcessing;
593
+ private antialiasingMode;
594
+ constructor(canvas: HTMLCanvasElement, cameraConfig?: CameraConfig, antialiasing?: AntialiasingMode);
595
+ /**
596
+ * Initialize scene with nodes and links
597
+ */
598
+ create(nodes: GraphNode[], links: GraphLink[], simulationBuffers: SimulationBuffers, pickBuffer: PickBuffer, groupOrder?: string[]): void;
599
+ /**
600
+ * Apply visual mode (colors, sizes, camera position)
601
+ */
602
+ applyMode(mode: string, options?: {
603
+ transitionDuration?: number;
604
+ cameraTransitionDuration?: number;
605
+ }): void;
606
+ /**
607
+ * Update position textures from simulation
608
+ */
609
+ updatePositions(positionTexture: THREE.Texture): void;
610
+ /**
611
+ * Update time-based uniforms (called each frame with elapsed time)
612
+ */
613
+ update(elapsedTime: number): void;
614
+ /**
615
+ * GPU picking at canvas coordinates
616
+ */
617
+ pick(pixelX: number, pixelY: number): number;
618
+ /**
619
+ * Render the scene
620
+ */
621
+ render(): void;
622
+ /**
623
+ * Handle window resize
624
+ */
625
+ resize(width: number, height: number): void;
626
+ /**
627
+ * Cleanup all resources
628
+ */
629
+ dispose(): void;
630
+ /**
631
+ * Switch antialiasing mode at runtime.
632
+ * Cannot switch to 'msaa' at runtime (requires renderer recreation).
633
+ * For 'smaa', 'fxaa', or 'none': creates or updates the post-processing pipeline.
634
+ */
635
+ setAntialiasing(mode: AntialiasingMode): void;
636
+ private applyDefaultMode;
637
+ getCamera(): CameraController;
638
+ getNodeRenderer(): NodesRenderer | null;
639
+ getLinkRenderer(): LinksRenderer | null;
640
+ }
641
+ //#endregion
642
+ //#region types/iAttractor.d.ts
643
+ /**
644
+ * Simple 3D vector type
645
+ */
646
+ interface Vec3 {
647
+ x: number;
648
+ y: number;
649
+ z: number;
650
+ }
651
+ /**
652
+ * Attractor - A point in space that attracts nodes of specific groups
653
+ */
654
+ interface Attractor {
655
+ /** Unique identifier */
656
+ id: string;
657
+ /** Position in world space */
658
+ position: Vec3;
659
+ /** Radius of attraction (default: 0.0) - nodes within this radius are not pulled further */
660
+ radius?: number;
661
+ /** Groups of nodes attracted to this attractor (empty = attracts all) */
662
+ groups: string[];
663
+ /** Strength of attraction (default: 1.0) */
664
+ strength?: number;
665
+ }
666
+ /**
667
+ * Resolved attractor with defaults applied
668
+ */
669
+ interface ResolvedAttractor {
670
+ id: string;
671
+ position: Vec3;
672
+ groups: string[];
673
+ strength: number;
674
+ radius: number;
675
+ }
676
+ //#endregion
677
+ //#region textures/StaticAssets.d.ts
678
+ /**
679
+ * Manages read-only GPU textures created at initialization
680
+ * These never change during simulation (except for mode changes)
681
+ *
682
+ * Node data: radii, colors
683
+ * Link data: source/target indices, properties
684
+ */
685
+ declare class StaticAssets {
686
+ private nodeRadiiTexture;
687
+ private nodeColorsTexture;
688
+ private linkIndicesTexture;
689
+ private linkPropertiesTexture;
690
+ private nodeLinkMapTexture;
691
+ private nodeTextureSize;
692
+ private linkTextureSize;
693
+ constructor();
694
+ /**
695
+ * Set/update node radii texture
696
+ */
697
+ setNodeRadii(radii: Float32Array, textureSize: number): void;
698
+ /**
699
+ * Set/update node colors texture
700
+ */
701
+ setNodeColors(colors: Float32Array, textureSize: number): void;
702
+ /**
703
+ * Set link indices (source/target pairs)
704
+ * Format: [sourceX, sourceY, targetX, targetY] per link
705
+ */
706
+ setLinkIndices(linkIndices: Float32Array, textureSize: number): void;
707
+ /**
708
+ * Set link properties (strength, distance, etc.)
709
+ */
710
+ setLinkProperties(linkProperties: Float32Array, textureSize: number): void;
711
+ setNodeLinkMap(linkMap: Float32Array, textureSize: number): void;
712
+ /**
713
+ * Create a data texture with proper settings for GPU compute
714
+ */
715
+ private createTexture;
716
+ getNodeRadiiTexture(): THREE.DataTexture | null;
717
+ getNodeColorsTexture(): THREE.DataTexture | null;
718
+ getLinkIndicesTexture(): THREE.DataTexture | null;
719
+ getLinkPropertiesTexture(): THREE.DataTexture | null;
720
+ getLinkMapTexture(): THREE.DataTexture | null;
721
+ getNodeTextureSize(): number;
722
+ getLinkTextureSize(): number;
723
+ /**
724
+ * Check if assets are ready
725
+ */
726
+ hasNodeAssets(): boolean;
727
+ hasLinkAssets(): boolean;
728
+ /**
729
+ * Cleanup
730
+ */
731
+ dispose(): void;
732
+ }
733
+ declare const staticAssets: StaticAssets;
734
+ //#endregion
735
+ //#region simulation/BasePass.d.ts
736
+ interface PassContext {
737
+ scene: THREE.Scene;
738
+ camera: THREE.Camera;
739
+ quad: THREE.BufferGeometry;
740
+ simBuffers: SimulationBuffers;
741
+ assets: StaticAssets;
742
+ renderer: THREE.WebGLRenderer;
743
+ config: ForceConfig;
744
+ textureSize: number;
745
+ }
746
+ /**
747
+ * Base class for GPU force simulation passes
748
+ * Each pass operates on simulation buffers and can read from static assets
749
+ */
750
+ declare abstract class BasePass {
751
+ protected material: THREE.ShaderMaterial | null;
752
+ protected enabled: boolean;
753
+ /**
754
+ * Get the name/identifier for this pass
755
+ */
756
+ abstract getName(): string;
757
+ /**
758
+ * Initialize the shader material for this pass
759
+ */
760
+ abstract initMaterial(context: PassContext): void;
761
+ /**
762
+ * Update uniforms before executing the pass
763
+ */
764
+ abstract updateUniforms(context: PassContext): void;
765
+ /**
766
+ * Execute the pass (renders to current velocity target)
767
+ */
768
+ execute(context: PassContext): void;
769
+ /**
770
+ * Render the compute shader
771
+ */
772
+ protected render(context: PassContext): void;
773
+ /**
774
+ * Create a shader material helper
775
+ */
776
+ protected createMaterial(vertexShader: string, fragmentShader: string, uniforms: {
777
+ [uniform: string]: THREE.IUniform;
778
+ }): THREE.ShaderMaterial;
779
+ /**
780
+ * Safe uniform setter - avoids TypeScript strict null check issues
781
+ */
782
+ protected setUniform(name: string, value: unknown): void;
783
+ /**
784
+ * Enable or disable this pass
785
+ */
786
+ setEnabled(enabled: boolean): void;
787
+ /**
788
+ * Check if pass is enabled
789
+ */
790
+ isEnabled(): boolean;
791
+ /**
792
+ * Get the material for external access
793
+ */
794
+ getMaterial(): THREE.ShaderMaterial | null;
795
+ /**
796
+ * Cleanup resources
797
+ */
798
+ dispose(): void;
799
+ }
800
+ //#endregion
801
+ //#region simulation/passes/AttractorPass.d.ts
802
+ /**
803
+ * Attractor force pass - attracts nodes to attractor points based on group membership
804
+ *
805
+ * Usage:
806
+ * attractorPass.setAttractors([
807
+ * { id: 'center', position: { x: 0, y: 0, z: 0 }, categories: ['root'] }, // categories acts as groups
808
+ * { id: 'left', position: { x: -100, y: 0, z: 0 }, categories: ['artwork', 'series'] }
809
+ * ])
810
+ */
811
+ declare class AttractorPass extends BasePass {
812
+ private attractors;
813
+ private groupMap;
814
+ private attractorsTexture;
815
+ private attractorGroupsTexture;
816
+ private attractorParamsTexture;
817
+ private nodeGroupsTexture;
818
+ getName(): string;
819
+ initMaterial(context: PassContext): void;
820
+ updateUniforms(context: PassContext): void;
821
+ /**
822
+ * Set attractors for the simulation
823
+ */
824
+ setAttractors(attractors: Attractor[]): void;
825
+ /**
826
+ * Add a single attractor
827
+ */
828
+ addAttractor(attractor: Attractor): void;
829
+ /**
830
+ * Remove an attractor by ID
831
+ */
832
+ removeAttractor(id: string): void;
833
+ /**
834
+ * Update an existing attractor's position
835
+ */
836
+ updateAttractorPosition(id: string, position: Vec3): void;
837
+ /**
838
+ * Get current attractors
839
+ */
840
+ getAttractors(): ResolvedAttractor[];
841
+ /**
842
+ * Set node groups from graph data
843
+ * Call this when graph data changes or grouping criteria changes
844
+ */
845
+ setNodeGroups(groups: string[][], textureSize: number): void;
846
+ /**
847
+ * Get the group map (group name -> index)
848
+ */
849
+ getGroupMap(): Map<string, number>;
850
+ private createAttractorTextures;
851
+ private updateAttractorTextures;
852
+ dispose(): void;
853
+ }
854
+ //#endregion
855
+ //#region simulation/ForceSimulation.d.ts
856
+ /**
857
+ * ForceSimulation - GPU-based force simulation
858
+ *
859
+ * Simple architecture:
860
+ * - Single shared config object (ForceConfig)
861
+ * - All passes read directly from config via PassContext
862
+ * - Enable flags control which passes execute
863
+ * - No manual syncing required
864
+ */
865
+ declare class ForceSimulation {
866
+ private renderer;
867
+ private simulationBuffers;
868
+ private computeScene;
869
+ private computeCamera;
870
+ private computeQuad;
871
+ private velocityCarryPass;
872
+ private collisionPass;
873
+ private manyBodyPass;
874
+ private gravityPass;
875
+ private linkPass;
876
+ private elasticPass;
877
+ private attractorPass;
878
+ private dragPass;
879
+ private integratePass;
880
+ private forcePasses;
881
+ readonly config: ForceConfig;
882
+ private isInitialized;
883
+ private iterationCount;
884
+ private readonly FIXED_DT;
885
+ private readonly MAX_STEPS_PER_FRAME;
886
+ private timeAccumulator;
887
+ constructor(renderer: THREE.WebGLRenderer);
888
+ private createComputeQuad;
889
+ /**
890
+ * Initialize simulation with buffers
891
+ */
892
+ initialize(simulationBuffers: SimulationBuffers): void;
893
+ private createContext;
894
+ /**
895
+ * Check if a pass should execute based on config
896
+ */
897
+ private shouldExecutePass;
898
+ /**
899
+ * Run simulation steps using a fixed timestep accumulator.
900
+ * Regardless of monitor refresh rate, physics always steps at 1/60s intervals.
901
+ */
902
+ step(deltaTime?: number): void;
903
+ /**
904
+ * Execute one fixed-rate physics step (always at 1/60s)
905
+ */
906
+ private fixedStep;
907
+ /**
908
+ * Get config for GUI binding
909
+ * Modify this object directly - changes take effect on next step()
910
+ */
911
+ getConfig(): ForceConfig;
912
+ /**
913
+ * Re-heat the simulation (set alpha to 1)
914
+ */
915
+ reheat(amt?: number): void;
916
+ startDrag(index: number, targetWorldPos: THREE.Vector3): void;
917
+ updateDrag(targetWorldPos: THREE.Vector3): void;
918
+ endDrag(): void;
919
+ /**
920
+ * Set attractors for category-based attraction
921
+ * @param attractors Array of attractor definitions
922
+ */
923
+ setAttractors(attractors: Attractor[]): void;
924
+ /**
925
+ * Add a single attractor
926
+ */
927
+ addAttractor(attractor: Attractor): void;
928
+ /**
929
+ * Remove an attractor by ID
930
+ */
931
+ removeAttractor(id: string): void;
932
+ /**
933
+ * Update an attractor's position (useful for animated attractors)
934
+ */
935
+ updateAttractorPosition(id: string, position: Vec3): void;
936
+ /**
937
+ * Get current attractors
938
+ */
939
+ getAttractors(): Attractor[];
940
+ /**
941
+ * Set node logic for attractor matching
942
+ * Call this when graph data changes
943
+ */
944
+ setNodeGroups(groups: (string | string[])[]): void;
945
+ setNodeGroupsFromData<T>(data: T[], accessor: (item: T, index: number) => string | string[] | undefined): void;
946
+ /**
947
+ * Get the attractor pass for direct access
948
+ */
949
+ getAttractorPass(): AttractorPass;
950
+ getAlpha(): number;
951
+ getIterationCount(): number;
952
+ reset(): void;
953
+ dispose(): void;
954
+ }
955
+ //#endregion
956
+ //#region ui/TooltipManager.d.ts
957
+ declare class TooltipManager {
958
+ private container;
959
+ private canvas;
960
+ private mainTooltip;
961
+ private previewTooltip;
962
+ private chainTooltips;
963
+ private config;
964
+ private closeButton;
965
+ private onCloseCallback?;
966
+ constructor(container: HTMLElement, canvas: HTMLCanvasElement, config?: TooltipConfig);
967
+ /**
968
+ * Show grab cursor when hovering over a node
969
+ */
970
+ showGrabIcon(x: number, y: number, progress: number): void;
971
+ hideGrabIcon(): void;
972
+ /**
973
+ * Show preview tooltip (triggered by pop event when hover reaches 1.0)
974
+ */
975
+ showPreview(node: GraphNode, x: number, y: number): void;
976
+ hidePreview(): void;
977
+ /**
978
+ * Show full tooltip (triggered by click)
979
+ */
980
+ showFull(node: GraphNode, x: number, y: number): void;
981
+ hideFull(): void;
982
+ /**
983
+ * Set callback for when tooltip is closed
984
+ */
985
+ setOnCloseCallback(callback: () => void): void;
986
+ /**
987
+ * Add close button to tooltip
988
+ */
989
+ private addCloseButton;
990
+ /**
991
+ * Remove close button from tooltip
992
+ */
993
+ private removeCloseButton;
994
+ /**
995
+ * Hide all tooltips
996
+ */
997
+ hideAll(): void;
998
+ showMainTooltip(content: string, x: number, y: number): void;
999
+ hideMainTooltip(): void;
1000
+ showChainTooltip(nodeId: string, content: string, x: number, y: number): void;
1001
+ hideChainTooltips(): void;
1002
+ updateMainTooltipPos(x: number, y: number): void;
1003
+ /**
1004
+ * Set main tooltip visibility (doesn't affect open state or content)
1005
+ */
1006
+ setMainTooltipVisibility(visible: boolean): void;
1007
+ dispose(): void;
1008
+ }
1009
+ //#endregion
1010
+ //#region core/EventEmitter.d.ts
1011
+ declare class EventEmitter {
1012
+ private listeners;
1013
+ protected listenerCount(event: string): number;
1014
+ on(event: string, listener: Function): () => void;
1015
+ off(event: string, listener: Function): void;
1016
+ emit(event: string, ...args: any[]): void;
1017
+ }
1018
+ //#endregion
1019
+ //#region controls/handlers/ClickHandler.d.ts
1020
+ declare class ClickHandler extends EventEmitter {
1021
+ private getNodeByIndex;
1022
+ constructor(getNodeByIndex: (index: number) => GraphNode | null);
1023
+ private handleClick;
1024
+ dispose(): void;
1025
+ }
1026
+ //#endregion
1027
+ //#region controls/handlers/DragHandler.d.ts
1028
+ declare class DragHandler extends EventEmitter {
1029
+ private getNodeByIndex;
1030
+ private cameraController?;
1031
+ private forceSimulation?;
1032
+ private viewport?;
1033
+ private isDragging;
1034
+ private raycaster;
1035
+ private dragPlane;
1036
+ private pointer;
1037
+ constructor(getNodeByIndex: (index: number) => GraphNode | null, cameraController?: CameraController, forceSimulation?: ForceSimulation, viewport?: {
1038
+ width: number;
1039
+ height: number;
1040
+ });
1041
+ /**
1042
+ * Set up drag plane perpendicular to camera, passing through a world point
1043
+ */
1044
+ private setupDragPlane;
1045
+ private handleDragStart;
1046
+ private handleDrag;
1047
+ private handleDragEnd;
1048
+ /**
1049
+ * Convert screen coordinates to world position on drag plane
1050
+ */
1051
+ private screenToWorld;
1052
+ /**
1053
+ * Update viewport dimensions on resize
1054
+ */
1055
+ resize(width: number, height: number): void;
1056
+ dispose(): void;
1057
+ }
1058
+ //#endregion
1059
+ //#region controls/handlers/HoverHandler.d.ts
1060
+ declare class HoverHandler extends EventEmitter {
1061
+ private getNodeByIndex;
1062
+ constructor(getNodeByIndex: (index: number) => GraphNode | null);
1063
+ private handleHoverStart;
1064
+ private handleHover;
1065
+ private handlePop;
1066
+ private handleHoverEnd;
1067
+ dispose(): void;
1068
+ }
1069
+ //#endregion
1070
+ //#region controls/InputProcessor.d.ts
1071
+ /**
1072
+ * Manages pointer/mouse input and emits interaction events
1073
+ * Uses GPU picking for efficient node detection
1074
+ */
1075
+ declare class InputProcessor extends EventEmitter {
1076
+ private pickFn;
1077
+ private canvas;
1078
+ private viewport;
1079
+ private readonly CLICK_THRESHOLD;
1080
+ private readonly HOVER_TO_POP_MS;
1081
+ private pointer;
1082
+ private canvasPointer;
1083
+ private isPointerDown;
1084
+ private isDragging;
1085
+ private mouseDownTime;
1086
+ private draggedIndex;
1087
+ private currentHoverIndex;
1088
+ private hoverStartTime;
1089
+ private hoverProgress;
1090
+ private hasPopped;
1091
+ private isTouch;
1092
+ private readonly TOUCH_MOVE_THRESHOLD;
1093
+ private pointerDownX;
1094
+ private pointerDownY;
1095
+ private lastClientX;
1096
+ private lastClientY;
1097
+ constructor(pickFn: (x: number, y: number) => number, // Injected
1098
+ canvas: HTMLCanvasElement, viewport: {
1099
+ width: number;
1100
+ height: number;
1101
+ });
1102
+ private setupEventListeners;
1103
+ private handlePointerMove;
1104
+ private handlePointerDown;
1105
+ private handlePointerUp;
1106
+ private handlePointerLeave;
1107
+ private updateHover;
1108
+ /**
1109
+ * Update hover state even when pointer is stationary
1110
+ * Called from render loop
1111
+ */
1112
+ update(): void;
1113
+ private updatePointer;
1114
+ /**
1115
+ * Update viewport dimensions on resize
1116
+ */
1117
+ resize(width: number, height: number): void;
1118
+ dispose(): void;
1119
+ }
1120
+ //#endregion
1121
+ //#region controls/InteractionManager.d.ts
1122
+ declare class InteractionManager {
1123
+ private graphScene?;
1124
+ private getConnectedNodeIds?;
1125
+ private pointerInput;
1126
+ private hoverHandler;
1127
+ private clickHandler;
1128
+ private dragHandler;
1129
+ tooltipManager: TooltipManager;
1130
+ private isDragging;
1131
+ isTooltipSticky: boolean;
1132
+ stickyNodeId: string | null;
1133
+ searchHighlightIds: string[];
1134
+ constructor(pickFunction: (x: number, y: number) => number, canvas: HTMLCanvasElement, viewport: {
1135
+ width: number;
1136
+ height: number;
1137
+ }, getNodeByIndex: (index: number) => GraphNode | null, cameraController?: CameraController, forceSimulation?: ForceSimulation, tooltipConfig?: TooltipConfig, graphScene?: GraphScene, getConnectedNodeIds?: (nodeId: string) => string[]);
1138
+ private wireEvents;
1139
+ private wireTooltipEvents;
1140
+ /**
1141
+ * Wire visual feedback events (opacity, highlighting)
1142
+ * Centralized control of visual responses to interactions
1143
+ */
1144
+ private wireVisualFeedbackEvents;
1145
+ getPointerInput(): InputProcessor;
1146
+ getHoverHandler(): HoverHandler;
1147
+ getClickHandler(): ClickHandler;
1148
+ getDragHandler(): DragHandler;
1149
+ getTooltipManager(): TooltipManager;
1150
+ isTooltipStickyOpen(): boolean;
1151
+ /**
1152
+ * Update viewport dimensions on resize
1153
+ */
1154
+ resize(width: number, height: number): void;
1155
+ cleanup(): void;
1156
+ dispose(): void;
1157
+ }
1158
+ //#endregion
1159
+ //#region core/GraphStore.d.ts
1160
+ /**
1161
+ * GraphStore - Central data management
1162
+ * Responsibilities:
1163
+ * - Store raw graph data (nodes, links)
1164
+ * - Node/Link CRUD operations
1165
+ * - ID mapping and lookups
1166
+ * - Data validation
1167
+ * - Change notifications
1168
+ */
1169
+ declare class GraphStore {
1170
+ private nodes;
1171
+ private links;
1172
+ private nodeArray;
1173
+ private linkArray;
1174
+ private nodeIdToIndex;
1175
+ private linkIdToIndex;
1176
+ private nodeToLinks;
1177
+ constructor();
1178
+ /**
1179
+ * Set graph data (replaces all)
1180
+ */
1181
+ setData(data: GraphData): void;
1182
+ /**
1183
+ * Add nodes
1184
+ */
1185
+ addNodes(nodes: GraphNode[]): void;
1186
+ /**
1187
+ * Remove nodes (and connected links)
1188
+ */
1189
+ removeNodes(nodeIds: string[]): void;
1190
+ /**
1191
+ * Add links
1192
+ */
1193
+ addLinks(links: GraphLink[]): void;
1194
+ /**
1195
+ * Remove links
1196
+ */
1197
+ removeLinks(linkIds: string[]): void;
1198
+ /**
1199
+ * Get all nodes as array
1200
+ */
1201
+ getNodes(): GraphNode[];
1202
+ /**
1203
+ * Get all links as array
1204
+ */
1205
+ getLinks(): GraphLink[];
1206
+ /**
1207
+ * Get connected node IDs for a given node
1208
+ */
1209
+ getConnectedNodeIds(nodeId: string): string[];
1210
+ /**
1211
+ * Get node by ID
1212
+ */
1213
+ getNodeById(id: string): GraphNode | null;
1214
+ /**
1215
+ * Get node by index
1216
+ */
1217
+ getNodeByIndex(index: number): GraphNode | null;
1218
+ /**
1219
+ * Get node index
1220
+ */
1221
+ getNodeIndex(id: string): number;
1222
+ /**
1223
+ * Get link by ID
1224
+ */
1225
+ getLinkById(id: string): GraphLink | null;
1226
+ /**
1227
+ * Get links connected to node
1228
+ */
1229
+ getNodeLinks(nodeId: string): GraphLink[];
1230
+ /**
1231
+ * Get node count
1232
+ */
1233
+ getNodeCount(): number;
1234
+ /**
1235
+ * Get link count
1236
+ */
1237
+ getLinkCount(): number;
1238
+ /**
1239
+ * Clear all data
1240
+ */
1241
+ clear(): void;
1242
+ private getLinkId;
1243
+ private addLinkConnectivity;
1244
+ private removeLinkConnectivity;
1245
+ private rebuildNodeArrays;
1246
+ private rebuildLinkArrays;
1247
+ }
1248
+ //#endregion
1249
+ //#region core/Engine.d.ts
1250
+ interface EngineOptions {
1251
+ width?: number;
1252
+ height?: number;
1253
+ backgroundColor?: string;
1254
+ tooltipConfig?: TooltipConfig;
1255
+ groupOrder?: string[];
1256
+ antialiasing?: AntialiasingMode;
1257
+ }
1258
+ /**
1259
+ * Engine - Main orchestrator
1260
+ * Responsibilities:
1261
+ * - Owns all shared buffers (StaticAssets, SimulationBuffers, PickBuffer)
1262
+ * - Coordinates GraphStore, GraphScene, ForceSimulation
1263
+ * - Manages render loop
1264
+ * - Handles user interaction
1265
+ */
1266
+ declare class Engine {
1267
+ readonly canvas: HTMLCanvasElement;
1268
+ readonly graphStore: GraphStore;
1269
+ private graphScene;
1270
+ private forceSimulation;
1271
+ interactionManager: InteractionManager;
1272
+ private clock;
1273
+ private simulationBuffers;
1274
+ private pickBuffer;
1275
+ private animationFrameId;
1276
+ private isRunning;
1277
+ private boundResizeHandler;
1278
+ private groupOrder?;
1279
+ private smoothedTooltipPos;
1280
+ constructor(canvas: HTMLCanvasElement, options?: EngineOptions);
1281
+ /**
1282
+ * Handle window resize event
1283
+ */
1284
+ private handleWindowResize;
1285
+ /**
1286
+ * Set graph data
1287
+ */
1288
+ setData(data: GraphData): void;
1289
+ /**
1290
+ * Update node states based on a callback
1291
+ * This allows changing visibility/behavior without resetting the simulation
1292
+ */
1293
+ updateNodeStates(callback: (node: GraphNode) => NodeState): void;
1294
+ /**
1295
+ * Set target positions for elastic force (tree layout, etc.)
1296
+ * Writes positions into the "original positions" GPU buffer that ElasticPass reads from,
1297
+ * without touching current positions or node states.
1298
+ * Must be called AFTER applyPreset() since updateNodeStates() overwrites original positions.
1299
+ */
1300
+ setTargetPositions(targets: Map<string, {
1301
+ x: number;
1302
+ y: number;
1303
+ z: number;
1304
+ }>): void;
1305
+ /**
1306
+ * Reheat the simulation
1307
+ */
1308
+ reheat(alpha?: number): void;
1309
+ /**
1310
+ * Set alpha decay
1311
+ */
1312
+ setAlphaDecay(decay: number): void;
1313
+ /**
1314
+ * Get current alpha
1315
+ */
1316
+ getAlpha(): number;
1317
+ /**
1318
+ Apply a preset to the graph
1319
+ */
1320
+ applyPreset(preset: GraphPreset): void;
1321
+ /**
1322
+ *
1323
+ * Start render loop
1324
+ */
1325
+ start(): void;
1326
+ /**
1327
+ * Stop render loop
1328
+ */
1329
+ stop(): void;
1330
+ /**
1331
+ * Render loop
1332
+ */
1333
+ private animate;
1334
+ /**
1335
+ * GPU pick node at canvas coordinates
1336
+ */
1337
+ pickNode(x: number, y: number): string | null;
1338
+ /**
1339
+ * Get node by ID
1340
+ */
1341
+ getNodeById(id: string): GraphNode | null;
1342
+ /**
1343
+ * Highlight nodes
1344
+ */
1345
+ highlightNodes(nodeIds: string[]): void;
1346
+ /**
1347
+ * Clear highlights
1348
+ */
1349
+ clearHighlights(): void;
1350
+ /**
1351
+ * Get node position in 3D space
1352
+ */
1353
+ getNodePosition(nodeId: string): THREE.Vector3 | null;
1354
+ /**
1355
+ * Get node screen position from world position
1356
+ * Returns position and visibility info (whether node is on screen and in front of camera)
1357
+ */
1358
+ getNodeScreenPosition(nodeId: string): {
1359
+ x: number;
1360
+ y: number;
1361
+ visible: boolean;
1362
+ } | null;
1363
+ /**
1364
+ * Update sticky tooltip position to follow node during camera movement
1365
+ * Uses lerp smoothing to filter out micro-jitter from force simulation
1366
+ */
1367
+ private updateStickyTooltipPosition;
1368
+ /**
1369
+ * Programmatically select a node (highlight + tooltip)
1370
+ */
1371
+ selectNode(nodeId: string): void;
1372
+ /**
1373
+ * Resize canvas and all dependent components
1374
+ */
1375
+ resize(width: number, height: number): void;
1376
+ /**
1377
+ * Get the unified clock for timing information
1378
+ */
1379
+ getClock(): Clock;
1380
+ /**
1381
+ * Get all nodes
1382
+ */
1383
+ get nodes(): GraphNode[];
1384
+ /**
1385
+ * Get all links
1386
+ */
1387
+ get links(): GraphLink[];
1388
+ /**
1389
+ * Get force simulation for external configuration (GUI binding)
1390
+ */
1391
+ get simulation(): ForceSimulation;
1392
+ /**
1393
+ * Get camera controller for external configuration
1394
+ */
1395
+ get camera(): CameraController;
1396
+ /**
1397
+ * Set camera mode (Orbit, Map, Fly)
1398
+ */
1399
+ setCameraMode(mode: CameraMode): void;
1400
+ /**
1401
+ * Set antialiasing mode at runtime.
1402
+ * Supports switching between 'smaa', 'fxaa', and 'none'.
1403
+ * Cannot switch to 'msaa' at runtime (requires renderer recreation).
1404
+ */
1405
+ setAntialiasing(mode: AntialiasingMode): void;
1406
+ /**
1407
+ * Animate camera to look at a specific target from a specific position
1408
+ */
1409
+ setCameraLookAt(position: {
1410
+ x: number;
1411
+ y: number;
1412
+ z: number;
1413
+ }, target: {
1414
+ x: number;
1415
+ y: number;
1416
+ z: number;
1417
+ }, transitionDuration?: number): Promise<void>;
1418
+ /**
1419
+ * Focus camera on a specific target node
1420
+ */
1421
+ setCameraFocus(target: {
1422
+ x: number;
1423
+ y: number;
1424
+ z: number;
1425
+ }, distance: number, transitionDuration?: number): Promise<void>;
1426
+ /**
1427
+ * Cleanup
1428
+ */
1429
+ dispose(): void;
1430
+ private calculateTextureSize;
1431
+ }
1432
+ //#endregion
1433
+ //#region core/StyleRegistry.d.ts
1434
+ /** Color input - can be THREE.Color, hex number, or CSS color string */
1435
+ type ColorInput = THREE.Color | number | string;
1436
+ /**
1437
+ * Visual properties for a node category (input)
1438
+ */
1439
+ interface NodeStyle {
1440
+ color: ColorInput;
1441
+ size: number;
1442
+ }
1443
+ /**
1444
+ * Visual properties for a link category (input)
1445
+ */
1446
+ interface LinkStyle {
1447
+ color: ColorInput;
1448
+ }
1449
+ /**
1450
+ * Resolved node style with THREE.Color
1451
+ */
1452
+ interface ResolvedNodeStyle {
1453
+ color: THREE.Color;
1454
+ size: number;
1455
+ }
1456
+ /**
1457
+ * Resolved link style with THREE.Color
1458
+ */
1459
+ interface ResolvedLinkStyle {
1460
+ color: THREE.Color;
1461
+ }
1462
+ /**
1463
+ * StyleRegistry - Manages visual styles for node and link categories
1464
+ *
1465
+ * Usage:
1466
+ * styleRegistry.setNodeStyle('person', { color: 0xff0000, size: 20 })
1467
+ * styleRegistry.setLinkStyle('friendship', { color: '#00ff00', width: 2 })
1468
+ *
1469
+ * const style = styleRegistry.getNodeStyle('person')
1470
+ */
1471
+ declare class StyleRegistry {
1472
+ private nodeStyles;
1473
+ private linkStyles;
1474
+ private defaultNodeStyle;
1475
+ private defaultLinkStyle;
1476
+ /**
1477
+ * Convert color input to THREE.Color
1478
+ */
1479
+ private toColor;
1480
+ /**
1481
+ * Set the default style for nodes without a category
1482
+ */
1483
+ setDefaultNodeStyle(style: Partial<NodeStyle>): void;
1484
+ /**
1485
+ * Set the default style for links without a category
1486
+ */
1487
+ setDefaultLinkStyle(style: Partial<LinkStyle>): void;
1488
+ /**
1489
+ * Register a style for a node category
1490
+ */
1491
+ setNodeStyle(category: string, style: NodeStyle): void;
1492
+ /**
1493
+ * Register multiple node styles at once
1494
+ */
1495
+ setNodeStyles(styles: Record<string, NodeStyle>): void;
1496
+ /**
1497
+ * Register a style for a link category
1498
+ */
1499
+ setLinkStyle(category: string, style: LinkStyle): void;
1500
+ /**
1501
+ * Register multiple link styles at once
1502
+ */
1503
+ setLinkStyles(styles: Record<string, LinkStyle>): void;
1504
+ /**
1505
+ * Get the resolved style for a node category
1506
+ */
1507
+ getNodeStyle(category?: string): ResolvedNodeStyle;
1508
+ /**
1509
+ * Get the resolved style for a link category
1510
+ */
1511
+ getLinkStyle(category?: string): ResolvedLinkStyle;
1512
+ /**
1513
+ * Check if a node category exists
1514
+ */
1515
+ hasNodeStyle(category: string): boolean;
1516
+ /**
1517
+ * Check if a link category exists
1518
+ */
1519
+ hasLinkStyle(category: string): boolean;
1520
+ /**
1521
+ * Remove a node style
1522
+ */
1523
+ removeNodeStyle(category: string): void;
1524
+ /**
1525
+ * Remove a link style
1526
+ */
1527
+ removeLinkStyle(category: string): void;
1528
+ /**
1529
+ * Clear all styles
1530
+ */
1531
+ clear(): void;
1532
+ /**
1533
+ * Get all registered node categories
1534
+ */
1535
+ getNodeCategories(): string[];
1536
+ /**
1537
+ * Get all registered link categories
1538
+ */
1539
+ getLinkCategories(): string[];
1540
+ }
1541
+ declare const styleRegistry: StyleRegistry;
1542
+ //#endregion
1543
+ //#region types/iEngineConfig.d.ts
1544
+ interface EngineConfig {
1545
+ container: HTMLElement;
1546
+ width?: number;
1547
+ height?: number;
1548
+ antialias?: boolean;
1549
+ alpha?: boolean;
1550
+ }
1551
+ //#endregion
1552
1552
  export { type AntialiasingMode, type Attractor, type CameraConfig, CameraMode, Clock, Engine, type EngineConfig, type ForceConfig, ForceSimulation, type GraphData, type GraphLink, type GraphNode, type GraphPreset, GraphScene, GraphStore, type LinkStyle, NodeState, type NodeStyle, PickBuffer, type ResolvedAttractor, type ResolvedLinkStyle, type ResolvedNodeStyle, SimulationBuffers, StaticAssets, type Vec3, staticAssets, styleRegistry };