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