vortx-gl 1.0.4 → 1.0.27

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 (53) hide show
  1. package/dist/components/DatasetSelector.d.ts +19 -0
  2. package/dist/components/FPSMonitor.d.ts +2 -0
  3. package/dist/components/GraphCanvas.d.ts +109 -0
  4. package/dist/components/LayoutControls.d.ts +18 -0
  5. package/dist/components/LucideIcon.d.ts +10 -0
  6. package/dist/components/PropertyPanel.d.ts +28 -0
  7. package/dist/components/RadialMenu.d.ts +33 -0
  8. package/dist/components/SearchBar.d.ts +12 -0
  9. package/dist/components/ViewControls.d.ts +18 -0
  10. package/dist/engine/Minimap.d.ts +25 -0
  11. package/dist/engine/api/adapter.d.ts +35 -0
  12. package/dist/engine/api/index.d.ts +2 -0
  13. package/dist/engine/api/types.d.ts +86 -0
  14. package/dist/engine/config.d.ts +117 -0
  15. package/dist/engine/core/Camera.d.ts +34 -0
  16. package/dist/engine/core/ComboStore.d.ts +23 -0
  17. package/dist/engine/core/EdgeStore.d.ts +37 -0
  18. package/dist/engine/core/NodeStore.d.ts +34 -0
  19. package/dist/engine/core/context.d.ts +20 -0
  20. package/dist/engine/events.d.ts +0 -13
  21. package/dist/engine/gpu/GpuBufferManager.d.ts +39 -0
  22. package/dist/engine/interaction/GroupInteraction.d.ts +40 -0
  23. package/dist/engine/interaction.d.ts +7 -2
  24. package/dist/engine/overlay/ComboRenderer.d.ts +25 -0
  25. package/dist/engine/overlay/EdgeRenderer.d.ts +32 -0
  26. package/dist/engine/overlay/NodeRenderer.d.ts +52 -0
  27. package/dist/engine/overlay/OverlayManager.d.ts +38 -0
  28. package/dist/engine/overlay/SharedOverlayState.d.ts +47 -0
  29. package/dist/engine/overlay/effects.d.ts +15 -0
  30. package/dist/engine/overlay/index.d.ts +2 -0
  31. package/dist/engine/overlay/shapes.d.ts +7 -0
  32. package/dist/engine/overlay/text.d.ts +15 -0
  33. package/dist/engine/picking.d.ts +14 -3
  34. package/dist/engine/renderConstants.d.ts +13 -0
  35. package/dist/engine/renderer.d.ts +185 -432
  36. package/dist/engine/shaders/edge.glsl.d.ts +2 -0
  37. package/dist/engine/shaders/node.glsl.d.ts +2 -0
  38. package/dist/engine/shaders.d.ts +2 -4
  39. package/dist/engine/spatialIndex.d.ts +32 -0
  40. package/dist/engine/types.d.ts +472 -9
  41. package/dist/engine/utils/pointSize.d.ts +23 -0
  42. package/dist/engine/utils/styleResolver.d.ts +163 -0
  43. package/dist/index.d.ts +11 -5
  44. package/dist/vortx-gl.css +1206 -1
  45. package/dist/vortx-gl.es.js +3718 -1
  46. package/dist/vortx-gl.umd.js +3706 -1
  47. package/package.json +27 -19
  48. package/dist/assets/layout.worker-CBxeMMC3.js +0 -1
  49. package/dist/engine/overlay.d.ts +0 -80
  50. package/dist/favicon.ico +0 -0
  51. package/dist/logo.png +0 -0
  52. package/dist/vite.svg +0 -1
  53. package/examples/vue-example.vue +0 -80
@@ -0,0 +1,20 @@
1
+ import { EventEmitter } from '../events';
2
+ import { InteractionState } from '../types';
3
+ import { NodeStore } from './NodeStore';
4
+ import { EdgeStore } from './EdgeStore';
5
+ import { ComboStore } from './ComboStore';
6
+ import { Camera } from './Camera';
7
+ import { GpuBufferManager } from '../gpu/GpuBufferManager';
8
+ export interface EngineContext {
9
+ gl: WebGL2RenderingContext;
10
+ canvas: HTMLCanvasElement;
11
+ emitter: EventEmitter;
12
+ requestRender: () => void;
13
+ nodes: NodeStore;
14
+ edges: EdgeStore;
15
+ combos: ComboStore;
16
+ camera: Camera;
17
+ gpu: GpuBufferManager;
18
+ state: InteractionState;
19
+ theme: "dark" | "light";
20
+ }
@@ -9,21 +9,8 @@ export type EventHandler<T = unknown> = (data: T) => void;
9
9
  */
10
10
  export declare class EventEmitter {
11
11
  private listeners;
12
- /**
13
- * Subscribe to an event.
14
- * @param event The event unique key.
15
- * @param handler Function to execute when the event fires.
16
- * @returns An unsubscribe function for convenient cleanup.
17
- */
18
12
  on<T = unknown>(event: string, handler: EventHandler<T>): () => void;
19
- /**
20
- * Unsubscribe a specific handler from an event.
21
- */
22
13
  off<T = unknown>(event: string, handler: EventHandler<T>): void;
23
- /**
24
- * @internal
25
- * Fire an event to all current subscribers.
26
- */
27
14
  emit<T = unknown>(event: string, data?: T): void;
28
15
  /**
29
16
  * Remove all handlers for a specific event, or all events if no name given.
@@ -0,0 +1,39 @@
1
+ export declare class GpuBufferManager {
2
+ program: WebGLProgram | null;
3
+ edgeProgram: WebGLProgram | null;
4
+ vao: WebGLVertexArrayObject | null;
5
+ edgeVao: WebGLVertexArrayObject | null;
6
+ positionBuffer: WebGLBuffer | null;
7
+ colorBuffer: WebGLBuffer | null;
8
+ idBuffer: WebGLBuffer | null;
9
+ shapeBuffer: WebGLBuffer | null;
10
+ sizeBuffer: WebGLBuffer | null;
11
+ targetPositionBuffer: WebGLBuffer | null;
12
+ edgeIndexBuffer: WebGLBuffer | null;
13
+ pickingFramebuffer: WebGLFramebuffer | null;
14
+ pickingTexture: WebGLTexture | null;
15
+ uMatrixLoc: WebGLUniformLocation | null;
16
+ uPointSizeLoc: WebGLUniformLocation | null;
17
+ uPointSizeMaxLoc: WebGLUniformLocation | null;
18
+ uPickingModeLoc: WebGLUniformLocation | null;
19
+ uEdgeMatrixLoc: WebGLUniformLocation | null;
20
+ uEdgeColorLoc: WebGLUniformLocation | null;
21
+ uTransitionProgressLoc: WebGLUniformLocation | null;
22
+ uEdgeTransitionProgressLoc: WebGLUniformLocation | null;
23
+ private gl;
24
+ private canvas;
25
+ constructor(gl: WebGL2RenderingContext, canvas: HTMLCanvasElement);
26
+ init(): void;
27
+ private initShaders;
28
+ private initBuffers;
29
+ initPicking(): void;
30
+ private createProgram;
31
+ reallocateNodeBuffers(positions: Float32Array, colorData: Float32Array, idData: Float32Array, shapeData: Float32Array, sizeData?: Float32Array): void;
32
+ syncNode(idx: number, positions: Float32Array, colorData: Float32Array, idData: Float32Array, shapeData: Float32Array, sizeData?: Float32Array): void;
33
+ /** Push a single node's size multiplier to the GPU. Used by updateNode. */
34
+ syncSize(idx: number, sizeData: Float32Array): void;
35
+ syncEdges(indices: Uint32Array | null): void;
36
+ syncPositions(positions: Float32Array): void;
37
+ syncAllPositions(positions: Float32Array): void;
38
+ destroy(): void;
39
+ }
@@ -0,0 +1,40 @@
1
+ import { vec2 } from 'gl-matrix';
2
+ import { GraphEngine } from '../renderer';
3
+ import { HUDAction } from '../overlay';
4
+ /**
5
+ * GroupInteraction manages all combo/group related interactions.
6
+ *
7
+ * Behavior design:
8
+ * - Click on combo HUD: Toggle collapse/expand or enter Edit Mode.
9
+ * - Edit Mode: Highlights the group and selects all its members.
10
+ * - Drag nodes INTO a group hull: Add nodes to that group.
11
+ * - Drag nodes OUT of a group hull: Remove nodes from that group.
12
+ * - Click on combo hull: Drag the entire group.
13
+ */
14
+ export declare class GroupInteraction {
15
+ private engine;
16
+ private canvas;
17
+ private _lastDropPickTime;
18
+ constructor(engine: GraphEngine, canvas: HTMLCanvasElement);
19
+ /**
20
+ * Handles HUD button actions (expand/collapse, edit).
21
+ * Returns true if handled — caller should return early.
22
+ */
23
+ handleHUDAction(hudAction: HUDAction): boolean;
24
+ /**
25
+ * Throttled drop-target highlight during node dragging.
26
+ * Shows orange feedback when dragging over a group.
27
+ */
28
+ handleDragOver(mouseX: number, mouseY: number): void;
29
+ /**
30
+ * Called on mouse/touch-up after dragging nodes.
31
+ * Membership is updated based on where the nodes were dropped.
32
+ */
33
+ handleDrop(mouseX: number, mouseY: number): void;
34
+ /**
35
+ * Moves the selected combo by the world-space delta from last mouse position.
36
+ */
37
+ handleGroupDrag(mouseX: number, mouseY: number, lastMouse: vec2): void;
38
+ /** Exits edit mode and clears selection. Call when clicking on empty space. */
39
+ exitEditMode(): void;
40
+ }
@@ -1,9 +1,11 @@
1
- import type { GraphEngine } from "./renderer";
1
+ import { GraphEngine } from './renderer';
2
2
  export declare class InteractionManager {
3
3
  private lastMouse;
4
4
  private isPanning;
5
+ private isDraggingCombo;
5
6
  private engine;
6
7
  private canvas;
8
+ private groups;
7
9
  private lastTouchDistance;
8
10
  private lastTouchMidpoint;
9
11
  private isTouching;
@@ -11,9 +13,12 @@ export declare class InteractionManager {
11
13
  private touchStartPos;
12
14
  private longPressTimer;
13
15
  private isLongPress;
14
- private isDraggingCombo;
16
+ private lastPickTime;
17
+ private _zoomSettleTimer;
18
+ private _disposers;
15
19
  constructor(engine: GraphEngine, canvas: HTMLCanvasElement);
16
20
  private setupListeners;
21
+ destroy(): void;
17
22
  private handleMouseDown;
18
23
  private handleMouseMove;
19
24
  private handleMouseUp;
@@ -0,0 +1,25 @@
1
+ import { mat3 } from 'gl-matrix';
2
+ import { Combo } from '../types';
3
+ import { SharedOverlayState } from './SharedOverlayState';
4
+ export interface HUDAction {
5
+ comboId: string;
6
+ action: "expand" | "edit" | "delete";
7
+ }
8
+ /**
9
+ * Renders combo (group) hulls, their summary circles when collapsed, and
10
+ * the floating HUD strip used to expand/edit each one.
11
+ *
12
+ * Owns the `hudRects` map so HUD hit-testing can stay co-located with
13
+ * the drawing code that produced the rectangles.
14
+ */
15
+ export declare class ComboRenderer {
16
+ private hudRects;
17
+ private state;
18
+ constructor(state: SharedOverlayState);
19
+ /** Hit-test the rendered HUD strip. Returns the action under the cursor, or null. */
20
+ pickHUDAction(mouseX: number, mouseY: number): HUDAction | null;
21
+ draw(combos: Map<string, Combo>, positions: Float32Array, nodeCount: number, viewMatrix: mat3, zoom: number, selectedComboId: string | null, dropTargetId: string | null, editingComboId: string | null, theme: string, dpr: number): void;
22
+ private drawCollapsedCombo;
23
+ private drawExpandedCombo;
24
+ private drawGroupHUD;
25
+ }
@@ -0,0 +1,32 @@
1
+ import { mat3 } from 'gl-matrix';
2
+ import { NodeMetadata, EdgeMetadata, PhantomEdge } from '../types';
3
+ import { SharedOverlayState } from './SharedOverlayState';
4
+ /**
5
+ * Renders custom edges (when overriding the GPU edge buffer), edge labels,
6
+ * arrowheads, hover/selected highlights, and the drag-to-create phantom edge.
7
+ *
8
+ * Owns the small adjacency cache used by the hover pass so we don't rescan
9
+ * the full edge list every frame.
10
+ */
11
+ export declare class EdgeRenderer {
12
+ private hoverNeighborCache;
13
+ private hoverCachedNodeId;
14
+ private hoverCachedEdgeCount;
15
+ private state;
16
+ constructor(state: SharedOverlayState);
17
+ drawHighlight(u: number, v: number, edgeId: string, positions: Float32Array, viewMatrix: mat3, dpr: number, nodeMetadata: Map<number, NodeMetadata>, edgeMetadata: Map<string, EdgeMetadata>, pointSize: number): void;
18
+ drawPhantom(phantom: PhantomEdge, positions: Float32Array, viewMatrix: mat3, dpr: number): void;
19
+ /**
20
+ * Draws every edge connected to `hoveredId` in the secondary highlight color.
21
+ * Adjacency list is cached and only rebuilt when the hovered node or edge
22
+ * topology changes — a major win on high-degree nodes.
23
+ */
24
+ drawHoverHighlight(hoveredId: number, indices: Uint32Array, count: number, theme: "dark" | "light", dpr: number, nodeMetadata: Map<number, NodeMetadata>, pointSize: number): void;
25
+ /**
26
+ * Draws edges that opt into custom styling (color, width, curvature, dash).
27
+ * Plain edges keep using the GPU pipeline.
28
+ */
29
+ drawCustomEdges(indices: Uint32Array, count: number, edgeMetadata: Map<string, EdgeMetadata>, edgeIndexToId: string[], theme: string, dpr: number, nodeMetadata: Map<number, NodeMetadata>, pointSize: number): void;
30
+ drawLabels(indices: Uint32Array, count: number, edgeMetadata: Map<string, EdgeMetadata>, edgeIndexToId: string[], theme: "dark" | "light", dpr: number, zoom: number, nodeMetadata: Map<number, NodeMetadata>, pointSize: number, defaultLabelMinZoom?: number, defaultLabelMaxZoom?: number): void;
31
+ drawArrows(indices: Uint32Array, count: number, edgeMetadata: Map<string, EdgeMetadata>, edgeIndexToId: string[], theme: string, dpr: number, zoom: number, nodeMetadata: Map<number, NodeMetadata>, pointSize: number): void;
32
+ }
@@ -0,0 +1,52 @@
1
+ import { mat3 } from 'gl-matrix';
2
+ import { NodeMetadata } from '../types';
3
+ import { SharedOverlayState } from './SharedOverlayState';
4
+ /**
5
+ * Draws everything that lives on a node: selection halos, shape borders,
6
+ * icons, labels, badges, and lock indicators.
7
+ */
8
+ export declare class NodeRenderer {
9
+ private state;
10
+ constructor(state: SharedOverlayState);
11
+ /**
12
+ * Selection ring stroked just outside each selected node. Off-screen
13
+ * selections get a small directional ping.
14
+ */
15
+ drawHighlights(ids: Set<number>, count: number, positions: Float32Array, viewMatrix: mat3, pointSize: number, dpr: number, hiddenNodes: Set<number>, shapeData?: Float32Array, metadata?: Map<number, NodeMetadata>): void;
16
+ /**
17
+ * Re-fills each selected node with its `colorOnSelect` (when set). Must run
18
+ * AFTER `punchOutNodes` and BEFORE `drawLabels` so the icon stays on top.
19
+ */
20
+ drawSelectionFills(ids: Set<number>, count: number, metadata: Map<number, NodeMetadata>, pointSize: number, hiddenNodes: Set<number>, shapeData?: Float32Array): void;
21
+ /**
22
+ * Two offset shadow circles behind any node carrying the "nodeGroup" class,
23
+ * conveying that the node represents multiple collapsed entities.
24
+ */
25
+ drawGroupStackShadows(_count: number, metadata: Map<number, NodeMetadata>, pointSize: number, dpr: number, colorData: Float32Array): void;
26
+ /**
27
+ * Dark count badge top-right of every nodeGroup-classed node, showing
28
+ * `metadata.groupCount`. Skipped when groupCount is undefined or zero.
29
+ */
30
+ drawGroupBadges(_count: number, metadata: Map<number, NodeMetadata>, pointSize: number, dpr: number): void;
31
+ /**
32
+ * Dark expand-button (+) top-right of every nodeGroup-classed node.
33
+ */
34
+ drawExpandButtons(_count: number, metadata: Map<number, NodeMetadata>, pointSize: number, dpr: number): void;
35
+ /**
36
+ * Draws a thin shape outline + clipped icon/image for each visible node, then
37
+ * places its label according to alignment metadata. Caps total drawn nodes
38
+ * at `maxLabels` so very dense graphs don't tank the frame.
39
+ */
40
+ drawLabels(count: number, metadata: Map<number, NodeMetadata>, theme: "dark" | "light", dpr: number, pointSize: number, zoom: number, lockedNodes: Set<number>, shapeData?: Float32Array, defaultLabelMinZoom?: number, defaultLabelMaxZoom?: number, hoveredNodeId?: number | null, priorityNodeIds?: Set<number>, colorData?: Float32Array): void;
41
+ private drawLabelLoop;
42
+ /** Draws round badges at the four corners around a node circle. */
43
+ drawBadges(_count: number, metadata: Map<number, NodeMetadata>, dpr: number, pointSize: number, zoom: number): void;
44
+ /**
45
+ * Punches transparent holes where each node's circle sits, so that overlay
46
+ * elements drawn earlier (edge labels, arrows) are visually clipped behind
47
+ * the WebGL-rendered node beneath them.
48
+ */
49
+ punchOutNodes(_count: number, metadata: Map<number, NodeMetadata>, pointSize: number): void;
50
+ private drawNodeIcon;
51
+ private drawLockIcon;
52
+ }
@@ -0,0 +1,38 @@
1
+ import { OverlayRenderParams } from '../types';
2
+ import { HUDAction } from './ComboRenderer';
3
+ /**
4
+ * Top-level Canvas2D overlay coordinator.
5
+ *
6
+ * Responsibilities are kept narrow:
7
+ * - own the shared scratch state + projection cache
8
+ * - compute viewport bounds and pre-project visible nodes
9
+ * - dispatch each render phase to a focused sub-renderer
10
+ *
11
+ * All actual drawing lives in ComboRenderer / NodeRenderer / EdgeRenderer
12
+ * and the small free-function modules in this directory.
13
+ */
14
+ export declare class OverlayManager {
15
+ private state;
16
+ private combos;
17
+ private nodes;
18
+ private edges;
19
+ private invViewScratch;
20
+ private tlScratch;
21
+ private brScratch;
22
+ private vMinX;
23
+ private vMaxX;
24
+ private vMinY;
25
+ private vMaxY;
26
+ private wasProjecting;
27
+ constructor(canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D);
28
+ /** Fast clear for animation frames — skips all drawing work. */
29
+ clearOnly(): void;
30
+ /** Hit-test the combo HUD strip (delegates to ComboRenderer). */
31
+ pickHUDAction(mouseX: number, mouseY: number): HUDAction | null;
32
+ render(params: OverlayRenderParams): void;
33
+ /**
34
+ * Walks every node, marking culled ones with NaN in `projectedCache` and
35
+ * filling the rest with screen-space coords.
36
+ */
37
+ private projectVisibleNodes;
38
+ }
@@ -0,0 +1,47 @@
1
+ import { mat3, vec2, vec3 } from 'gl-matrix';
2
+ /**
3
+ * Shared mutable state passed to every overlay sub-renderer.
4
+ *
5
+ * Owns the projection cache, scratch vectors, and `project()` helper so that
6
+ * sub-renderers can avoid re-allocating per frame and stay aligned on a single
7
+ * world→screen mapping.
8
+ */
9
+ export declare class SharedOverlayState {
10
+ canvas: HTMLCanvasElement;
11
+ ctx: CanvasRenderingContext2D;
12
+ /** Screen-space (x,y) for every node, indexed by node id. NaN means culled. */
13
+ projectedCache: Float32Array<ArrayBuffer>;
14
+ /** Pre-built [0..count] index array, reused for label iteration. */
15
+ nodeIndices: Int32Array<ArrayBuffer>;
16
+ /**
17
+ * Subset of nodeIndices whose projected coords fall inside the canvas
18
+ * (plus a small margin). Built once per frame in OverlayManager.render
19
+ * after projection. Per-node overlay passes (punchOutNodes, drawLabels,
20
+ * drawBadges, drawGroupBadges, drawExpandButtons) iterate THIS instead
21
+ * of nodeIndices so they walk ~visible-count entries instead of N.
22
+ *
23
+ * On a 100K-node graph with ~500 nodes visible, this turns O(N)
24
+ * iterations per pass into O(visible) — typically 10–100× faster per
25
+ * Canvas2D pass during pan/zoom.
26
+ */
27
+ visibleNodeIndices: Int32Array<ArrayBuffer>;
28
+ /** Number of valid entries at the start of `visibleNodeIndices`. */
29
+ visibleNodeCount: number;
30
+ posScratch: vec3;
31
+ spScratch: vec2;
32
+ s1Scratch: vec2;
33
+ s2Scratch: vec2;
34
+ maxLabelsPerFrame: number;
35
+ smallGraphThreshold: number;
36
+ viewportCullMargin: number;
37
+ /** CSS pixels of inset between the icon and the node's outer border. */
38
+ nodeIconPaddingPx: number;
39
+ /** Toggle for the off-canvas-edge dot+arrow that marks a selected node
40
+ * outside the viewport. Mirrors GraphConfig.style.showOffscreenSelectionIndicator. */
41
+ showOffscreenSelectionIndicator: boolean;
42
+ constructor(canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D);
43
+ /** World→screen projection. Writes to `out` and returns it for chaining. */
44
+ project(x: number, y: number, viewMatrix: mat3, out: vec2): vec2;
45
+ /** Grow projection/index buffers if the node count exceeds current capacity. */
46
+ ensureCapacity(nodeCount: number): void;
47
+ }
@@ -0,0 +1,15 @@
1
+ import { vec2 } from 'gl-matrix';
2
+ import { EdgeMetadata, FlowConfig } from '../types';
3
+ /** Box-selection marquee rectangle. */
4
+ export declare function drawMarquee(ctx: CanvasRenderingContext2D, start: vec2, end: vec2, dpr: number): void;
5
+ /**
6
+ * Small "ping" + arrow at the screen edge pointing to an off-screen target.
7
+ * Used so users notice selected nodes/edges that have scrolled out of view.
8
+ */
9
+ export declare function drawOffscreenIndicator(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, target1: vec2, target2: vec2, color: string, dpr: number): void;
10
+ /**
11
+ * Animated particles travelling along edges. Reads endpoint positions from
12
+ * the projection cache (NaN endpoints are skipped). Particle count is capped
13
+ * via `step` so very dense graphs don't blow out path complexity.
14
+ */
15
+ export declare function drawFlow(ctx: CanvasRenderingContext2D, projectedCache: Float32Array, indices: Uint32Array, count: number, zoom: number, dpr: number, theme: "dark" | "light", flow: FlowConfig, edgeMetadata: Map<string, EdgeMetadata>, selectedNodes: Set<number>): void;
@@ -0,0 +1,2 @@
1
+ export { OverlayManager } from './OverlayManager';
2
+ export type { HUDAction } from './ComboRenderer';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Shape index → Canvas2D path. Numeric ids match the GPU shader's switch:
3
+ * 0=circle, 1=square, 2=triangle, 3=diamond, 4=round-rect, 5=cut-rect.
4
+ *
5
+ * Caller is responsible for `beginPath()` before and `fill()`/`stroke()`/`clip()` after.
6
+ */
7
+ export declare function drawShapePath(ctx: CanvasRenderingContext2D, x: number, y: number, r: number, shape: number): void;
@@ -0,0 +1,15 @@
1
+ import { NodeMetadata, EdgeMetadata } from '../types';
2
+ /** Strip HTML tags so they aren't drawn literally onto the canvas. */
3
+ export declare function stripHtml(text: string): string;
4
+ /**
5
+ * Resolve the text actually rendered for a node/edge. Honors `labelHidden`
6
+ * and `labelSource` (which pulls a value from `meta.data`).
7
+ */
8
+ export declare function resolveLabelText(meta: NodeMetadata | EdgeMetadata): string;
9
+ /**
10
+ * Draws a metadata-driven text label with optional background, border, outline,
11
+ * uppercase/lowercase transform, and word-wrapping.
12
+ *
13
+ * `isMiddle` indicates an edge mid-label (different default styling than node labels).
14
+ */
15
+ export declare function drawStyledText(ctx: CanvasRenderingContext2D, text: string, x: number, y: number, meta: NodeMetadata | EdgeMetadata, theme: "dark" | "light", dpr: number, isMiddle?: boolean, bgOpacityOverride?: number, isHovered?: boolean, scale?: number): void;
@@ -1,7 +1,15 @@
1
- import { mat3 } from "gl-matrix";
2
- import type { Combo } from "./types";
1
+ import { mat3 } from 'gl-matrix';
2
+ import { Combo, EdgeMetadata } from './types';
3
3
  export declare class PickingEngine {
4
4
  private gl;
5
+ private _v1;
6
+ private _v2;
7
+ private _v3;
8
+ private _bSeg0;
9
+ private _bSeg1;
10
+ private _p1;
11
+ private _invViewScratch;
12
+ private _mouseNDC;
5
13
  constructor(gl: WebGL2RenderingContext);
6
14
  pickNode(params: {
7
15
  mouseX: number;
@@ -23,6 +31,8 @@ export declare class PickingEngine {
23
31
  viewMatrix: mat3;
24
32
  canvasW: number;
25
33
  canvasH: number;
34
+ edgeMetadata: Map<string, EdgeMetadata>;
35
+ edgeIndexToId: string[];
26
36
  }): string | null;
27
37
  pickCombo(params: {
28
38
  mouseX: number;
@@ -34,7 +44,8 @@ export declare class PickingEngine {
34
44
  zoom: number;
35
45
  canvasW: number;
36
46
  canvasH: number;
47
+ excludeIndices?: Set<number>;
37
48
  }): string | null;
38
49
  private distToSegment;
39
- private project;
50
+ private projectTo;
40
51
  }
@@ -0,0 +1,13 @@
1
+ export declare const SELECTION_RING_COLOR: "#4A9EFF";
2
+ export declare const SELECTION_RING_WIDTH_PX: 3;
3
+ export declare const SELECTION_RING_RADIUS_FACTOR: 1.1;
4
+ export declare const NODE_GROUP_BADGE_RADIUS_PX: 10;
5
+ export declare const NODE_GROUP_BADGE_FILL: "#76ABE7";
6
+ export declare const NODE_GROUP_BADGE_TEXT: "#ffffff";
7
+ export declare const NODE_GROUP_BADGE_TEXT_PX: 10;
8
+ export declare const NODE_GROUP_STACK_SHADOW_OFFSETS: readonly number[];
9
+ export declare const NODE_GROUP_STACK_SHADOW_OPACITY: 0.2;
10
+ export declare const NODE_EXPAND_BUTTON_RADIUS_PX: 10;
11
+ export declare const NODE_EXPAND_BUTTON_FILL: "#1a1a1a";
12
+ export declare const NODE_EXPAND_BUTTON_ICON: "#ffffff";
13
+ export declare const NODE_EXPAND_BUTTON_ICON_PX: 12;