force-3d-graph 1.0.0
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 +114 -0
- package/dist/force-3d-graph.js +2625 -0
- package/dist/force-3d-graph.js.map +1 -0
- package/dist/force-3d-graph.umd.cjs +336 -0
- package/dist/force-3d-graph.umd.cjs.map +1 -0
- package/dist/index.d.ts +320 -0
- package/package.json +55 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import type * as THREE_2 from 'three';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a normalized edge key for duplicate detection
|
|
5
|
+
* Always puts the smaller ID first to handle bidirectional edges
|
|
6
|
+
*/
|
|
7
|
+
export declare function createEdgeKey(source: string, target: string): string;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Default options
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEFAULT_OPTIONS: Required<Omit<ForceGraph3DOptions, 'container' | 'onNodeClick' | 'onNodeHover' | 'onEdgeHover' | 'onNodeAdd' | 'onNodeRemove' | 'onEdgeAdd' | 'onEdgeRemove' | 'onExpand' | 'panelTemplate' | 'panelStyles'>>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Edge data provided by the user
|
|
16
|
+
*/
|
|
17
|
+
export declare interface Edge {
|
|
18
|
+
/** Source node ID */
|
|
19
|
+
source: string;
|
|
20
|
+
/** Target node ID */
|
|
21
|
+
target: string;
|
|
22
|
+
/** Optional relationship label */
|
|
23
|
+
relationship?: string;
|
|
24
|
+
/** Additional custom data */
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export declare interface EdgeObject {
|
|
29
|
+
line: THREE_2.Line;
|
|
30
|
+
source: string;
|
|
31
|
+
target: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export declare type EventCallback = (...args: unknown[]) => void;
|
|
35
|
+
|
|
36
|
+
export declare type EventType = 'nodeClick' | 'nodeHover' | 'edgeHover' | 'nodeAdd' | 'nodeRemove' | 'edgeAdd' | 'edgeRemove' | 'expand' | 'ready';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* ForceGraph3D
|
|
40
|
+
* Main class for the 3D force-directed graph library
|
|
41
|
+
*/
|
|
42
|
+
export declare class ForceGraph3D {
|
|
43
|
+
private options;
|
|
44
|
+
private container;
|
|
45
|
+
private sceneManager;
|
|
46
|
+
private nodeManager;
|
|
47
|
+
private edgeManager;
|
|
48
|
+
private graphEngine;
|
|
49
|
+
private rendererManager;
|
|
50
|
+
private materialFactory;
|
|
51
|
+
private nodeFactory;
|
|
52
|
+
private edgeFactory;
|
|
53
|
+
private lodManager;
|
|
54
|
+
private frustumCuller;
|
|
55
|
+
private raycasterManager;
|
|
56
|
+
private panelManager;
|
|
57
|
+
private edgeTooltipManager;
|
|
58
|
+
private eventCallbacks;
|
|
59
|
+
private initialized;
|
|
60
|
+
private devControls;
|
|
61
|
+
constructor(container?: HTMLElement | null, options?: ForceGraph3DOptions);
|
|
62
|
+
/**
|
|
63
|
+
* Sets up internal callbacks
|
|
64
|
+
*/
|
|
65
|
+
private setupCallbacks;
|
|
66
|
+
/**
|
|
67
|
+
* Handles edge hover
|
|
68
|
+
*/
|
|
69
|
+
private onEdgeHover;
|
|
70
|
+
/**
|
|
71
|
+
* Handles node click
|
|
72
|
+
*/
|
|
73
|
+
private onNodeClick;
|
|
74
|
+
/**
|
|
75
|
+
* Called every simulation step
|
|
76
|
+
*/
|
|
77
|
+
private onSimulate;
|
|
78
|
+
/**
|
|
79
|
+
* Called every render frame
|
|
80
|
+
*/
|
|
81
|
+
private onRender;
|
|
82
|
+
/**
|
|
83
|
+
* Sets the graph data
|
|
84
|
+
*/
|
|
85
|
+
setData(data: GraphData): void;
|
|
86
|
+
/**
|
|
87
|
+
* Adds a node to the graph
|
|
88
|
+
* @returns true if added, false if node already exists or invalid
|
|
89
|
+
*/
|
|
90
|
+
addNode(nodeData: NodeData): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Removes a node from the graph
|
|
93
|
+
* @returns true if removed, false if not found
|
|
94
|
+
*/
|
|
95
|
+
removeNode(nodeId: string): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Updates a node's properties
|
|
98
|
+
*/
|
|
99
|
+
updateNode(nodeId: string, updates: Partial<NodeData>): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Adds an edge to the graph
|
|
102
|
+
* @returns true if added, false if edge already exists or nodes don't exist
|
|
103
|
+
*/
|
|
104
|
+
addEdge(edge: Edge): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Removes an edge from the graph
|
|
107
|
+
* @returns true if removed, false if not found
|
|
108
|
+
*/
|
|
109
|
+
removeEdge(source: string, target: string): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Expands a node by fetching more data
|
|
112
|
+
* @param nodeId - The ID of the node to expand
|
|
113
|
+
* @param depth - The depth of expansion (1-3 levels, default 1)
|
|
114
|
+
* @param fetchFn - Optional fetch function to override the default
|
|
115
|
+
*/
|
|
116
|
+
expandNode(nodeId: string, depth?: number, fetchFn?: (nodeId: string, depth: number) => Promise<GraphData>): Promise<boolean>;
|
|
117
|
+
/**
|
|
118
|
+
* Gets a node by ID
|
|
119
|
+
*/
|
|
120
|
+
getNode(nodeId: string): NodeData | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* Gets neighbor nodes for a node
|
|
123
|
+
*/
|
|
124
|
+
getNeighbors(nodeId: string): NodeData[];
|
|
125
|
+
/**
|
|
126
|
+
* Gets the number of nodes
|
|
127
|
+
*/
|
|
128
|
+
getNodeCount(): number;
|
|
129
|
+
/**
|
|
130
|
+
* Gets the number of edges
|
|
131
|
+
*/
|
|
132
|
+
getEdgeCount(): number;
|
|
133
|
+
/**
|
|
134
|
+
* Sets the expand callback
|
|
135
|
+
* @param callback - Function that fetches expansion data given a nodeId and depth
|
|
136
|
+
*/
|
|
137
|
+
setExpandCallback(callback: (nodeId: string, depth?: number) => Promise<GraphData>): void;
|
|
138
|
+
/**
|
|
139
|
+
* Focuses the camera on a specific node with smooth animation
|
|
140
|
+
*/
|
|
141
|
+
focusOnNode(nodeId: string, distance?: number): void;
|
|
142
|
+
/**
|
|
143
|
+
* Shows the info panel for a specific node
|
|
144
|
+
*/
|
|
145
|
+
showNodePanel(nodeId: string): void;
|
|
146
|
+
/**
|
|
147
|
+
* Searches nodes by label or ID (case-insensitive)
|
|
148
|
+
* @returns Array of matching nodes
|
|
149
|
+
*/
|
|
150
|
+
searchNodes(query: string): NodeData[];
|
|
151
|
+
/**
|
|
152
|
+
* Searches edges by relationship (case-insensitive)
|
|
153
|
+
* @returns Array of matching edges with source/target node info
|
|
154
|
+
*/
|
|
155
|
+
searchEdges(query: string): Array<{
|
|
156
|
+
edge: Edge;
|
|
157
|
+
sourceNode: NodeData;
|
|
158
|
+
targetNode: NodeData;
|
|
159
|
+
}>;
|
|
160
|
+
/**
|
|
161
|
+
* Gets all nodes as an array
|
|
162
|
+
*/
|
|
163
|
+
getAllNodes(): NodeData[];
|
|
164
|
+
/**
|
|
165
|
+
* Gets all edges
|
|
166
|
+
*/
|
|
167
|
+
getAllEdges(): Edge[];
|
|
168
|
+
/**
|
|
169
|
+
* Checks if the graph is initialized
|
|
170
|
+
*/
|
|
171
|
+
isInitialized(): boolean;
|
|
172
|
+
/**
|
|
173
|
+
* Registers an event listener
|
|
174
|
+
*/
|
|
175
|
+
on(event: EventType, callback: EventCallback): void;
|
|
176
|
+
/**
|
|
177
|
+
* Emits an event
|
|
178
|
+
*/
|
|
179
|
+
private emit;
|
|
180
|
+
/**
|
|
181
|
+
* Sets physics parameters
|
|
182
|
+
*/
|
|
183
|
+
setPhysicsParams(params: {
|
|
184
|
+
repulsionStrength?: number;
|
|
185
|
+
attractionStrength?: number;
|
|
186
|
+
damping?: number;
|
|
187
|
+
}): void;
|
|
188
|
+
/**
|
|
189
|
+
* Creates dev mode controls (only in development)
|
|
190
|
+
*/
|
|
191
|
+
private createDevControls;
|
|
192
|
+
/**
|
|
193
|
+
* Destroys the graph and releases all resources
|
|
194
|
+
*/
|
|
195
|
+
destroy(): void;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Constructor options for ForceGraph3D
|
|
200
|
+
*/
|
|
201
|
+
export declare interface ForceGraph3DOptions {
|
|
202
|
+
container?: HTMLElement | null;
|
|
203
|
+
backgroundColor?: number | string;
|
|
204
|
+
cameraPosition?: Vector3Data;
|
|
205
|
+
cameraFov?: number;
|
|
206
|
+
repulsionStrength?: number;
|
|
207
|
+
attractionStrength?: number;
|
|
208
|
+
damping?: number;
|
|
209
|
+
useBarnesHut?: boolean;
|
|
210
|
+
barnesHutTheta?: number;
|
|
211
|
+
defaultNodeColor?: number;
|
|
212
|
+
nodeRadius?: number;
|
|
213
|
+
nodeSegments?: number;
|
|
214
|
+
enableLOD?: boolean;
|
|
215
|
+
lodDistances?: number[];
|
|
216
|
+
lodSegments?: number[];
|
|
217
|
+
edgeColor?: number;
|
|
218
|
+
edgeOpacity?: number;
|
|
219
|
+
enableEdgeCulling?: boolean;
|
|
220
|
+
showPanel?: boolean;
|
|
221
|
+
panelTemplate?: (nodeData: NodeData, neighbors: NodeData[]) => string;
|
|
222
|
+
panelStyles?: Record<string, string>;
|
|
223
|
+
targetFPS?: number;
|
|
224
|
+
maxVisibleNodes?: number;
|
|
225
|
+
onNodeClick?: (nodeData: NodeData) => void;
|
|
226
|
+
onNodeHover?: (nodeData: NodeData | null) => void;
|
|
227
|
+
onEdgeHover?: (edge: Edge | null, sourceNode: NodeData | null, targetNode: NodeData | null) => void;
|
|
228
|
+
onNodeAdd?: (nodeData: NodeData) => void;
|
|
229
|
+
onNodeRemove?: (nodeId: string) => void;
|
|
230
|
+
onEdgeAdd?: (edge: Edge) => void;
|
|
231
|
+
onEdgeRemove?: (edge: Edge) => void;
|
|
232
|
+
onExpand?: (nodeId: string, depth?: number) => Promise<GraphData>;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Generates a large sample dataset for performance testing
|
|
237
|
+
*/
|
|
238
|
+
export declare function generateLargeSampleData(nodeCount?: number): GraphData;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Generates sample graph data with the specified number of nodes
|
|
242
|
+
*/
|
|
243
|
+
export declare function generateSampleData(nodeCount?: number): GraphData;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Graph data structure
|
|
247
|
+
*/
|
|
248
|
+
export declare interface GraphData {
|
|
249
|
+
nodes: NodeData[];
|
|
250
|
+
edges: Edge[];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Internal edge representation
|
|
255
|
+
*/
|
|
256
|
+
export declare interface InternalEdge extends Edge {
|
|
257
|
+
sourceNode: InternalNode;
|
|
258
|
+
targetNode: InternalNode;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Internal node representation with physics state
|
|
263
|
+
*/
|
|
264
|
+
export declare interface InternalNode extends NodeData {
|
|
265
|
+
position: Vector3Data;
|
|
266
|
+
velocity: Vector3Data;
|
|
267
|
+
mass: number;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export declare enum LODLevel {
|
|
271
|
+
HIGH = 0,
|
|
272
|
+
MEDIUM = 1,
|
|
273
|
+
LOW = 2
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Node data provided by the user
|
|
278
|
+
*/
|
|
279
|
+
export declare interface NodeData {
|
|
280
|
+
/** Unique identifier for the node */
|
|
281
|
+
id: string;
|
|
282
|
+
/** Display label for the node */
|
|
283
|
+
label: string;
|
|
284
|
+
/** Optional hex color (default: 0x4A90E2) */
|
|
285
|
+
color?: number;
|
|
286
|
+
/** Optional initial position (random if not provided) */
|
|
287
|
+
position?: Vector3Data;
|
|
288
|
+
/** Additional custom data */
|
|
289
|
+
[key: string]: unknown;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export declare interface NodeObject {
|
|
293
|
+
group: THREE_2.Group;
|
|
294
|
+
sphere: THREE_2.Mesh;
|
|
295
|
+
label: THREE_2.Sprite;
|
|
296
|
+
lodLevel: LODLevel;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Validates edge data
|
|
301
|
+
* @returns true if valid, false otherwise (logs warning)
|
|
302
|
+
*/
|
|
303
|
+
export declare function validateEdgeData(edge: unknown): edge is Edge;
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Validates node data
|
|
307
|
+
* @returns true if valid, false otherwise (logs warning)
|
|
308
|
+
*/
|
|
309
|
+
export declare function validateNodeData(node: unknown): node is NodeData;
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Simple 3D vector
|
|
313
|
+
*/
|
|
314
|
+
export declare interface Vector3Data {
|
|
315
|
+
x: number;
|
|
316
|
+
y: number;
|
|
317
|
+
z: number;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export { }
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "force-3d-graph",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A 3D force-directed graph visualization library built with Three.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/force-3d-graph.umd.cjs",
|
|
7
|
+
"module": "./dist/force-3d-graph.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/force-3d-graph.js",
|
|
12
|
+
"require": "./dist/force-3d-graph.umd.cjs",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"dev": "vite",
|
|
21
|
+
"build": "tsc && vite build",
|
|
22
|
+
"preview": "vite preview"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"3d",
|
|
26
|
+
"graph",
|
|
27
|
+
"force-directed",
|
|
28
|
+
"three.js",
|
|
29
|
+
"visualization",
|
|
30
|
+
"network"
|
|
31
|
+
],
|
|
32
|
+
"author": "Anish <visy.ani@gmail.com>",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/visy-ani/force-graph.git"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/visy-ani/force-graph/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/visy-ani/force-graph#readme",
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"three": ">=0.150.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^25.0.8",
|
|
47
|
+
"@types/three": "^0.160.0",
|
|
48
|
+
"typescript": "^5.3.3",
|
|
49
|
+
"vite": "^5.0.10",
|
|
50
|
+
"vite-plugin-dts": "^3.7.0"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"three": ">=0.150.0"
|
|
54
|
+
}
|
|
55
|
+
}
|