@graphty/graphty-element 2.3.1 → 2.4.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.
- package/AGENTS.md +4 -3
- package/dist/ai.js +3 -3
- package/dist/catalog.js +28 -27
- package/dist/chunks/{AiManager-BBmGJbH4.js → AiManager-DNJCoeTO.js} +5 -5
- package/dist/chunks/{DataSource-OeN3NeyD.js → DataSource-xL3Yn0Pa.js} +72 -61
- package/dist/chunks/{GraphSession-Bef1AYw9.js → GraphSession-PFm2tJ_j.js} +2942 -2822
- package/dist/chunks/{GraphtyLogger-5KEttFUo.js → GraphtyLogger-kbOx2zq3.js} +170 -222
- package/dist/chunks/{NodeStyle-DKj7HjMJ.js → NodeStyle-CtmA7dXi.js} +16 -14
- package/dist/chunks/{VoiceInputAdapter-Dr9Gcmds.js → VoiceInputAdapter-CDNKQgUK.js} +1 -1
- package/dist/chunks/{XRPivotCameraController-BbfgZWpS.js → XRPivotCameraController-JdlLBcD7.js} +146 -134
- package/dist/chunks/{algorithms-CpX56sUB.js → algorithms-B87OPYw4.js} +780 -635
- package/dist/chunks/{capability-check-Blhb2aBB.js → capability-check-B2oYf_30.js} +1 -1
- package/dist/chunks/{detect-Cqwshr9a.js → detect-tuYQLJbT.js} +2 -2
- package/dist/chunks/{format-detection-BXGO1lSn.js → format-detection-BG6CMwPO.js} +1 -1
- package/dist/chunks/{index-C0mIoumR.js → index-6GDfNfwJ.js} +3185 -2731
- package/dist/chunks/{optionsFromZod-17lkrAJs.js → optionsFromZod-DHLLiX_8.js} +275 -267
- package/dist/chunks/{paletteRegistry-x7WOEKZY.js → paletteRegistry-jg9uS7wo.js} +72 -70
- package/dist/chunks/pluginRegistry-MaTIDh6l.js +238 -0
- package/dist/chunks/{registry-CSba5QGJ.js → registry-DQeq4B2K.js} +8 -8
- package/dist/chunks/{scales-BRwl51k8.js → scales-BXHmwPXC.js} +572 -399
- package/dist/chunks/{types-B7bX5c0K.js → types-C_c53VgR.js} +31 -26
- package/dist/commands.d.ts +4 -0
- package/dist/custom-elements.json +1 -1
- package/dist/extend.js +8 -8
- package/dist/graphty-catalog.json +245 -12
- package/dist/graphty.bundle.js +37843 -36551
- package/dist/graphty.js +69 -65
- package/dist/index.d.ts +3 -0
- package/dist/logging.js +2 -2
- package/dist/schema.d.ts +1 -1
- package/dist/schema.js +42 -40
- package/dist/session.js +6 -6
- package/dist/src/Edge.d.ts +4 -4
- package/dist/src/Graph.d.ts +79 -7
- package/dist/src/acceleration/AccelerationController.d.ts +20 -3
- package/dist/src/acceleration/registry.d.ts +3 -0
- package/dist/src/acceleration/types.d.ts +85 -0
- package/dist/src/algorithms/Algorithm.d.ts +13 -0
- package/dist/src/algorithms/KCoreAlgorithm.d.ts +26 -0
- package/dist/src/algorithms/LinkPredictionAlgorithm.d.ts +41 -0
- package/dist/src/cameras/InputUtils.d.ts +67 -0
- package/dist/src/cameras/XRInputHandler.d.ts +0 -8
- package/dist/src/catalog/algorithms.d.ts +5 -5
- package/dist/src/catalog/index.d.ts +2 -2
- package/dist/src/catalog/layouts.d.ts +7 -6
- package/dist/src/catalog/pluginRegistry.d.ts +62 -0
- package/dist/src/catalog/registry.d.ts +7 -0
- package/dist/src/catalog/types.d.ts +77 -6
- package/dist/src/config/EdgeStyle.d.ts +35 -0
- package/dist/src/config/index.d.ts +1 -1
- package/dist/src/data/DataSource.d.ts +1 -1
- package/dist/src/data/GEXFDataSource.d.ts +23 -0
- package/dist/src/errors/codes.d.ts +16 -1
- package/dist/src/events.d.ts +30 -0
- package/dist/src/graphty-element.d.ts +66 -26
- package/dist/src/layout/GridLayoutEngine.d.ts +37 -0
- package/dist/src/layout/LayoutEngine.d.ts +7 -7
- package/dist/src/layout/NGraphLayoutEngine.d.ts +2 -0
- package/dist/src/layout/RadialLayoutEngine.d.ts +37 -0
- package/dist/src/layout/SimulationLayoutEngine.d.ts +12 -0
- package/dist/src/managers/DataManager.d.ts +69 -2
- package/dist/src/managers/EventManager.d.ts +10 -4
- package/dist/src/managers/GraphContext.d.ts +2 -1
- package/dist/src/managers/LayoutManager.d.ts +30 -3
- package/dist/src/meshes/CustomLineRenderer.d.ts +11 -9
- package/dist/src/meshes/EdgeMesh.d.ts +18 -9
- package/dist/src/meshes/FilledArrowRenderer.d.ts +61 -23
- package/dist/src/meshes/MeshCache.d.ts +18 -0
- package/dist/src/meshes/NodeEffects.d.ts +16 -11
- package/dist/src/meshes/NodeMesh.d.ts +2 -2
- package/dist/src/meshes/PatternedLineRenderer.d.ts +5 -37
- package/dist/src/meshes/PerSceneMaterials.d.ts +49 -0
- package/dist/src/meshes/RichTextParser.d.ts +26 -0
- package/dist/src/meshes/RichTextRenderer.d.ts +0 -1
- package/dist/src/session/cost/estimate.d.ts +1 -1
- package/dist/src/session/layout.d.ts +3 -3
- package/dist/src/session/runs/RunsApi.d.ts +1 -1
- package/dist/src/session/styles/StylesApi.d.ts +6 -0
- package/dist/src/session/styles/intern.d.ts +26 -5
- package/dist/src/session/styles/repaint.d.ts +2 -1
- package/dist/src/session/types.d.ts +6 -6
- package/dist/src/xr/XRSessionManager.d.ts +1 -1
- package/dist/webgpu.d.ts +8 -0
- package/dist/webgpu.js +2 -2
- package/package.json +6 -6
- package/dist/chunks/GraphtyError-BwcnblTH.js +0 -132
|
@@ -69,7 +69,8 @@ export interface GraphContext {
|
|
|
69
69
|
*/
|
|
70
70
|
isRunning(): boolean;
|
|
71
71
|
/**
|
|
72
|
-
*
|
|
72
|
+
* Play or pause the layout on a consumer's behalf. A pause holds until `setRunning(true)`;
|
|
73
|
+
* the element's own restarts write `getLayoutManager().running`, which the pause refuses.
|
|
73
74
|
*/
|
|
74
75
|
setRunning(running: boolean): void;
|
|
75
76
|
/**
|
|
@@ -42,6 +42,13 @@ export declare class LayoutManager implements Manager {
|
|
|
42
42
|
private styles;
|
|
43
43
|
layoutEngine?: LayoutEngine;
|
|
44
44
|
private _running;
|
|
45
|
+
/**
|
|
46
|
+
* Set while a CONSUMER has paused the layout, through {@link LayoutManager.setPaused}. Nothing
|
|
47
|
+
* inside the element clears it: a load, a freeze, an accelerator attaching, a new layout or a
|
|
48
|
+
* drag may rebuild or place nodes, but their `running = true` is refused until the consumer
|
|
49
|
+
* resumes.
|
|
50
|
+
*/
|
|
51
|
+
private _paused;
|
|
45
52
|
/**
|
|
46
53
|
* Set when a layout was built over a graph with nothing in it, and the pre-steps it is
|
|
47
54
|
* configured with have therefore not been spent. See
|
|
@@ -68,8 +75,19 @@ export declare class LayoutManager implements Manager {
|
|
|
68
75
|
* again and the next frame moves nodes. Going true -> false only stops `step()` being
|
|
69
76
|
* called; batches already in flight land in the position array by themselves, nothing is
|
|
70
77
|
* disposed and nothing is released.
|
|
78
|
+
*
|
|
79
|
+
* While the consumer has paused the layout (see {@link LayoutManager.setPaused}) a `true` is
|
|
80
|
+
* ignored, so the element's own restarts cannot undo the pause.
|
|
71
81
|
*/
|
|
72
82
|
set running(value: boolean);
|
|
83
|
+
/**
|
|
84
|
+
* Pause or resume the layout on a consumer's behalf.
|
|
85
|
+
*
|
|
86
|
+
* A pause holds until the consumer resumes it: internal restarts are refused while it is set.
|
|
87
|
+
* Resuming runs the layout, and reheats a simulation that had settled.
|
|
88
|
+
* @param paused - True to pause, false to resume.
|
|
89
|
+
*/
|
|
90
|
+
setPaused(paused: boolean): void;
|
|
73
91
|
private graphContext;
|
|
74
92
|
/**
|
|
75
93
|
* The graph's acceleration controller, once a context has arrived. A manager built without a
|
|
@@ -134,7 +152,7 @@ export declare class LayoutManager implements Manager {
|
|
|
134
152
|
/**
|
|
135
153
|
* Internal method for setting layout - bypasses queue
|
|
136
154
|
* Used by operations that are already queued to prevent nested queueing
|
|
137
|
-
* @param
|
|
155
|
+
* @param layout - A registered engine name, or a catalogue layout id
|
|
138
156
|
* @param opts - Layout-specific options
|
|
139
157
|
*/
|
|
140
158
|
private _setLayoutInternal;
|
|
@@ -246,10 +264,18 @@ export declare class LayoutManager implements Manager {
|
|
|
246
264
|
*/
|
|
247
265
|
getNodePosition(node: Node): [number, number, number] | undefined;
|
|
248
266
|
/**
|
|
249
|
-
*
|
|
250
|
-
*
|
|
267
|
+
* Whether the layout engine has converged: the positions are final.
|
|
268
|
+
*
|
|
269
|
+
* A layout that was stopped part-way is NOT settled; it is {@link LayoutManager.isPaused}. A
|
|
270
|
+
* reader that only needs "positions are not moving right now" asks `!running || isSettled`.
|
|
271
|
+
* @returns True when the engine has converged, or when there is no engine.
|
|
251
272
|
*/
|
|
252
273
|
get isSettled(): boolean;
|
|
274
|
+
/**
|
|
275
|
+
* Whether the layout was stopped before it converged, so its positions are not final.
|
|
276
|
+
* @returns True when the layout is not running and has not settled.
|
|
277
|
+
*/
|
|
278
|
+
get isPaused(): boolean;
|
|
253
279
|
/**
|
|
254
280
|
* Get nodes from layout engine
|
|
255
281
|
* @returns Iterable of nodes managed by the layout engine
|
|
@@ -295,6 +321,7 @@ export declare class LayoutManager implements Manager {
|
|
|
295
321
|
layoutType: string | undefined;
|
|
296
322
|
isRunning: boolean;
|
|
297
323
|
isSettled: boolean;
|
|
324
|
+
isPaused: boolean;
|
|
298
325
|
nodeCount: number;
|
|
299
326
|
edgeCount: number;
|
|
300
327
|
};
|
|
@@ -34,19 +34,21 @@ interface CustomLineOptions {
|
|
|
34
34
|
*/
|
|
35
35
|
export declare class CustomLineRenderer {
|
|
36
36
|
private static shadersRegistered;
|
|
37
|
-
private static activeMaterials;
|
|
38
|
-
private static registeredScene;
|
|
39
37
|
/**
|
|
40
|
-
*
|
|
38
|
+
* Every line material, grouped by scene, each scene's group given that scene's render size
|
|
39
|
+
* once per frame. See {@link PerSceneMaterials} for the defect (issue #45).
|
|
41
40
|
*/
|
|
42
|
-
static
|
|
41
|
+
private static readonly resolutionTracked;
|
|
42
|
+
/**
|
|
43
|
+
* Number of line materials receiving per-frame resolution updates.
|
|
44
|
+
* @param scene - Count only this scene's materials; omit for every scene
|
|
45
|
+
* @returns Count of tracked materials
|
|
46
|
+
*/
|
|
47
|
+
static getActiveMaterialCount(scene?: Scene): number;
|
|
43
48
|
/**
|
|
44
|
-
* Register
|
|
45
|
-
* This callback updates ALL line materials at once, instead of having one callback per material.
|
|
46
|
-
* This dramatically improves performance when rendering many edges.
|
|
47
|
-
* @param scene - The Babylon.js scene to register the callback on
|
|
49
|
+
* Register custom line shaders
|
|
48
50
|
*/
|
|
49
|
-
|
|
51
|
+
static registerShaders(): void;
|
|
50
52
|
/**
|
|
51
53
|
* Calculate evenly-spaced dot positions along a line path
|
|
52
54
|
* @param points - Path points defining the line
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractMesh, type Scene, Vector3 } from "@babylonjs/core";
|
|
1
|
+
import { AbstractMesh, type InstancedMesh, type Scene, Vector3 } from "@babylonjs/core";
|
|
2
2
|
import type { EdgeStyleConfig } from "../config";
|
|
3
3
|
import type { MeshCache } from "./MeshCache";
|
|
4
4
|
import { PatternedLineMesh } from "./PatternedLineMesh";
|
|
@@ -80,26 +80,35 @@ export declare class EdgeMesh {
|
|
|
80
80
|
*
|
|
81
81
|
* In 2D mode, uses StandardMaterial with XY rotation.
|
|
82
82
|
* In 3D mode, uses shader-based billboard rendering.
|
|
83
|
+
*
|
|
84
|
+
* The head is an InstancedMesh of a batch its scene shares with every head of the same
|
|
85
|
+
* shape (and, where the material holds them, the same colour and opacity), so a graph's
|
|
86
|
+
* arrowheads cost a draw call per batch rather than per edge. See
|
|
87
|
+
* `FilledArrowRenderer.instanceOf`.
|
|
83
88
|
* @param _cache - MeshCache instance (currently unused, kept for API compatibility)
|
|
84
89
|
* @param _styleId - Style ID (currently unused, kept for API compatibility)
|
|
85
90
|
* @param options - Arrow head options including type, width, color, size, and opacity
|
|
86
91
|
* @param scene - Babylon.js scene
|
|
87
92
|
* @returns The created arrow mesh, or null if type is "none" or undefined
|
|
88
93
|
*/
|
|
89
|
-
static createArrowHead(_cache: MeshCache, _styleId: string, options: ArrowHeadOptions, scene: Scene):
|
|
94
|
+
static createArrowHead(_cache: MeshCache, _styleId: string, options: ArrowHeadOptions, scene: Scene): InstancedMesh | null;
|
|
90
95
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* lineDirection is set per-instance when creating thin instances.
|
|
94
|
-
* @param type - Arrow type (normal, inverted, diamond, etc.)
|
|
96
|
+
* A 3D sphere-dot arrowhead: an unlit sphere, batched by colour and opacity, sized by the
|
|
97
|
+
* instance's scale.
|
|
95
98
|
* @param length - Arrow length in world units
|
|
96
|
-
* @param _width - Arrow width in world units (reserved for future use)
|
|
97
99
|
* @param color - Arrow color as hex string
|
|
98
100
|
* @param opacity - Arrow opacity (0-1)
|
|
99
101
|
* @param scene - Babylon.js scene
|
|
100
|
-
* @returns
|
|
102
|
+
* @returns The sphere instance
|
|
103
|
+
*/
|
|
104
|
+
private static createSphereDot;
|
|
105
|
+
/**
|
|
106
|
+
* Build the normalized geometry of a billboarded arrow type (every filled type but sphere-dot).
|
|
107
|
+
* @param type - Arrow type (normal, inverted, diamond, etc.)
|
|
108
|
+
* @param scene - Babylon.js scene
|
|
109
|
+
* @returns The arrow's geometry, with no material
|
|
101
110
|
*/
|
|
102
|
-
private static
|
|
111
|
+
private static createArrowShape;
|
|
103
112
|
private static createStaticLine;
|
|
104
113
|
private static createAnimatedLine;
|
|
105
114
|
private static createAnimatedTexture;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "@babylonjs/core/Meshes/instancedMesh";
|
|
2
|
+
import { type AbstractMesh, InstancedMesh, Mesh, Scene, ShaderMaterial, Vector3 } from "@babylonjs/core";
|
|
2
3
|
export interface FilledArrowOptions {
|
|
3
4
|
size: number;
|
|
4
5
|
color: string;
|
|
@@ -18,16 +19,23 @@ export interface FilledArrowOptions {
|
|
|
18
19
|
*/
|
|
19
20
|
export declare class FilledArrowRenderer {
|
|
20
21
|
private static shadersRegistered;
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Every billboarding material, grouped by scene, each scene's group given that scene's
|
|
24
|
+
* camera position once per frame. See {@link PerSceneMaterials} for the defect (issue #45).
|
|
25
|
+
*/
|
|
26
|
+
private static readonly cameraTracked;
|
|
27
|
+
/**
|
|
28
|
+
* The arrowhead batches: per scene, one hidden source mesh per batch key. See
|
|
29
|
+
* {@link FilledArrowRenderer.instanceOf}.
|
|
30
|
+
*/
|
|
31
|
+
private static readonly batches;
|
|
23
32
|
/**
|
|
24
33
|
* Unregister a shader material so the per-frame camera-uniform walk stops visiting it.
|
|
25
34
|
*
|
|
26
35
|
* WHY THIS EXISTS -- the defect it repairs:
|
|
27
36
|
* {@link FilledArrowRenderer.applyShader} builds a fresh `ShaderMaterial` per mesh and
|
|
28
|
-
* adds it to
|
|
29
|
-
*
|
|
30
|
-
* path but cannot fire: `ShaderMaterial.setVector3` does not throw on a disposed
|
|
37
|
+
* adds it to the per-frame camera walk. Nothing used to remove entries. A `catch` inside
|
|
38
|
+
* that walk read as an eviction path but could not fire: `ShaderMaterial.setVector3` does not throw on a disposed
|
|
31
39
|
* material, it just records the value into a dead material's uniform cache. So every
|
|
32
40
|
* arrowhead and every pattern element ever built stayed in the walk for the lifetime of
|
|
33
41
|
* the page, and since both are rebuilt wholesale on every style change the walk grew
|
|
@@ -48,21 +56,15 @@ export declare class FilledArrowRenderer {
|
|
|
48
56
|
* Exists so the leak described on {@link FilledArrowRenderer.releaseMaterial} is
|
|
49
57
|
* OBSERVABLE from a test; it has no visible symptom until the frame rate has already
|
|
50
58
|
* collapsed, and asserting on frame time instead would be flaky.
|
|
59
|
+
* @param scene - Count only this scene's materials; omit for every scene
|
|
51
60
|
* @returns Count of tracked materials
|
|
52
61
|
* @public
|
|
53
62
|
*/
|
|
54
|
-
static getActiveMaterialCount(): number;
|
|
63
|
+
static getActiveMaterialCount(scene?: Scene): number;
|
|
55
64
|
/**
|
|
56
65
|
* Register filled arrow shaders
|
|
57
66
|
*/
|
|
58
67
|
static registerShaders(): void;
|
|
59
|
-
/**
|
|
60
|
-
* Register the shared camera position update callback
|
|
61
|
-
* This callback updates ALL arrow materials at once, instead of having one callback per material.
|
|
62
|
-
* This dramatically improves performance when rendering many arrows.
|
|
63
|
-
* @param scene - The Babylon.js scene to register the callback on
|
|
64
|
-
*/
|
|
65
|
-
private static registerCameraCallback;
|
|
66
68
|
/**
|
|
67
69
|
* Create a filled triangle arrow mesh
|
|
68
70
|
*
|
|
@@ -191,13 +193,11 @@ export declare class FilledArrowRenderer {
|
|
|
191
193
|
*
|
|
192
194
|
* This line used to read `mesh.alwaysSelectAsActiveMesh = true`, with a comment
|
|
193
195
|
* explaining that thin instances needed it because their base mesh was parked at
|
|
194
|
-
* y = -10000. Both halves of that comment are now false.
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
* the `MeshCache` template that genuinely does sit at y = -10000 holds NODE meshes, uses
|
|
200
|
-
* `InstancedMesh`, and never reaches this function. The flag's effect today is simply that
|
|
196
|
+
* y = -10000. Both halves of that comment are now false. This function is reached from
|
|
197
|
+
* `applyShader` (pattern elements, one mesh each) and from `createArrowInstance`, which
|
|
198
|
+
* calls it on each arrowhead INSTANCE -- positioned at the real arrow location by `Edge` --
|
|
199
|
+
* never on a parked template; and the `MeshCache` template that genuinely does sit at
|
|
200
|
+
* y = -10000 holds NODE meshes and never reaches this function. The flag's effect was that
|
|
201
201
|
* every mesh carrying this shader is submitted every frame regardless of where the camera
|
|
202
202
|
* is pointing -- which, at the mesh counts a dotted line used to reach, was thousands of
|
|
203
203
|
* pointless draw calls per frame.
|
|
@@ -230,10 +230,48 @@ export declare class FilledArrowRenderer {
|
|
|
230
230
|
/**
|
|
231
231
|
* Set the line direction for a filled arrow mesh
|
|
232
232
|
* This should be called every frame when the edge updates
|
|
233
|
-
* @param mesh - Filled arrow mesh
|
|
233
|
+
* @param mesh - Filled arrow mesh, or an arrowhead instance from {@link FilledArrowRenderer.createArrowInstance}
|
|
234
234
|
* @param direction - Line direction vector (normalized)
|
|
235
235
|
*/
|
|
236
|
-
static setLineDirection(mesh:
|
|
236
|
+
static setLineDirection(mesh: AbstractMesh, direction: Vector3): void;
|
|
237
|
+
/**
|
|
238
|
+
* Draw one arrowhead as an instance of its scene's batch for `key`, building the batch's
|
|
239
|
+
* hidden source mesh with `build` the first time the scene needs it.
|
|
240
|
+
*
|
|
241
|
+
* WHY -- issue #25: every arrowhead used to be its own `Mesh` with its own material, so N
|
|
242
|
+
* arrowheaded edges cost N draw calls a frame (and, through issue #27, O(N^2) to load). A
|
|
243
|
+
* batch is drawn in one call however many edges use it. Each instance keeps its own
|
|
244
|
+
* transform, and Babylon refills the per-instance buffers once per frame in one pass, so this
|
|
245
|
+
* does not bring back the per-edge buffer writes that made thin instances 35x slower.
|
|
246
|
+
*
|
|
247
|
+
* The source mesh goes when its last instance does, so a cleared graph leaves nothing in the
|
|
248
|
+
* scene, and the batches of one scene are never seen by another.
|
|
249
|
+
* @param scene - The scene the arrowhead is drawn in
|
|
250
|
+
* @param key - What the batch's heads have in common: shape, and whatever else lives on the material
|
|
251
|
+
* @param build - Builds the source mesh (with its material) for a new batch
|
|
252
|
+
* @returns The arrowhead: an instance of the batch's source mesh
|
|
253
|
+
*/
|
|
254
|
+
static instanceOf(scene: Scene, key: string, build: () => Mesh): InstancedMesh;
|
|
255
|
+
/**
|
|
256
|
+
* Draw one billboarded 3D arrowhead as an instance of its scene's batch for that shape and
|
|
257
|
+
* opacity. The direction, size and colour are the instance's own attributes, so edges of
|
|
258
|
+
* every colour and size share one draw call.
|
|
259
|
+
* @param shape - The arrow type, which names the batch's geometry
|
|
260
|
+
* @param createShape - Builds that geometry, for a new batch
|
|
261
|
+
* @param options - The head's size (world-space length), colour and opacity
|
|
262
|
+
* @param scene - Babylon.js scene
|
|
263
|
+
* @returns The arrowhead instance; point it with {@link FilledArrowRenderer.setLineDirection}
|
|
264
|
+
*/
|
|
265
|
+
static createArrowInstance(shape: string, createShape: () => Mesh, options: FilledArrowOptions, scene: Scene): InstancedMesh;
|
|
266
|
+
/**
|
|
267
|
+
* Give a batch's source mesh the billboard shader, reading direction, size and colour from
|
|
268
|
+
* instance attributes instead of uniforms.
|
|
269
|
+
* @param mesh - The batch's source mesh
|
|
270
|
+
* @param opacity - The opacity every head in the batch is drawn at
|
|
271
|
+
* @param scene - Babylon.js scene
|
|
272
|
+
* @returns The same mesh
|
|
273
|
+
*/
|
|
274
|
+
private static applyInstancedShader;
|
|
237
275
|
/**
|
|
238
276
|
* Create a 2D arrow mesh with flat StandardMaterial
|
|
239
277
|
*
|
|
@@ -26,6 +26,24 @@ export declare class MeshCache {
|
|
|
26
26
|
* Clear all cached meshes and reset statistics
|
|
27
27
|
*/
|
|
28
28
|
clear(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Dispose and forget every cached mesh that nothing is drawn from any more.
|
|
31
|
+
*
|
|
32
|
+
* Every source mesh is handed out only as instances, so one with no instances is a look no
|
|
33
|
+
* element has: a size a layer used to paint, a halo nobody is selected for. Without this the
|
|
34
|
+
* cache holds one mesh per look ever drawn, which grows with every edit to a size or a shape
|
|
35
|
+
* until the next dataset boundary. A name that is asked for again is simply built again.
|
|
36
|
+
*/
|
|
37
|
+
prune(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Dispose a source mesh and the material it was built with.
|
|
40
|
+
*
|
|
41
|
+
* Every creator handed to get() builds a fresh material for its mesh, so the material dies
|
|
42
|
+
* with it; `mesh.dispose()` alone would leave it in `scene.materials` for good. Textures are
|
|
43
|
+
* kept: node gradient textures are shared across materials per scene.
|
|
44
|
+
* @param mesh - The cached source mesh
|
|
45
|
+
*/
|
|
46
|
+
private static disposeSource;
|
|
29
47
|
/**
|
|
30
48
|
* Get the number of cached meshes
|
|
31
49
|
* @returns Count of cached meshes
|
|
@@ -83,13 +83,16 @@ export declare class NodeEffects {
|
|
|
83
83
|
* must not pay for it, so the only call site is the `effect.glow` branch of
|
|
84
84
|
* {@link NodeEffects.applyGlowEffect}; the removal branch deliberately does NOT create one.
|
|
85
85
|
*
|
|
86
|
+
* DISPOSED AGAIN WHEN NOTHING GLOWS, by {@link NodeEffects.syncGlowStrengths}. The inclusion
|
|
87
|
+
* list alone never says so: `node.glow` is a mesh channel, so a node that stops glowing moves
|
|
88
|
+
* to another source mesh and the old glowing source stays listed with no instances. The next
|
|
89
|
+
* glow recreates the layer through this method.
|
|
90
|
+
*
|
|
86
91
|
* `excludeByDefault: true` is a safety catch, not a tuning knob. Babylon's inclusion list
|
|
87
92
|
* means "only these" when it is non-empty and "no opinion" -- i.e. EVERY mesh in the scene --
|
|
88
|
-
* when it is empty (ThinGlowLayer.hasMesh).
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* failure to be worth one option: with this set, `_internalShouldRender` returns false while
|
|
92
|
-
* the list is empty, so an emptied layer renders nothing at all.
|
|
93
|
+
* when it is empty (ThinGlowLayer.hasMesh). With this set, `_internalShouldRender` returns
|
|
94
|
+
* false while the list is empty, so an emptied layer renders nothing rather than blooming
|
|
95
|
+
* the whole graph.
|
|
93
96
|
* @param scene - The Babylon.js scene
|
|
94
97
|
* @returns The glow layer for the scene
|
|
95
98
|
*/
|
|
@@ -142,6 +145,10 @@ export declare class NodeEffects {
|
|
|
142
145
|
* back to 0.1) leaves a mesh with no instances behind; counted, it would hold the layer at 100
|
|
143
146
|
* and round the live glow away in the 8-bit map. It keeps its entry, because a node that goes
|
|
144
147
|
* back to that strength reuses the cached mesh. A disposed mesh is dropped.
|
|
148
|
+
*
|
|
149
|
+
* When no glowing source mesh draws a node any more, the layer is disposed: it is a
|
|
150
|
+
* full-screen post-process that would otherwise render nothing every frame for the life of
|
|
151
|
+
* the scene. Every node mesh is an instance, so a source with no instances draws nothing.
|
|
145
152
|
* @param glowLayer - The scene's glow layer
|
|
146
153
|
* @param scene - The Babylon.js scene
|
|
147
154
|
*/
|
|
@@ -155,8 +162,8 @@ export declare class NodeEffects {
|
|
|
155
162
|
* with one outline configuration -- and resolving to it here would take the outline away from
|
|
156
163
|
* every sibling still on screen. That is the same reasoning `Node.dispose` records for glow,
|
|
157
164
|
* and it has the same consequence: for an instanced node this removes nothing, the source is
|
|
158
|
-
* freed when `MeshCache`
|
|
159
|
-
* Babylon's uniqueIds are monotonic per scene and never reused.
|
|
165
|
+
* freed when `MeshCache` prunes or clears it, and the layer's leftover uniqueId is inert
|
|
166
|
+
* because Babylon's uniqueIds are monotonic per scene and never reused.
|
|
160
167
|
* @param mesh - The mesh to remove from highlighting
|
|
161
168
|
*/
|
|
162
169
|
static removeFromHighlight(mesh: AbstractMesh): void;
|
|
@@ -178,10 +185,8 @@ export declare class NodeEffects {
|
|
|
178
185
|
* The colour map is keyed by mesh uniqueId, so it MUST die with the layer: leaving it behind
|
|
179
186
|
* would let a later mesh that happens to reuse a uniqueId inherit a dead style's glow colour.
|
|
180
187
|
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* than rebuilt. It exists so that whoever tears a scene down has one call for each layer this
|
|
184
|
-
* class can create, instead of discovering the glow layer only by leaking it.
|
|
188
|
+
* Called by {@link NodeEffects.syncGlowStrengths} once no node glows; the next glow
|
|
189
|
+
* recreates the layer lazily.
|
|
185
190
|
* @param scene - The Babylon.js scene
|
|
186
191
|
*/
|
|
187
192
|
static disposeGlowLayer(scene: Scene): void;
|
|
@@ -120,8 +120,8 @@ export declare class NodeMesh {
|
|
|
120
120
|
* provenance is invisible here, but unbounded allocation is not.
|
|
121
121
|
*
|
|
122
122
|
* The cache is a WeakMap keyed by scene, so the entries die with the scene and never leak
|
|
123
|
-
* across scenes or across tests. `MeshCache
|
|
124
|
-
*
|
|
123
|
+
* across scenes or across tests. `MeshCache` disposes a source mesh's material but never its
|
|
124
|
+
* textures, so a cached texture stays valid across a 2D/3D switch.
|
|
125
125
|
* @param gradient - The normalised gradient to paint
|
|
126
126
|
* @param scene - Babylon.js scene that will own the texture
|
|
127
127
|
* @returns The shared texture, or undefined if one cannot or should not be allocated
|
|
@@ -45,42 +45,16 @@ export declare const PATTERN_DEFINITIONS: Record<PatternType, PatternDefinition>
|
|
|
45
45
|
* Static utility class for creating mesh-based pattern geometries for line visualization
|
|
46
46
|
*/
|
|
47
47
|
export declare class PatternedLineRenderer {
|
|
48
|
-
private static activeMaterials;
|
|
49
|
-
private static cameraCallbackRegistered;
|
|
50
48
|
/**
|
|
51
|
-
*
|
|
49
|
+
* Stop a pattern material receiving per-frame camera updates.
|
|
52
50
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* `
|
|
57
|
-
* are iterated once per frame to push the camera position uniform. Nothing ever removed
|
|
58
|
-
* an entry: `PatternedLineMesh.dispose` disposed the mesh with Babylon's default
|
|
59
|
-
* arguments, which leaves the material alive, and the `catch` inside each per-frame walk
|
|
60
|
-
* that looks like an eviction path cannot fire, because `ShaderMaterial.setVector3` does
|
|
61
|
-
* not throw on a disposed material. The result was a per-frame loop that grew
|
|
62
|
-
* monotonically for the lifetime of the page: every change of line style, width or colour
|
|
63
|
-
* rebuilt every edge's meshes and left the previous generation's materials in the walk
|
|
64
|
-
* forever. That is a second, slower-burning half of the same halt the product owner
|
|
65
|
-
* reported ("I changed line style to dot and width to 1 and everything crawled to a halt").
|
|
66
|
-
*
|
|
67
|
-
* Removal must reach BOTH sets, which is why this delegates to
|
|
68
|
-
* {@link FilledArrowRenderer.releaseMaterial} as well as clearing its own.
|
|
51
|
+
* Every pattern element owns its own `ShaderMaterial`, built by
|
|
52
|
+
* `FilledArrowRenderer.applyShader`, which registers it in that renderer's per-scene camera
|
|
53
|
+
* walk (see `PerSceneMaterials`). Disposing the material ends the registration on its own;
|
|
54
|
+
* `PatternedLineMesh` calls this as well, eagerly, before it disposes one.
|
|
69
55
|
* @param material - The ShaderMaterial to stop tracking; passing an untracked material is a no-op
|
|
70
|
-
* @public
|
|
71
56
|
*/
|
|
72
57
|
static releaseMaterial(material: ShaderMaterial): void;
|
|
73
|
-
/**
|
|
74
|
-
* Number of pattern materials currently receiving per-frame camera updates.
|
|
75
|
-
*
|
|
76
|
-
* Exists so the material leak described on {@link PatternedLineRenderer.releaseMaterial}
|
|
77
|
-
* is OBSERVABLE from a test. The leak has no visible symptom until the frame rate has
|
|
78
|
-
* already collapsed, and the count is the only direct evidence that a disposed pattern
|
|
79
|
-
* line truly stopped costing anything; asserting on frame time instead would be flaky.
|
|
80
|
-
* @returns Count of tracked materials
|
|
81
|
-
* @public
|
|
82
|
-
*/
|
|
83
|
-
static getActiveMaterialCount(): number;
|
|
84
58
|
/**
|
|
85
59
|
* Create a PatternedLineMesh instance
|
|
86
60
|
* Note: start/end are already adjusted by Edge.transformArrowCap() for node surfaces and arrows
|
|
@@ -233,11 +207,5 @@ export declare class PatternedLineRenderer {
|
|
|
233
207
|
* @returns The default shape type for the pattern
|
|
234
208
|
*/
|
|
235
209
|
private static getDefaultShapeType;
|
|
236
|
-
/**
|
|
237
|
-
* Register camera position update callback
|
|
238
|
-
* Updates all pattern materials in one batch per frame
|
|
239
|
-
* @param scene - Babylon.js scene
|
|
240
|
-
*/
|
|
241
|
-
private static registerCameraCallback;
|
|
242
210
|
}
|
|
243
211
|
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Scene, ShaderMaterial } from "@babylonjs/core";
|
|
2
|
+
/**
|
|
3
|
+
* Called once per frame for one scene, with the shader materials that scene draws.
|
|
4
|
+
*/
|
|
5
|
+
type RefreshFn = (scene: Scene, materials: Iterable<ShaderMaterial>) => void;
|
|
6
|
+
/**
|
|
7
|
+
* Shader materials grouped by the scene that draws them, each group refreshed by an observer on
|
|
8
|
+
* its OWN scene, just before that scene renders.
|
|
9
|
+
*
|
|
10
|
+
* WHY THIS EXISTS -- the defect it repairs (issue #45): the line, arrowhead and pattern renderers
|
|
11
|
+
* push per-frame uniforms (the render resolution, the camera position) into their shader
|
|
12
|
+
* materials. Each kept those materials in one static set shared by every `<graphty-element>` on
|
|
13
|
+
* the page, and registered its per-frame observer either once per page (on whichever scene came
|
|
14
|
+
* first) or once per scene switch. So a second element's arrowheads billboarded towards the
|
|
15
|
+
* FIRST element's camera, an element created after the first was disposed got no camera
|
|
16
|
+
* position at all, and each scene's observer walked every other scene's materials.
|
|
17
|
+
*
|
|
18
|
+
* Here each scene gets its own set and its own observer, which reads that scene's own engine and
|
|
19
|
+
* camera. A material leaves its set when it is disposed, and a scene's set and observer go when
|
|
20
|
+
* the scene is disposed, so nothing outlives the element that drew it.
|
|
21
|
+
*/
|
|
22
|
+
export declare class PerSceneMaterials {
|
|
23
|
+
private readonly refresh;
|
|
24
|
+
private readonly scenes;
|
|
25
|
+
/**
|
|
26
|
+
* Track materials whose uniforms `refresh` writes once per frame.
|
|
27
|
+
* @param refresh - Writes the per-frame uniforms of one scene's materials
|
|
28
|
+
*/
|
|
29
|
+
constructor(refresh: RefreshFn);
|
|
30
|
+
/**
|
|
31
|
+
* Track a material under its own scene and give it its uniforms now, so it draws correctly
|
|
32
|
+
* even on the first frame.
|
|
33
|
+
* @param material - The shader material to keep refreshed
|
|
34
|
+
*/
|
|
35
|
+
add(material: ShaderMaterial): void;
|
|
36
|
+
/**
|
|
37
|
+
* Stop refreshing a material. Disposing the material does this on its own.
|
|
38
|
+
* @param material - The material to forget; an untracked material is a no-op
|
|
39
|
+
*/
|
|
40
|
+
delete(material: ShaderMaterial): void;
|
|
41
|
+
/**
|
|
42
|
+
* Number of tracked materials.
|
|
43
|
+
* @param scene - Count only this scene's materials; omit for every scene
|
|
44
|
+
* @returns How many materials are refreshed each frame
|
|
45
|
+
*/
|
|
46
|
+
count(scene?: Scene): number;
|
|
47
|
+
private materialsOf;
|
|
48
|
+
}
|
|
49
|
+
export {};
|
|
@@ -35,3 +35,29 @@ export declare class RichTextParser {
|
|
|
35
35
|
totalHeight: number;
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Measures one line of segments from the font's own metrics.
|
|
40
|
+
*
|
|
41
|
+
* The line's ink height is the tallest ascent plus the deepest descent over its segments, each
|
|
42
|
+
* the larger of the font box (`fontBoundingBoxAscent` / `fontBoundingBoxDescent`) and the actual
|
|
43
|
+
* glyph box, plus the outline on both sides. The line box is that height times `lineHeight`, and
|
|
44
|
+
* the extra leading is split evenly above and below, as CSS does. The label's panel height and
|
|
45
|
+
* the renderer's line advance both come from here, so they cannot disagree.
|
|
46
|
+
* @param ctx - Canvas rendering context for measurement
|
|
47
|
+
* @param lineSegments - The segments of one line
|
|
48
|
+
* @param options - Layout options
|
|
49
|
+
* @param options.lineHeight - Line height multiplier
|
|
50
|
+
* @param options.textOutline - Whether text outline is enabled
|
|
51
|
+
* @param options.textOutlineWidth - Width of text outline
|
|
52
|
+
* @returns The line's advance width, its line box height, and the distance from the top of the
|
|
53
|
+
* line box to the alphabetic baseline
|
|
54
|
+
*/
|
|
55
|
+
export declare function measureLine(ctx: CanvasRenderingContext2D, lineSegments: TextSegment[], options: {
|
|
56
|
+
lineHeight: number;
|
|
57
|
+
textOutline: boolean;
|
|
58
|
+
textOutlineWidth: number;
|
|
59
|
+
}): {
|
|
60
|
+
width: number;
|
|
61
|
+
lineBox: number;
|
|
62
|
+
baseline: number;
|
|
63
|
+
};
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* Nothing here reaches Babylon.js, Lit or the DOM: an estimate is arithmetic over plain data,
|
|
28
28
|
* published from the Node-safe `./session` entry point.
|
|
29
29
|
*/
|
|
30
|
-
import type
|
|
30
|
+
import { type AlgorithmDescriptor, type AlgorithmKey, type CostClass, type Scope } from "../../catalog/types";
|
|
31
31
|
import { GraphtyError } from "../../errors/GraphtyError";
|
|
32
32
|
import type { GraphStatistics } from "../types";
|
|
33
33
|
/**
|
|
@@ -29,8 +29,8 @@ export interface LayoutRecommendation {
|
|
|
29
29
|
* The arrangement, exactly as `catalog.layouts()` publishes it.
|
|
30
30
|
*
|
|
31
31
|
* `layout.id` is the public arrangement name -- `"force"`, `"circular"` -- and `layout.engine`
|
|
32
|
-
* is the registered engine
|
|
33
|
-
*
|
|
32
|
+
* is the registered engine that runs it by default. `setLayout` takes either, so a consumer
|
|
33
|
+
* acts on the id: `element.setLayout(recommendation.layout.id)`.
|
|
34
34
|
*/
|
|
35
35
|
readonly layout: LayoutDescriptor;
|
|
36
36
|
/** Why this arrangement suits this graph, in a sentence a consumer can show a reader. */
|
|
@@ -80,7 +80,7 @@ export interface LayoutRecommendationOptions {
|
|
|
80
80
|
* });
|
|
81
81
|
*
|
|
82
82
|
* if (advice !== undefined) {
|
|
83
|
-
* await element.setLayout(advice.layout.
|
|
83
|
+
* await element.setLayout(advice.layout.id);
|
|
84
84
|
* }
|
|
85
85
|
* ```
|
|
86
86
|
*/
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* structural view of `OperationQueueManager` narrow enough that the session never imports the
|
|
19
19
|
* renderer's manager to talk to it.
|
|
20
20
|
*/
|
|
21
|
-
import type
|
|
21
|
+
import { type AlgorithmDescriptor, type LayerId, type RunId, type Scope } from "../../catalog/types";
|
|
22
22
|
import type { AutoApplyPolicy } from "../styles/autoApply";
|
|
23
23
|
import { type RunExecutor, type RunQueueContext } from "./Run";
|
|
24
24
|
import { type Caveats, type EngineVersions, type ResolvedScope, type RunChange, type RunsApi } from "./types";
|
|
@@ -493,6 +493,12 @@ export interface StylesSources {
|
|
|
493
493
|
* @param change - What changed, and how much was painted.
|
|
494
494
|
*/
|
|
495
495
|
readonly onChange?: (change: StyleChange) => void;
|
|
496
|
+
/**
|
|
497
|
+
* Aborted when the session holding the stack is disposed. Every edit still pending is
|
|
498
|
+
* cancelled with it, so a caller awaiting one gets an `AbortError` rather than waiting for
|
|
499
|
+
* ever, and an edit issued afterwards is cancelled before it starts.
|
|
500
|
+
*/
|
|
501
|
+
readonly disposed?: AbortSignal;
|
|
496
502
|
}
|
|
497
503
|
/**
|
|
498
504
|
* What a highlight paints when its caller names no style.
|