@yurialvesbordin/graphium 0.0.0-stage → 2.0.1

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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -2
  3. package/dist/Graphium.d.ts +156 -0
  4. package/dist/Graphium.d.ts.map +1 -0
  5. package/dist/Graphium.js +413 -0
  6. package/dist/Graphium.js.map +1 -0
  7. package/dist/core/FocusController.d.ts +16 -0
  8. package/dist/core/FocusController.d.ts.map +1 -0
  9. package/dist/core/FocusController.js +53 -0
  10. package/dist/core/FocusController.js.map +1 -0
  11. package/dist/core/GraphEditor.d.ts +61 -0
  12. package/dist/core/GraphEditor.d.ts.map +1 -0
  13. package/dist/core/GraphEditor.js +165 -0
  14. package/dist/core/GraphEditor.js.map +1 -0
  15. package/dist/core/GraphModel.d.ts +166 -0
  16. package/dist/core/GraphModel.d.ts.map +1 -0
  17. package/dist/core/GraphModel.js +730 -0
  18. package/dist/core/GraphModel.js.map +1 -0
  19. package/dist/core/SelectionController.d.ts +26 -0
  20. package/dist/core/SelectionController.d.ts.map +1 -0
  21. package/dist/core/SelectionController.js +78 -0
  22. package/dist/core/SelectionController.js.map +1 -0
  23. package/dist/core/colors.d.ts +27 -0
  24. package/dist/core/colors.d.ts.map +1 -0
  25. package/dist/core/colors.js +141 -0
  26. package/dist/core/colors.js.map +1 -0
  27. package/dist/core/events.d.ts +21 -0
  28. package/dist/core/events.d.ts.map +1 -0
  29. package/dist/core/events.js +64 -0
  30. package/dist/core/events.js.map +1 -0
  31. package/dist/core/handles.d.ts +60 -0
  32. package/dist/core/handles.d.ts.map +1 -0
  33. package/dist/core/handles.js +116 -0
  34. package/dist/core/handles.js.map +1 -0
  35. package/dist/core/theme.d.ts +9 -0
  36. package/dist/core/theme.d.ts.map +1 -0
  37. package/dist/core/theme.js +167 -0
  38. package/dist/core/theme.js.map +1 -0
  39. package/dist/core/themes.d.ts +9 -0
  40. package/dist/core/themes.d.ts.map +1 -0
  41. package/dist/core/themes.js +103 -0
  42. package/dist/core/themes.js.map +1 -0
  43. package/dist/core/types.d.ts +287 -0
  44. package/dist/core/types.d.ts.map +1 -0
  45. package/dist/core/types.js +7 -0
  46. package/dist/core/types.js.map +1 -0
  47. package/dist/index.d.ts +21 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +20 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/interaction/InteractionBinder.d.ts +43 -0
  52. package/dist/interaction/InteractionBinder.d.ts.map +1 -0
  53. package/dist/interaction/InteractionBinder.js +121 -0
  54. package/dist/interaction/InteractionBinder.js.map +1 -0
  55. package/dist/interaction/PointerController.d.ts +83 -0
  56. package/dist/interaction/PointerController.d.ts.map +1 -0
  57. package/dist/interaction/PointerController.js +294 -0
  58. package/dist/interaction/PointerController.js.map +1 -0
  59. package/dist/physics/PhysicsEngine.d.ts +82 -0
  60. package/dist/physics/PhysicsEngine.d.ts.map +1 -0
  61. package/dist/physics/PhysicsEngine.js +469 -0
  62. package/dist/physics/PhysicsEngine.js.map +1 -0
  63. package/dist/physics/SpatialHash.d.ts +36 -0
  64. package/dist/physics/SpatialHash.d.ts.map +1 -0
  65. package/dist/physics/SpatialHash.js +126 -0
  66. package/dist/physics/SpatialHash.js.map +1 -0
  67. package/dist/physics/presets.d.ts +14 -0
  68. package/dist/physics/presets.d.ts.map +1 -0
  69. package/dist/physics/presets.js +108 -0
  70. package/dist/physics/presets.js.map +1 -0
  71. package/dist/render/Camera.d.ts +55 -0
  72. package/dist/render/Camera.d.ts.map +1 -0
  73. package/dist/render/Camera.js +94 -0
  74. package/dist/render/Camera.js.map +1 -0
  75. package/dist/render/LabelLayer.d.ts +32 -0
  76. package/dist/render/LabelLayer.d.ts.map +1 -0
  77. package/dist/render/LabelLayer.js +142 -0
  78. package/dist/render/LabelLayer.js.map +1 -0
  79. package/dist/render/RenderLoop.d.ts +67 -0
  80. package/dist/render/RenderLoop.d.ts.map +1 -0
  81. package/dist/render/RenderLoop.js +126 -0
  82. package/dist/render/RenderLoop.js.map +1 -0
  83. package/dist/render/Renderer.d.ts +73 -0
  84. package/dist/render/Renderer.d.ts.map +1 -0
  85. package/dist/render/Renderer.js +512 -0
  86. package/dist/render/Renderer.js.map +1 -0
  87. package/dist/render/TextureAtlas.d.ts +51 -0
  88. package/dist/render/TextureAtlas.d.ts.map +1 -0
  89. package/dist/render/TextureAtlas.js +160 -0
  90. package/dist/render/TextureAtlas.js.map +1 -0
  91. package/dist/render/ViewportController.d.ts +34 -0
  92. package/dist/render/ViewportController.d.ts.map +1 -0
  93. package/dist/render/ViewportController.js +57 -0
  94. package/dist/render/ViewportController.js.map +1 -0
  95. package/dist/render/geometry.d.ts +19 -0
  96. package/dist/render/geometry.d.ts.map +1 -0
  97. package/dist/render/geometry.js +71 -0
  98. package/dist/render/geometry.js.map +1 -0
  99. package/dist/render/shaders.d.ts +13 -0
  100. package/dist/render/shaders.d.ts.map +1 -0
  101. package/dist/render/shaders.js +183 -0
  102. package/dist/render/shaders.js.map +1 -0
  103. package/package.json +73 -4
@@ -0,0 +1,413 @@
1
+ /**
2
+ * Implements the main Graphium facade. The class wires the data model,
3
+ * physics engine, camera, renderer, label layer and pointer controller into
4
+ * one object, exposes a fluent chainable API with sensible defaults, and
5
+ * runs an on demand render loop that pauses completely while the simulation
6
+ * sleeps.
7
+ */
8
+ import { Emitter } from './core/events.js';
9
+ import { FocusController } from './core/FocusController.js';
10
+ import { GraphEditor } from './core/GraphEditor.js';
11
+ import { GraphModel } from './core/GraphModel.js';
12
+ import { LinkHandle, NodeHandle } from './core/handles.js';
13
+ import { SelectionController } from './core/SelectionController.js';
14
+ import { resolveTheme } from './core/theme.js';
15
+ import { BUILT_IN_THEMES } from './core/themes.js';
16
+ import { InteractionBinder } from './interaction/InteractionBinder.js';
17
+ import { PhysicsEngine } from './physics/PhysicsEngine.js';
18
+ import { Camera } from './render/Camera.js';
19
+ import { LabelLayer } from './render/LabelLayer.js';
20
+ import { RenderLoop } from './render/RenderLoop.js';
21
+ import { Renderer } from './render/Renderer.js';
22
+ import { TextureAtlas } from './render/TextureAtlas.js';
23
+ import { ViewportController } from './render/ViewportController.js';
24
+ export class Graphium {
25
+ constructor(options = {}) {
26
+ this.events = new Emitter();
27
+ this.running = false;
28
+ this.destroyed = false;
29
+ this.options = options;
30
+ this.theme = resolveTheme(options.theme);
31
+ this.model = new GraphModel({
32
+ nodeCapacity: options.nodeCapacity,
33
+ linkCapacity: options.linkCapacity,
34
+ theme: this.theme,
35
+ });
36
+ this.physics = new PhysicsEngine(this.model, options.physics ?? {});
37
+ this.physics.hash.setCellSize(this.physics.options.repulsionRadius);
38
+ this.camera = new Camera(options.camera ?? {});
39
+ const canvas = options.canvas ?? (options.container ? createCanvasIn(options.container) : createCanvasIn(document.body));
40
+ this.renderer = new Renderer(canvas, this.theme, options.renderer ?? {});
41
+ this.renderer.setCamera(this.camera);
42
+ this.atlas = new TextureAtlas(this.renderer.gl);
43
+ this.renderer.setAtlas(this.atlas);
44
+ this.atlas.onEvent = event => {
45
+ this.events.emit(event.type, event);
46
+ this.invalidate();
47
+ };
48
+ const host = canvas.parentElement ?? document.body;
49
+ this.labels = new LabelLayer(host, this.theme);
50
+ this.labels.attach(this.model, this.camera);
51
+ this.loop = new RenderLoop({
52
+ model: this.model,
53
+ physics: this.physics,
54
+ camera: this.camera,
55
+ renderer: this.renderer,
56
+ labels: this.labels,
57
+ atlas: this.atlas,
58
+ isRunning: () => this.running,
59
+ isDestroyed: () => this.destroyed,
60
+ autoFit: options.autoFit ?? false,
61
+ fitView: () => this.fit(),
62
+ });
63
+ this.editor = new GraphEditor({
64
+ model: this.model,
65
+ physics: this.physics,
66
+ events: this.events,
67
+ resetAutoFit: () => this.loop.resetAutoFit(),
68
+ invalidate: () => this.invalidate(),
69
+ });
70
+ this.selection = new SelectionController(this.model, () => this.invalidate());
71
+ this.focusController = new FocusController(this.model, () => this.invalidate());
72
+ this.viewport = new ViewportController({
73
+ model: this.model,
74
+ camera: this.camera,
75
+ renderer: this.renderer,
76
+ invalidate: () => this.invalidate(),
77
+ });
78
+ this.binder = new InteractionBinder({
79
+ canvas,
80
+ model: this.model,
81
+ physics: this.physics,
82
+ camera: this.camera,
83
+ hash: this.physics.hash,
84
+ events: this.events,
85
+ interaction: options.interaction,
86
+ selection: this.selection,
87
+ invalidate: () => this.invalidate(),
88
+ });
89
+ this.resize();
90
+ if (typeof ResizeObserver !== 'undefined' && (options.autoResize ?? true)) {
91
+ new ResizeObserver(() => this.resize()).observe(canvas);
92
+ }
93
+ if (options.autoStart ?? true) {
94
+ this.start();
95
+ }
96
+ }
97
+ /** Creates a Graphium instance with the supplied configuration. */
98
+ static create(options = {}) {
99
+ return new Graphium(options);
100
+ }
101
+ /** Subscribes to an event and returns an unsubscribe function. */
102
+ on(type, listener) {
103
+ return this.events.on(type, listener);
104
+ }
105
+ /** Subscribes to an event exactly once. */
106
+ once(type, listener) {
107
+ return this.events.once(type, listener);
108
+ }
109
+ /** Removes one listener, or every listener of a type. */
110
+ off(type, listener) {
111
+ this.events.off(type, listener);
112
+ return this;
113
+ }
114
+ /** Dispatches an event payload to the registered listeners. */
115
+ emit(type, payload) {
116
+ this.events.emit(type, payload);
117
+ return this;
118
+ }
119
+ /** Adds one node and returns the graph for chaining. */
120
+ addNode(id, options = {}) {
121
+ this.editor.addNode(id, options);
122
+ return this;
123
+ }
124
+ /** Adds many nodes in one call and returns the graph for chaining. */
125
+ addNodes(nodes) {
126
+ this.editor.addNodes(nodes);
127
+ return this;
128
+ }
129
+ link(sourceOrId, target, options = {}) {
130
+ if (target === undefined) {
131
+ return this.linkById(sourceOrId);
132
+ }
133
+ this.editor.link(sourceOrId, target, options);
134
+ return this;
135
+ }
136
+ /** Adds many links in one call and returns the graph for chaining. */
137
+ addLinks(links) {
138
+ this.editor.addLinks(links);
139
+ return this;
140
+ }
141
+ /** Returns a fluent handle for one node, or null when it is missing. */
142
+ node(id) {
143
+ const index = this.model.nodeIndexOf(id);
144
+ return index < 0 ? null : new NodeHandle(this, this.model.nodeIdAt(index));
145
+ }
146
+ /** Returns a fluent handle for one link, or null when it is missing. */
147
+ linkById(id) {
148
+ const index = this.model.linkIndexOf(id);
149
+ return index < 0 ? null : new LinkHandle(this, this.model.linkIdAt(index));
150
+ }
151
+ /** Replaces the entire graph with the supplied data payload. */
152
+ setData(data) {
153
+ this.editor.setData(data);
154
+ return this;
155
+ }
156
+ /** Removes one node together with its links. */
157
+ removeNode(id) {
158
+ return this.editor.removeNode(id);
159
+ }
160
+ /** Removes one link by id. */
161
+ removeLink(id) {
162
+ return this.editor.removeLink(id);
163
+ }
164
+ /** Removes every node and link while keeping the current theme. */
165
+ clear() {
166
+ this.editor.clear();
167
+ return this;
168
+ }
169
+ /** Returns a snapshot of one node or null when it does not exist. */
170
+ getNode(id) {
171
+ const index = this.model.nodeIndexOf(id);
172
+ return index < 0 ? null : this.model.nodeSnapshot(index);
173
+ }
174
+ /** Returns a snapshot of one link or null when it does not exist. */
175
+ getLink(id) {
176
+ const index = this.model.linkIndexOf(id);
177
+ return index < 0 ? null : this.model.linkSnapshot(index);
178
+ }
179
+ /** Returns the ids of every node currently in the graph. */
180
+ nodeIds() {
181
+ const ids = [];
182
+ for (let index = 0; index < this.model.nodeCount; index++) {
183
+ ids.push(this.model.nodeIdAt(index));
184
+ }
185
+ return ids;
186
+ }
187
+ /** Returns the ids of every link currently in the graph. */
188
+ linkIds() {
189
+ const ids = [];
190
+ for (let index = 0; index < this.model.linkCount; index++) {
191
+ ids.push(this.model.linkIdAt(index));
192
+ }
193
+ return ids;
194
+ }
195
+ /** Sets the node image and starts the asynchronous load. */
196
+ setNodeImage(id, url, mode = 'cover') {
197
+ this.editor.setNodeImage(id, url, mode);
198
+ return this;
199
+ }
200
+ /** Selects one node, optionally keeping the current selection. */
201
+ selectNode(id, selected = true, additive = false) {
202
+ this.selection.selectNode(id, selected, additive);
203
+ return this;
204
+ }
205
+ /** Selects one link, optionally keeping the current selection. */
206
+ selectLink(id, selected = true, additive = false) {
207
+ this.selection.selectLink(id, selected, additive);
208
+ return this;
209
+ }
210
+ /** Clears the selection of every node and link. */
211
+ clearSelection() {
212
+ this.selection.clear();
213
+ return this;
214
+ }
215
+ /** Returns the ids of every selected node. */
216
+ selectedNodes() {
217
+ return this.selection.selectedNodes();
218
+ }
219
+ /** Returns the ids of every selected link. */
220
+ selectedLinks() {
221
+ return this.selection.selectedLinks();
222
+ }
223
+ /** Dims every node and link that is not adjacent to the focus node. */
224
+ focus(id) {
225
+ this.focusController.focus(id);
226
+ return this;
227
+ }
228
+ /** Removes all dimming applied by focus. */
229
+ unfocus() {
230
+ this.focusController.unfocus();
231
+ return this;
232
+ }
233
+ /** Merges theme values, optionally starting from a built in theme name. */
234
+ setTheme(theme) {
235
+ const base = theme.name && BUILT_IN_THEMES[theme.name] ? BUILT_IN_THEMES[theme.name] : this.options.theme ?? {};
236
+ const merged = { ...base, ...theme };
237
+ delete merged.name;
238
+ this.options.theme = merged;
239
+ this.theme = resolveTheme(merged, this.theme);
240
+ this.model.palette = this.theme.nodeColorPalette;
241
+ this.renderer.setTheme(this.theme);
242
+ this.labels.theme = this.theme;
243
+ this.labels.applyTheme();
244
+ this.labels.minZoom = this.theme.labelEnabled ? 0.3 : 2;
245
+ this.invalidate();
246
+ return this;
247
+ }
248
+ /** Updates physics options live and wakes the simulation. */
249
+ setPhysics(options) {
250
+ this.physics.setOptions(options);
251
+ this.physics.hash.setCellSize(this.physics.options.repulsionRadius);
252
+ return this;
253
+ }
254
+ /** Applies a named physics preset with optional overrides. */
255
+ usePreset(name, overrides = {}) {
256
+ this.physics.usePreset(name, overrides);
257
+ this.physics.hash.setCellSize(this.physics.options.repulsionRadius);
258
+ return this;
259
+ }
260
+ /** Updates interaction options on the live pointer controller. */
261
+ setInteraction(options) {
262
+ this.binder.setInteraction(options);
263
+ return this;
264
+ }
265
+ /** Restarts the simulation and returns the graph for chaining. */
266
+ reboot() {
267
+ this.physics.reset();
268
+ return this;
269
+ }
270
+ /** Scales the view so the whole graph fits with padding. */
271
+ fit(padding = 60) {
272
+ this.viewport.fit(padding);
273
+ return this;
274
+ }
275
+ /** Centers the view on a world point. */
276
+ centerOn(x, y) {
277
+ this.viewport.centerOn(x, y);
278
+ return this;
279
+ }
280
+ /** Multiplies the current zoom level. */
281
+ zoomBy(factor) {
282
+ this.viewport.zoomBy(factor);
283
+ return this;
284
+ }
285
+ /** Sets an absolute zoom level. */
286
+ zoomTo(zoom) {
287
+ this.viewport.zoomTo(zoom);
288
+ return this;
289
+ }
290
+ /** Resizes the renderer to the canvas client size. */
291
+ resize() {
292
+ this.viewport.resize();
293
+ return this;
294
+ }
295
+ /** Advances physics and renders once, returning the kinetic energy. */
296
+ step(dt = 1 / 60) {
297
+ return this.loop.step(dt);
298
+ }
299
+ /** Renders a frame immediately without stepping the simulation. */
300
+ render() {
301
+ this.loop.renderNow();
302
+ return this;
303
+ }
304
+ /** Requests a render on the next scheduled frame. */
305
+ requestRender() {
306
+ this.loop.requestRender();
307
+ return this;
308
+ }
309
+ /** Marks the view dirty and guarantees a scheduled frame. */
310
+ invalidate() {
311
+ this.loop.invalidate();
312
+ }
313
+ /** Starts the run loop and returns the graph for chaining. */
314
+ start() {
315
+ if (this.running || this.destroyed) {
316
+ return this;
317
+ }
318
+ this.running = true;
319
+ this.physics.wake();
320
+ this.events.emit('start', {});
321
+ this.loop.schedule();
322
+ return this;
323
+ }
324
+ /** Stops the run loop and returns the graph for chaining. */
325
+ stop() {
326
+ if (!this.running) {
327
+ return this;
328
+ }
329
+ this.running = false;
330
+ this.events.emit('stop', {});
331
+ return this;
332
+ }
333
+ /** Resolves when every requested node image finished loading. */
334
+ loadImages() {
335
+ return this.atlas.loadAll();
336
+ }
337
+ /** Finds the link index closest to a world position within a radius. */
338
+ pickLinkAt(worldX, worldY, hitRadius = 8) {
339
+ return this.binder.pickLinkAt(worldX, worldY, hitRadius);
340
+ }
341
+ /** Returns the world position under a screen position. */
342
+ screenToWorld(screenX, screenY) {
343
+ return this.viewport.screenToWorld(screenX, screenY);
344
+ }
345
+ /** Returns a performance statistics snapshot for dashboards. */
346
+ stats() {
347
+ return {
348
+ nodeCount: this.model.nodeCount,
349
+ linkCount: this.model.linkCount,
350
+ fps: Math.round(this.loop.fps),
351
+ frameMs: Math.round(this.loop.frameMs * 100) / 100,
352
+ physicsMs: Math.round(this.loop.physicsMs * 100) / 100,
353
+ renderMs: Math.round(this.renderer.lastRenderMs * 100) / 100,
354
+ sleeping: this.physics.sleeping,
355
+ };
356
+ }
357
+ /** Captures the current canvas contents as a PNG data URL. */
358
+ screenshot() {
359
+ this.loop.renderNow();
360
+ return this.renderer.canvas.toDataURL('image/png');
361
+ }
362
+ /** Exports the current graph as a plain JSON friendly object. */
363
+ toJSON() {
364
+ return this.editor.toJSON();
365
+ }
366
+ /** Releases every resource owned by the instance. */
367
+ destroy() {
368
+ if (this.destroyed) {
369
+ return;
370
+ }
371
+ this.destroyed = true;
372
+ this.running = false;
373
+ this.loop.cancel();
374
+ this.binder.destroy();
375
+ this.labels.destroy();
376
+ this.atlas.onEvent = null;
377
+ this.renderer.destroy();
378
+ this.events.clear();
379
+ this.model.clear();
380
+ }
381
+ /** Returns the number of nodes in the graph. */
382
+ get nodeCount() {
383
+ return this.model.nodeCount;
384
+ }
385
+ /** Returns the number of links in the graph. */
386
+ get linkCount() {
387
+ return this.model.linkCount;
388
+ }
389
+ /** Reports whether the physics simulation is currently asleep. */
390
+ get sleeping() {
391
+ return this.physics.sleeping;
392
+ }
393
+ }
394
+ /** Creates a canvas element appended to a host element. */
395
+ function createCanvasIn(host) {
396
+ const canvas = document.createElement('canvas');
397
+ Object.assign(canvas.style, {
398
+ display: 'block',
399
+ width: '100%',
400
+ height: '100%',
401
+ position: 'absolute',
402
+ top: '0',
403
+ left: '0',
404
+ zIndex: '0',
405
+ touchAction: 'none',
406
+ });
407
+ if (host !== document.body) {
408
+ Object.assign(host.style, { position: 'relative' });
409
+ }
410
+ host.appendChild(canvas);
411
+ return canvas;
412
+ }
413
+ //# sourceMappingURL=Graphium.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Graphium.js","sourceRoot":"","sources":["../src/Graphium.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Owns the focus mode: dims every node and link that is not adjacent to
3
+ * the focused node and restores the graph on unfocus.
4
+ */
5
+ import { GraphModel } from './GraphModel.js';
6
+ import type { NodeId } from './types.js';
7
+ export declare class FocusController {
8
+ private readonly model;
9
+ private readonly invalidate;
10
+ constructor(model: GraphModel, invalidate: () => void);
11
+ /** Dims every node and link that is not adjacent to the focus node. */
12
+ focus(id: NodeId | number): void;
13
+ /** Removes all dimming applied by focus. */
14
+ unfocus(): void;
15
+ }
16
+ //# sourceMappingURL=FocusController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FocusController.d.ts","sourceRoot":"","sources":["../../src/core/FocusController.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAsB,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;gBADV,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,MAAM,IAAI;IAGzC,uEAAuE;IACvE,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA2BhC,4CAA4C;IAC5C,OAAO,IAAI,IAAI;CAWhB"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Owns the focus mode: dims every node and link that is not adjacent to
3
+ * the focused node and restores the graph on unfocus.
4
+ */
5
+ import { LINK_DIM, NODE_DIM } from './GraphModel.js';
6
+ export class FocusController {
7
+ constructor(model, invalidate) {
8
+ this.model = model;
9
+ this.invalidate = invalidate;
10
+ }
11
+ /** Dims every node and link that is not adjacent to the focus node. */
12
+ focus(id) {
13
+ const index = this.model.nodeIndexOf(id);
14
+ if (index < 0) {
15
+ return;
16
+ }
17
+ const model = this.model;
18
+ const neighbors = new Set([index]);
19
+ for (let link = 0; link < model.linkCount; link++) {
20
+ const touches = model.source[link] === index || model.target[link] === index;
21
+ if (touches) {
22
+ neighbors.add(model.source[link]);
23
+ neighbors.add(model.target[link]);
24
+ }
25
+ else {
26
+ model.linkFlags[link] |= LINK_DIM;
27
+ }
28
+ }
29
+ for (let node = 0; node < model.nodeCount; node++) {
30
+ if (!neighbors.has(node)) {
31
+ model.flags[node] |= NODE_DIM;
32
+ }
33
+ else {
34
+ model.flags[node] &= ~NODE_DIM;
35
+ }
36
+ }
37
+ model.appearanceRevision++;
38
+ this.invalidate();
39
+ }
40
+ /** Removes all dimming applied by focus. */
41
+ unfocus() {
42
+ const model = this.model;
43
+ for (let node = 0; node < model.nodeCount; node++) {
44
+ model.flags[node] &= ~NODE_DIM;
45
+ }
46
+ for (let link = 0; link < model.linkCount; link++) {
47
+ model.linkFlags[link] &= ~LINK_DIM;
48
+ }
49
+ model.appearanceRevision++;
50
+ this.invalidate();
51
+ }
52
+ }
53
+ //# sourceMappingURL=FocusController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FocusController.js","sourceRoot":"","sources":["../../src/core/FocusController.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,QAAQ,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGjE,MAAM,OAAO,eAAe;IAC1B,YACmB,KAAiB,EACjB,UAAsB;QADtB,UAAK,GAAL,KAAK,CAAY;QACjB,eAAU,GAAV,UAAU,CAAY;IACtC,CAAC;IAEJ,uEAAuE;IACvE,KAAK,CAAC,EAAmB;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACzC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC;YAC7E,IAAI,OAAO,EAAE,CAAC;gBACZ,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBAClC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;YACpC,CAAC;QACH,CAAC;QACD,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;YAClD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;YACjC,CAAC;QACH,CAAC;QACD,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC3B,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED,4CAA4C;IAC5C,OAAO;QACL,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;YAClD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;QACjC,CAAC;QACD,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;YAClD,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;QACrC,CAAC;QACD,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC3B,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;CACF"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Owns every graph data mutation: node and link CRUD, per element property
3
+ * updates, custom data attachment and JSON export.
4
+ */
5
+ import type { Emitter } from './events.js';
6
+ import { GraphModel } from './GraphModel.js';
7
+ import type { PhysicsEngine } from '../physics/PhysicsEngine.js';
8
+ import type { GraphData, LinkId, LinkOptions, NodeId, NodeOptions, NodeStateName } from './types.js';
9
+ /** Collaborators and hooks the editor needs from the main facade. */
10
+ export interface GraphEditorDeps {
11
+ model: GraphModel;
12
+ physics: PhysicsEngine;
13
+ events: Emitter;
14
+ resetAutoFit(): void;
15
+ invalidate(): void;
16
+ }
17
+ export declare class GraphEditor {
18
+ private readonly deps;
19
+ private linkCounter;
20
+ constructor(deps: GraphEditorDeps);
21
+ /** Adds one node. */
22
+ addNode(id: NodeId, options?: NodeOptions): void;
23
+ /** Adds many nodes in one call. */
24
+ addNodes(nodes: Array<NodeOptions & {
25
+ id: NodeId;
26
+ }>): void;
27
+ /** Links two nodes, reusing an existing link with the same auto id. */
28
+ link(source: NodeId, target: NodeId, options?: LinkOptions): void;
29
+ /** Adds many links in one call. */
30
+ addLinks(links: Array<LinkOptions & {
31
+ source: NodeId;
32
+ target: NodeId;
33
+ }>): void;
34
+ /** Replaces the entire graph with the supplied data payload. */
35
+ setData(data: GraphData): void;
36
+ /** Removes one node together with its links. */
37
+ removeNode(id: NodeId): boolean;
38
+ /** Removes one link by id. */
39
+ removeLink(id: LinkId): boolean;
40
+ /** Removes every node and link while keeping the current theme. */
41
+ clear(): void;
42
+ /** Moves a node to a world position. */
43
+ setNodePosition(id: NodeId | number, x: number, y: number): void;
44
+ /** Locks or unlocks a node in the solver. */
45
+ setNodeFixed(id: NodeId | number, fixed: boolean): void;
46
+ /** Assigns a visual state to a node. */
47
+ setNodeState(id: NodeId | number, state: NodeStateName): void;
48
+ /** Updates node appearance properties. */
49
+ setNodeAppearance(id: NodeId | number, options: NodeOptions): void;
50
+ /** Updates link appearance properties. */
51
+ setLinkAppearance(id: LinkId | number, options: LinkOptions): void;
52
+ /** Sets the node image and starts the asynchronous load. */
53
+ setNodeImage(id: NodeId | number, url: string | null, mode?: 'cover' | 'contain'): void;
54
+ /** Replaces the custom data object attached to a node. */
55
+ setNodeData(id: NodeId | number, data: Record<string, unknown>): void;
56
+ /** Replaces the custom data object attached to a link. */
57
+ setLinkData(id: LinkId | number, data: Record<string, unknown>): void;
58
+ /** Exports the current graph as a plain JSON friendly object. */
59
+ toJSON(): GraphData;
60
+ }
61
+ //# sourceMappingURL=GraphEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphEditor.d.ts","sourceRoot":"","sources":["../../src/core/GraphEditor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAErG,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,IAAI,IAAI,CAAC;IACrB,UAAU,IAAI,IAAI,CAAC;CACpB;AAED,qBAAa,WAAW;IAGV,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,WAAW,CAAK;gBAEK,IAAI,EAAE,eAAe;IAElD,qBAAqB;IACrB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI;IASpD,mCAAmC;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAQ1D,uEAAuE;IACvE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI;IAOrE,mCAAmC;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAU9E,gEAAgE;IAChE,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAQ9B,gDAAgD;IAChD,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAS/B,8BAA8B;IAC9B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAS/B,mEAAmE;IACnE,KAAK,IAAI,IAAI;IAOb,wCAAwC;IACxC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAShE,6CAA6C;IAC7C,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IASvD,wCAAwC;IACxC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI;IAQ7D,0CAA0C;IAC1C,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAQlE,0CAA0C;IAC1C,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAQlE,4DAA4D;IAC5D,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,GAAE,OAAO,GAAG,SAAmB,GAAG,IAAI;IAQhG,0DAA0D;IAC1D,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAWrE,0DAA0D;IAC1D,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAWrE,iEAAiE;IACjE,MAAM,IAAI,SAAS;CAcpB"}