@fusefactory/fuse-three-forcegraph 1.0.4 → 1.0.6

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