@cosmos.gl/graph 3.0.0-beta.7 → 3.0.0-beta.9

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.
@@ -1,9 +1,11 @@
1
1
  import { Store } from '../Store';
2
2
  import { GraphConfigInterface } from '../../config';
3
+ import { Transition } from '../Transition';
3
4
  export declare class Drag {
4
5
  readonly store: Store;
5
6
  readonly config: GraphConfigInterface;
7
+ readonly transition: Transition;
6
8
  isActive: boolean;
7
9
  behavior: import('d3-drag').DragBehavior<HTMLCanvasElement, undefined, import('d3-drag').SubjectPosition | undefined>;
8
- constructor(store: Store, config: GraphConfigInterface);
10
+ constructor(store: Store, config: GraphConfigInterface, transition: Transition);
9
11
  }
@@ -26,6 +26,18 @@ export declare class GraphData {
26
26
  inputClusterStrength: Float32Array | undefined;
27
27
  inputPinnedPoints: number[] | undefined;
28
28
  pointPositions: Float32Array | undefined;
29
+ /**
30
+ * Number of points before the latest data update.
31
+ * Used as the `from` value for point transitions.
32
+ * This lets transitions handle added or removed points correctly.
33
+ */
34
+ sourcePointsNumber: number;
35
+ /**
36
+ * Number of points after the latest data update.
37
+ * Used as the `to` value for point transitions.
38
+ * This lets transitions handle added or removed points correctly.
39
+ */
40
+ targetPointsNumber: number;
29
41
  pointColors: Float32Array | undefined;
30
42
  pointSizes: Float32Array | undefined;
31
43
  pointShapes: Float32Array | undefined;
@@ -93,7 +105,26 @@ export declare class GraphData {
93
105
  updateLinkStrength(): void;
94
106
  updateClusters(): void;
95
107
  update(): void;
96
- getAdjacentIndices(index: number): number[] | undefined;
108
+ /**
109
+ * Returns unique point indices that are neighbors of the given point(s) —
110
+ * i.e., connected by a link in either direction.
111
+ * @param pointIndices - A single point index or an array of point indices.
112
+ * @returns Array of neighboring point indices.
113
+ */
114
+ getNeighboringPointIndices(pointIndices: number | number[]): number[];
115
+ /**
116
+ * Returns unique link indices where both the source and target endpoints
117
+ * are within the given point(s). Only links fully contained in the set are returned.
118
+ * @param pointIndices - A single point index or an array of point indices.
119
+ * @returns Array of link indices connecting points within the provided set.
120
+ */
121
+ getConnectedLinkIndices(pointIndices: number | number[]): number[];
122
+ /**
123
+ * Returns unique point indices at the endpoints (source and target) of the given link(s).
124
+ * @param linkIndices - A single link index or an array of link indices.
125
+ * @returns Array of point indices at the ends of the provided links.
126
+ */
127
+ getConnectedPointIndices(linkIndices: number | number[]): number[];
97
128
  private _createAdjacencyLists;
98
129
  private _calculateDegrees;
99
130
  }
@@ -1,16 +1,22 @@
1
- import { Framebuffer, RenderPass } from '@luma.gl/core';
1
+ import { Framebuffer, Texture, RenderPass } from '@luma.gl/core';
2
2
  import { CoreModule } from '../core-module';
3
3
  export declare class Lines extends CoreModule {
4
4
  linkIndexFbo: Framebuffer | undefined;
5
5
  hoveredLineIndexFbo: Framebuffer | undefined;
6
6
  sampledLinksFbo: Framebuffer | undefined;
7
+ linkStatusTexture: Texture | undefined;
8
+ private linkStatusTextureSize;
7
9
  private drawCurveCommand;
8
10
  private hoveredLineIndexCommand;
9
11
  private fillSampledLinksFboCommand;
10
12
  private pointABuffer;
11
13
  private pointBBuffer;
12
- private colorBuffer;
13
- private widthBuffer;
14
+ private sourceColorBuffer;
15
+ private targetColorBuffer;
16
+ private previousColorData;
17
+ private sourceWidthBuffer;
18
+ private targetWidthBuffer;
19
+ private previousWidthData;
14
20
  private arrowBuffer;
15
21
  private curveLineGeometry;
16
22
  private curveLineBuffer;
@@ -18,6 +24,9 @@ export declare class Lines extends CoreModule {
18
24
  private quadBuffer;
19
25
  private linkIndexTexture;
20
26
  private hoveredLineIndexTexture;
27
+ private transitionProgress;
28
+ private shouldAnimateLinkColors;
29
+ private shouldAnimateLinkWidths;
21
30
  private fillSampledLinksUniformStore;
22
31
  private drawLineUniformStore;
23
32
  private hoveredLineIndexUniformStore;
@@ -30,6 +39,7 @@ export declare class Lines extends CoreModule {
30
39
  updateColor(): void;
31
40
  updateWidth(): void;
32
41
  updateArrow(): void;
42
+ updateLinkStatus(): void;
33
43
  updateCurveLineGeometry(): void;
34
44
  getSampledLinkPositionsMap(): Map<number, [number, number, number]>;
35
45
  getSampledLinks(): {
@@ -38,9 +48,11 @@ export declare class Lines extends CoreModule {
38
48
  angles: number[];
39
49
  };
40
50
  findHoveredLine(): void;
51
+ setTransitionProgress(progress: number, animateColors?: boolean, animateWidths?: boolean): void;
41
52
  /**
42
53
  * Destruction order matters
43
54
  * Models -> Framebuffers -> Textures -> UniformStores -> Buffers
44
55
  */
45
56
  destroy(): void;
57
+ private ensureLinkStatusPlaceholder;
46
58
  }
@@ -1,10 +1,14 @@
1
1
  import { Framebuffer, Texture, RenderPass } from '@luma.gl/core';
2
2
  import { CoreModule } from '../core-module';
3
+ import { Transition } from '../Transition';
3
4
  export declare class Points extends CoreModule {
5
+ transition: Transition | undefined;
4
6
  currentPositionFbo: Framebuffer | undefined;
5
7
  previousPositionFbo: Framebuffer | undefined;
8
+ sourcePositionFbo: Framebuffer | undefined;
9
+ targetPositionFbo: Framebuffer | undefined;
6
10
  velocityFbo: Framebuffer | undefined;
7
- selectedFbo: Framebuffer | undefined;
11
+ searchFbo: Framebuffer | undefined;
8
12
  hoveredFbo: Framebuffer | undefined;
9
13
  scaleX: ((x: number) => number) | undefined;
10
14
  scaleY: ((y: number) => number) | undefined;
@@ -14,7 +18,9 @@ export declare class Points extends CoreModule {
14
18
  currentPositionTexture: Texture | undefined;
15
19
  previousPositionTexture: Texture | undefined;
16
20
  velocityTexture: Texture | undefined;
17
- greyoutStatusTexture: Texture | undefined;
21
+ pointStatusTexture: Texture | undefined;
22
+ sourcePositionTexture: Texture | undefined;
23
+ targetPositionTexture: Texture | undefined;
18
24
  /**
19
25
  * Whether the cached cluster centroid positions are still valid.
20
26
  * Set to `false` in `swapFbo()` whenever GPU point positions change (simulation tick or drag).
@@ -22,8 +28,12 @@ export declare class Points extends CoreModule {
22
28
  * Used together with `Clusters.cachedCentroidPositions` to skip redundant GPU readbacks.
23
29
  */
24
30
  areClusterCentroidsUpToDate: boolean;
25
- private colorBuffer;
26
- private sizeBuffer;
31
+ private sourceColorBuffer;
32
+ private targetColorBuffer;
33
+ private previousColorData;
34
+ private sourceSizeBuffer;
35
+ private targetSizeBuffer;
36
+ private previousSizeData;
27
37
  private shapeBuffer;
28
38
  private imageIndicesBuffer;
29
39
  private imageSizesBuffer;
@@ -32,24 +42,32 @@ export declare class Points extends CoreModule {
32
42
  private trackedPositionsFbo;
33
43
  private sampledPointsFbo;
34
44
  private trackedPositions;
45
+ /**
46
+ * Guards the CPU-side `trackedPositions` cache in `getTrackedPositionsMap()`.
47
+ * Set to `true` after a successful readback when the simulation is inactive;
48
+ * must be set to `false` whenever `currentPositionFbo` is written to
49
+ * (simulation step, drag, position transition) so the next call re-reads from the GPU.
50
+ */
35
51
  private isPositionsUpToDate;
36
52
  private drawCommand;
37
53
  private drawHighlightedCommand;
38
54
  private updatePositionCommand;
55
+ private interpolatePositionCommand;
39
56
  private dragPointCommand;
40
- private findPointsOnAreaSelectionCommand;
41
- private findPointsOnPolygonSelectionCommand;
57
+ private findPointsInRectCommand;
58
+ private findPointsInPolygonCommand;
42
59
  private findHoveredPointCommand;
43
60
  private fillSampledPointsFboCommand;
44
61
  private trackPointsCommand;
45
62
  private updatePositionVertexCoordBuffer;
63
+ private interpolatePositionVertexCoordBuffer;
46
64
  private dragPointVertexCoordBuffer;
47
- private findPointsOnAreaSelectionVertexCoordBuffer;
48
- private findPointsOnPolygonSelectionVertexCoordBuffer;
65
+ private findPointsInRectVertexCoordBuffer;
66
+ private findPointsInPolygonVertexCoordBuffer;
49
67
  private drawHighlightedVertexCoordBuffer;
50
68
  private trackPointsVertexCoordBuffer;
51
69
  private trackedIndices;
52
- private selectedTexture;
70
+ private searchTexture;
53
71
  private pinnedStatusTexture;
54
72
  private sizeTexture;
55
73
  private trackedIndicesTexture;
@@ -58,19 +76,23 @@ export declare class Points extends CoreModule {
58
76
  private drawPointIndices;
59
77
  private hoveredPointIndices;
60
78
  private sampledPointIndices;
79
+ private transitionProgress;
80
+ private shouldAnimatePointColors;
81
+ private shouldAnimatePointSizes;
61
82
  private updatePositionUniformStore;
83
+ private interpolatePositionUniformStore;
62
84
  private dragPointUniformStore;
63
85
  private drawUniformStore;
64
- private findPointsOnAreaSelectionUniformStore;
65
- private findPointsOnPolygonSelectionUniformStore;
86
+ private findPointsInRectUniformStore;
87
+ private findPointsInPolygonUniformStore;
66
88
  private findHoveredPointUniformStore;
67
89
  private fillSampledPointsUniformStore;
68
90
  private drawHighlightedUniformStore;
69
91
  private trackPointsUniformStore;
70
- updatePositions(): void;
92
+ updatePositions(): boolean;
71
93
  initPrograms(): void;
72
94
  updateColor(): void;
73
- updateGreyoutStatus(): void;
95
+ updatePointStatus(): void;
74
96
  updatePinnedStatus(): void;
75
97
  updateSize(): void;
76
98
  updateShape(): void;
@@ -79,11 +101,12 @@ export declare class Points extends CoreModule {
79
101
  createAtlas(): void;
80
102
  updateSampledPointsGrid(): void;
81
103
  trackPoints(): void;
104
+ setTransitionProgress(progress: number, animateColors?: boolean, animateSizes?: boolean): void;
82
105
  draw(renderPass: RenderPass): void;
83
106
  updatePosition(): void;
84
107
  drag(): void;
85
- findPointsOnAreaSelection(): void;
86
- findPointsOnPolygonSelection(): void;
108
+ findPointsInRect(): boolean;
109
+ findPointsInPolygon(): boolean;
87
110
  updatePolygonPath(polygonPath: [number, number][]): void;
88
111
  findHoveredPoint(): void;
89
112
  trackPointsByIndices(indices?: number[] | undefined): void;
@@ -103,10 +126,17 @@ export declare class Points extends CoreModule {
103
126
  };
104
127
  getTrackedPositionsArray(): number[];
105
128
  /**
106
- * Destruction order matters
107
- * Models -> Framebuffers -> Textures -> UniformStores -> Buffers
108
- * */
129
+ * Destroy luma.gl resources in ownership order:
130
+ * Models -> Framebuffers -> Textures -> UniformStores -> Buffers.
131
+ */
109
132
  destroy(): void;
110
- private swapFbo;
133
+ ensureSimulationResources(): void;
134
+ createTransitionResources(): void;
135
+ destroyTransitionResources(): void;
136
+ interpolatePosition(progress: number): void;
137
+ destroySimulationResources(): void;
138
+ swapFbo(): void;
139
+ private createOrUpdatePositionTextures;
140
+ private ensureUpdatePositionProgram;
111
141
  private rescaleInitialNodePositions;
112
142
  }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Build RGBA32F texture data from a flat `[x, y, x, y, ...]` point positions array.
3
+ *
4
+ * Layout per pixel: `[x, y, index, 0]`. The blue channel encodes the point index —
5
+ * `drag-point.frag` reads it to match the drag target. Alpha is unused by shaders.
6
+ */
7
+ export declare function buildPositionTextureData(pointPositions: Float32Array | undefined, pointsTextureSize: number, pointsNumber: number): Float32Array;
8
+ /**
9
+ * Build the `sourcePosition` texture data for a transition when the point count changed.
10
+ *
11
+ * Shared indices (`0..sharedCount`) carry over their on-screen positions from
12
+ * `previousPositionPixels` (readback of the pre-transition `currentPositionFbo`), so the
13
+ * animation starts from where each point was last rendered. New indices (`sharedCount..targetCount`)
14
+ * start at their target position so they don't drift in from the origin.
15
+ *
16
+ * Precondition: `sharedCount * 4 <= previousPositionPixels.length` — the caller guarantees
17
+ * this by passing `min(previousPointsCount, targetCount)`.
18
+ */
19
+ export declare function buildSourcePositionTextureData(previousPositionPixels: Float32Array, targetData: Float32Array, sharedCount: number, targetCount: number, newTextureSize: number): Float32Array;
@@ -1 +1,7 @@
1
+ import { Buffer, Device } from '@luma.gl/core';
1
2
  export declare function createIndexesForBuffer(textureSize: number): Float32Array;
3
+ export declare function updateAttributeBuffers(device: Device, targetData: Float32Array, sourceBuffer: Buffer | undefined, targetBuffer: Buffer | undefined, previousData: Float32Array | undefined, tupleSize: 1 | 4): {
4
+ source: Buffer;
5
+ target: Buffer;
6
+ previous: Float32Array;
7
+ };
@@ -33,10 +33,9 @@ export declare class Store {
33
33
  screenSize: [number, number];
34
34
  mousePosition: number[];
35
35
  screenMousePosition: number[];
36
- selectedArea: number[][];
36
+ searchArea: number[][];
37
37
  isSimulationRunning: boolean;
38
38
  simulationProgress: number;
39
- selectedIndices: Float32Array | null;
40
39
  maxPointSize: number;
41
40
  hoveredPoint: Hovered | undefined;
42
41
  focusedPoint: Focused | undefined;
@@ -48,6 +47,9 @@ export declare class Store {
48
47
  webglMaxTextureSize: number;
49
48
  hoveredPointRingColor: number[];
50
49
  focusedPointRingColor: number[];
50
+ outlinedPointRingColor: number[];
51
+ highlightedPointSet: Set<number> | undefined;
52
+ outlinedPointSet: Set<number> | undefined;
51
53
  hoveredLinkColor: number[];
52
54
  greyoutPointColor: number[];
53
55
  isDarkenGreyout: boolean;
@@ -164,6 +166,9 @@ export declare class Store {
164
166
  scaleY(y: number): number;
165
167
  setHoveredPointRingColor(color: string | [number, number, number, number]): void;
166
168
  setFocusedPointRingColor(color: string | [number, number, number, number]): void;
169
+ setOutlinedPointRingColor(color: string | [number, number, number, number]): void;
170
+ setHighlightedPointSet(indices: number[] | undefined): void;
171
+ setOutlinedPointSet(indices: number[] | undefined): void;
167
172
  setGreyoutPointColor(color: string | [number, number, number, number] | undefined): void;
168
173
  updateLinkHoveringEnabled(config: Pick<GraphConfigInterface, 'onLinkClick' | 'onLinkContextMenu' | 'onLinkMouseOver' | 'onLinkMouseOut'>): void;
169
174
  setHoveredLinkColor(color?: string | [number, number, number, number]): void;
@@ -0,0 +1,87 @@
1
+ import { GraphConfigInterface } from '../../config';
2
+ export declare enum TransitionProperty {
3
+ Positions = "positions",
4
+ PointColors = "pointColors",
5
+ PointSizes = "pointSizes",
6
+ LinkColors = "linkColors",
7
+ LinkWidths = "linkWidths"
8
+ }
9
+ export declare enum TransitionEasing {
10
+ Linear = "linear",
11
+ QuadIn = "quad-in",
12
+ QuadOut = "quad-out",
13
+ QuadInOut = "quad-in-out",
14
+ CubicIn = "cubic-in",
15
+ CubicOut = "cubic-out",
16
+ CubicInOut = "cubic-in-out",
17
+ SinIn = "sin-in",
18
+ SinOut = "sin-out",
19
+ SinInOut = "sin-in-out",
20
+ ExpIn = "exp-in",
21
+ ExpOut = "exp-out",
22
+ ExpInOut = "exp-in-out",
23
+ CircleIn = "circle-in",
24
+ CircleOut = "circle-out",
25
+ CircleInOut = "circle-in-out"
26
+ }
27
+ export declare class Transition {
28
+ /** Last eased progress value in the `[0, 1]` range. */
29
+ progress: number;
30
+ private readonly config;
31
+ private startTime;
32
+ /** Properties queued via `queue()`, awaiting `start()` to consume them. */
33
+ private pendingProperties;
34
+ /** Properties currently animating in the running cycle. */
35
+ private activeProperties;
36
+ constructor(config: GraphConfigInterface);
37
+ /** True while one or more properties are queued via `queue()` awaiting `start()`. */
38
+ get isPending(): boolean;
39
+ /** True between `start()` and the end of the cycle. */
40
+ get isActive(): boolean;
41
+ /** Reports whether a specific property is queued and awaiting `start()`. */
42
+ isPendingFor(property: TransitionProperty): boolean;
43
+ /** Reports whether a specific property is part of the active cycle. */
44
+ isActiveFor(property: TransitionProperty): boolean;
45
+ /** Queues a property for the next transition cycle. */
46
+ queue(property: TransitionProperty): void;
47
+ /** Removes a property from the pending queue without affecting the active cycle. */
48
+ dequeue(property: TransitionProperty): void;
49
+ /**
50
+ * Starts a queued transition cycle.
51
+ *
52
+ * - No pending queue → no-op.
53
+ * - `transitionDuration > 0` → begin cycle; fire `onTransitionStart`.
54
+ * - `transitionDuration <= 0` → pending is discarded; no cycle begins.
55
+ *
56
+ * In either non-no-op path, any active cycle is reported as interrupted
57
+ * via `onTransitionEnd(true)` before the new state takes effect.
58
+ */
59
+ start(): void;
60
+ /**
61
+ * Advances the active cycle.
62
+ *
63
+ * - No active cycle → no-op.
64
+ * - `transitionDuration <= 0` → end interrupted; fire `onTransitionEnd(true)`.
65
+ * - Progress < 1 → update `progress`; fire `onTransition(eased)`.
66
+ * - Progress reaches 1 → fire `onTransition(1)` then `onTransitionEnd(false)`.
67
+ */
68
+ step(): void;
69
+ /**
70
+ * Ends the active cycle.
71
+ *
72
+ * - No active cycle → no-op.
73
+ * - Otherwise → fire `onTransitionEnd(interrupted)`.
74
+ *
75
+ * TODO: support per-property end.
76
+ */
77
+ end(interrupted: boolean): void;
78
+ /**
79
+ * Clears all transition state — active cycle and pending queue — without
80
+ * firing lifecycle callbacks. Unlike `end()`, also drops any properties
81
+ * queued via `queue()`.
82
+ */
83
+ abort(): void;
84
+ private applyEasing;
85
+ /** Ends the active cycle, preserving any pending queue for the next `start()`. */
86
+ private clearActiveCycle;
87
+ }
@@ -1,9 +1,12 @@
1
1
  import { PointShape } from './modules/GraphData';
2
+ import { TransitionEasing } from './modules/Transition';
2
3
  /**
3
4
  * Default values for all graph configuration properties.
4
5
  */
5
6
  export declare const defaultConfigValues: {
6
7
  enableSimulation: true;
8
+ transitionDuration: number;
9
+ transitionEasing: TransitionEasing.CubicInOut;
7
10
  backgroundColor: string;
8
11
  /** Setting to 4096 because larger values crash the graph on iOS. More info: https://github.com/cosmosgl/graph/issues/203 */
9
12
  spaceSize: number;
@@ -20,6 +23,9 @@ export declare const defaultConfigValues: {
20
23
  hoveredPointRingColor: string;
21
24
  focusedPointRingColor: string;
22
25
  focusedPointIndex: undefined;
26
+ highlightedPointIndices: undefined;
27
+ outlinedPointIndices: undefined;
28
+ outlinedPointRingColor: string;
23
29
  renderLinks: true;
24
30
  linkDefaultColor: string;
25
31
  linkDefaultWidth: number;
@@ -38,6 +44,9 @@ export declare const defaultConfigValues: {
38
44
  hoveredLinkCursor: string;
39
45
  hoveredLinkColor: undefined;
40
46
  hoveredLinkWidthIncrease: number;
47
+ highlightedLinkIndices: undefined;
48
+ focusedLinkIndex: undefined;
49
+ focusedLinkWidthIncrease: number;
41
50
  simulationDecay: number;
42
51
  simulationGravity: number;
43
52
  simulationCenter: number;
@@ -55,6 +64,9 @@ export declare const defaultConfigValues: {
55
64
  onSimulationEnd: undefined;
56
65
  onSimulationPause: undefined;
57
66
  onSimulationUnpause: undefined;
67
+ onTransitionStart: undefined;
68
+ onTransition: undefined;
69
+ onTransitionEnd: undefined;
58
70
  onClick: undefined;
59
71
  onPointClick: undefined;
60
72
  onLinkClick: undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmos.gl/graph",
3
- "version": "3.0.0-beta.7",
3
+ "version": "3.0.0-beta.9",
4
4
  "description": "GPU-based force graph layout and rendering",
5
5
  "jsdelivr": "dist/index.min.js",
6
6
  "main": "dist/index.js",
@@ -72,9 +72,10 @@
72
72
  "vite-plugin-dts": "^4.3.0"
73
73
  },
74
74
  "dependencies": {
75
- "@luma.gl/core": "^9.2.6",
76
- "@luma.gl/engine": "^9.2.6",
77
- "@luma.gl/webgl": "^9.2.6",
75
+ "@luma.gl/core": "~9.2.6",
76
+ "@luma.gl/engine": "~9.2.6",
77
+ "@luma.gl/shadertools": "~9.2.6",
78
+ "@luma.gl/webgl": "~9.2.6",
78
79
  "d3-array": "^3.2.0",
79
80
  "d3-color": "^3.1.0",
80
81
  "d3-drag": "^3.0.0",