@cosmos.gl/graph 2.2.0 → 2.3.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +7 -7
  2. package/dist/config.d.ts +16 -0
  3. package/dist/index.d.ts +68 -7
  4. package/dist/index.js +1989 -1880
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.min.js +64 -55
  7. package/dist/index.min.js.map +1 -1
  8. package/dist/modules/Points/index.d.ts +11 -6
  9. package/dist/stories/clusters/{lasso-selection → polygon-selection}/index.d.ts +1 -1
  10. package/dist/stories/clusters/{lasso-selection/lasso.d.ts → polygon-selection/polygon.d.ts} +5 -5
  11. package/dist/stories/clusters.stories.d.ts +1 -1
  12. package/dist/variables.d.ts +2 -0
  13. package/package.json +1 -1
  14. package/src/config.ts +21 -0
  15. package/src/index.ts +115 -22
  16. package/src/modules/Lines/draw-curve-line.frag +2 -1
  17. package/src/modules/Lines/draw-curve-line.vert +9 -3
  18. package/src/modules/Lines/index.ts +1 -0
  19. package/src/modules/Points/draw-highlighted.vert +2 -1
  20. package/src/modules/Points/draw-points.vert +2 -1
  21. package/src/modules/Points/{find-points-on-lasso-selection.frag → find-points-on-polygon-selection.frag} +8 -8
  22. package/src/modules/Points/index.ts +68 -25
  23. package/src/stories/2. configuration.mdx +2 -0
  24. package/src/stories/3. api-reference.mdx +82 -27
  25. package/src/stories/beginners/basic-set-up/index.ts +1 -1
  26. package/src/stories/clusters/{lasso-selection → polygon-selection}/index.ts +11 -11
  27. package/src/stories/clusters/{lasso-selection/lasso.ts → polygon-selection/polygon.ts} +16 -16
  28. package/src/stories/clusters/{lasso-selection → polygon-selection}/style.css +1 -1
  29. package/src/stories/clusters/worm.ts +22 -1
  30. package/src/stories/clusters.stories.ts +9 -9
  31. package/src/variables.ts +2 -0
@@ -6,7 +6,7 @@ import { defaultConfigValues } from '@/graph/variables'
6
6
  import drawPointsFrag from '@/graph/modules/Points/draw-points.frag'
7
7
  import drawPointsVert from '@/graph/modules/Points/draw-points.vert'
8
8
  import findPointsOnAreaSelectionFrag from '@/graph/modules/Points/find-points-on-area-selection.frag'
9
- import findPointsOnLassoSelectionFrag from '@/graph/modules/Points/find-points-on-lasso-selection.frag'
9
+ import findPointsOnPolygonSelectionFrag from '@/graph/modules/Points/find-points-on-polygon-selection.frag'
10
10
  import drawHighlightedFrag from '@/graph/modules/Points/draw-highlighted.frag'
11
11
  import drawHighlightedVert from '@/graph/modules/Points/draw-highlighted.vert'
12
12
  import findHoveredPointFrag from '@/graph/modules/Points/find-hovered-point.frag'
@@ -42,7 +42,7 @@ export class Points extends CoreModule {
42
42
  private updatePositionCommand: regl.DrawCommand | undefined
43
43
  private dragPointCommand: regl.DrawCommand | undefined
44
44
  private findPointsOnAreaSelectionCommand: regl.DrawCommand | undefined
45
- private findPointsOnLassoSelectionCommand: regl.DrawCommand | undefined
45
+ private findPointsOnPolygonSelectionCommand: regl.DrawCommand | undefined
46
46
  private findHoveredPointCommand: regl.DrawCommand | undefined
47
47
  private clearHoveredFboCommand: regl.DrawCommand | undefined
48
48
  private clearSampledPointsFboCommand: regl.DrawCommand | undefined
@@ -53,9 +53,9 @@ export class Points extends CoreModule {
53
53
  private greyoutStatusTexture: regl.Texture2D | undefined
54
54
  private sizeTexture: regl.Texture2D | undefined
55
55
  private trackedIndicesTexture: regl.Texture2D | undefined
56
- private lassoPathTexture: regl.Texture2D | undefined
57
- private lassoPathFbo: regl.Framebuffer2D | undefined
58
- private lassoPathLength = 0
56
+ private polygonPathTexture: regl.Texture2D | undefined
57
+ private polygonPathFbo: regl.Framebuffer2D | undefined
58
+ private polygonPathLength = 0
59
59
  private drawPointIndices: regl.Buffer | undefined
60
60
  private hoveredPointIndices: regl.Buffer | undefined
61
61
  private sampledPointIndices: regl.Buffer | undefined
@@ -232,6 +232,7 @@ export class Points extends CoreModule {
232
232
  transformationMatrix: () => store.transform,
233
233
  spaceSize: () => store.adjustedSpaceSize,
234
234
  screenSize: () => store.screenSize,
235
+ pointOpacity: () => config.pointOpacity,
235
236
  greyoutOpacity: () => config.pointGreyoutOpacity ?? -1,
236
237
  greyoutColor: () => store.greyoutPointColor,
237
238
  backgroundColor: () => store.backgroundColor,
@@ -285,9 +286,9 @@ export class Points extends CoreModule {
285
286
  })
286
287
  }
287
288
 
288
- if (!this.findPointsOnLassoSelectionCommand) {
289
- this.findPointsOnLassoSelectionCommand = reglInstance({
290
- frag: findPointsOnLassoSelectionFrag,
289
+ if (!this.findPointsOnPolygonSelectionCommand) {
290
+ this.findPointsOnPolygonSelectionCommand = reglInstance({
291
+ frag: findPointsOnPolygonSelectionFrag,
291
292
  vert: updateVert,
292
293
  framebuffer: () => this.selectedFbo as regl.Framebuffer2D,
293
294
  primitive: 'triangle strip',
@@ -300,8 +301,8 @@ export class Points extends CoreModule {
300
301
  spaceSize: () => store.adjustedSpaceSize,
301
302
  screenSize: () => store.screenSize,
302
303
  transformationMatrix: () => store.transform,
303
- lassoPathTexture: () => this.lassoPathTexture,
304
- lassoPathLength: () => this.lassoPathLength,
304
+ polygonPathTexture: () => this.polygonPathTexture,
305
+ polygonPathLength: () => this.polygonPathLength,
305
306
  },
306
307
  })
307
308
  }
@@ -412,6 +413,7 @@ export class Points extends CoreModule {
412
413
  scalePointsOnZoom: () => config.scalePointsOnZoom,
413
414
  maxPointSize: () => store.maxPointSize,
414
415
  pointGreyoutStatusTexture: () => this.greyoutStatusFbo,
416
+ universalPointOpacity: () => config.pointOpacity,
415
417
  greyoutOpacity: () => config.pointGreyoutOpacity ?? -1,
416
418
  darkenGreyout: () => store.darkenGreyout,
417
419
  backgroundColor: () => store.backgroundColor,
@@ -573,26 +575,26 @@ export class Points extends CoreModule {
573
575
  this.findPointsOnAreaSelectionCommand?.()
574
576
  }
575
577
 
576
- public findPointsOnLassoSelection (): void {
577
- this.findPointsOnLassoSelectionCommand?.()
578
+ public findPointsOnPolygonSelection (): void {
579
+ this.findPointsOnPolygonSelectionCommand?.()
578
580
  }
579
581
 
580
- public updateLassoPath (lassoPath: [number, number][]): void {
582
+ public updatePolygonPath (polygonPath: [number, number][]): void {
581
583
  const { reglInstance } = this
582
- this.lassoPathLength = lassoPath.length
584
+ this.polygonPathLength = polygonPath.length
583
585
 
584
- if (lassoPath.length === 0) {
585
- this.lassoPathTexture = undefined
586
- this.lassoPathFbo = undefined
586
+ if (polygonPath.length === 0) {
587
+ this.polygonPathTexture = undefined
588
+ this.polygonPathFbo = undefined
587
589
  return
588
590
  }
589
591
 
590
592
  // Calculate texture size (square texture)
591
- const textureSize = Math.ceil(Math.sqrt(lassoPath.length))
593
+ const textureSize = Math.ceil(Math.sqrt(polygonPath.length))
592
594
  const textureData = new Float32Array(textureSize * textureSize * 4)
593
595
 
594
- // Fill texture with lasso path points
595
- for (const [i, point] of lassoPath.entries()) {
596
+ // Fill texture with polygon path points
597
+ for (const [i, point] of polygonPath.entries()) {
596
598
  const [x, y] = point
597
599
  textureData[i * 4] = x
598
600
  textureData[i * 4 + 1] = y
@@ -600,17 +602,17 @@ export class Points extends CoreModule {
600
602
  textureData[i * 4 + 3] = 0 // unused
601
603
  }
602
604
 
603
- if (!this.lassoPathTexture) this.lassoPathTexture = reglInstance.texture()
604
- this.lassoPathTexture({
605
+ if (!this.polygonPathTexture) this.polygonPathTexture = reglInstance.texture()
606
+ this.polygonPathTexture({
605
607
  data: textureData,
606
608
  width: textureSize,
607
609
  height: textureSize,
608
610
  type: 'float',
609
611
  })
610
612
 
611
- if (!this.lassoPathFbo) this.lassoPathFbo = reglInstance.framebuffer()
612
- this.lassoPathFbo({
613
- color: this.lassoPathTexture,
613
+ if (!this.polygonPathFbo) this.polygonPathFbo = reglInstance.framebuffer()
614
+ this.polygonPathFbo({
615
+ color: this.polygonPathTexture,
614
616
  depth: false,
615
617
  stencil: false,
616
618
  })
@@ -695,6 +697,47 @@ export class Points extends CoreModule {
695
697
  return positions
696
698
  }
697
699
 
700
+ public getSampledPoints (): { indices: number[]; positions: number[] } {
701
+ const indices: number[] = []
702
+ const positions: number[] = []
703
+ if (!this.sampledPointsFbo) return { indices, positions }
704
+
705
+ this.clearSampledPointsFboCommand?.()
706
+ this.fillSampledPointsFboCommand?.()
707
+ const pixels = readPixels(this.reglInstance, this.sampledPointsFbo as regl.Framebuffer2D)
708
+
709
+ for (let i = 0; i < pixels.length / 4; i++) {
710
+ const index = pixels[i * 4]
711
+ const isNotEmpty = !!pixels[i * 4 + 1]
712
+ const x = pixels[i * 4 + 2]
713
+ const y = pixels[i * 4 + 3]
714
+
715
+ if (isNotEmpty && index !== undefined && x !== undefined && y !== undefined) {
716
+ indices.push(index)
717
+ positions.push(x, y)
718
+ }
719
+ }
720
+
721
+ return { indices, positions }
722
+ }
723
+
724
+ public getTrackedPositionsArray (): number[] {
725
+ const positions: number[] = []
726
+ if (!this.trackedIndices) return positions
727
+ positions.length = this.trackedIndices.length * 2
728
+ const pixels = readPixels(this.reglInstance, this.trackedPositionsFbo as regl.Framebuffer2D)
729
+ for (let i = 0; i < pixels.length / 4; i += 1) {
730
+ const x = pixels[i * 4]
731
+ const y = pixels[i * 4 + 1]
732
+ const index = this.trackedIndices[i]
733
+ if (x !== undefined && y !== undefined && index !== undefined) {
734
+ positions[i * 2] = x
735
+ positions[i * 2 + 1] = y
736
+ }
737
+ }
738
+ return positions
739
+ }
740
+
698
741
  private swapFbo (): void {
699
742
  const temp = this.previousPositionFbo
700
743
  this.previousPositionFbo = this.currentPositionFbo
@@ -13,6 +13,7 @@ import { Meta } from "@storybook/blocks";
13
13
  | pointGreyoutOpacity | Greyed out point opacity value when the selection is active | `undefined` |
14
14
  | pointGreyoutColor | Greyed out point color value when the selection is active | `undefined` |
15
15
  | pointSize | The default size value to use for points when no point sizes are provided or if the size value in the array is `undefined` or `null` | `4` |
16
+ | pointOpacity | Universal opacity value applied to all points. This value multiplies with individual point alpha values (if set via setPointColors). Useful for dynamically controlling opacity of all points without updating individual RGBA arrays. | `1.0` |
16
17
  | pointSizeScale | Scale factor for the point size | `1` |
17
18
  | hoveredPointCursor | Cursor style to use when hovering over a point | `auto` |
18
19
  | renderHoveredPointRing | Turns ring rendering around a point on hover on / off | `false` |
@@ -21,6 +22,7 @@ import { Meta } from "@storybook/blocks";
21
22
  | focusedPointIndex | Set focus on a point by index. A ring will be highlighted around the focused point. When set to `undefined`, no point is focused. | `undefined` |
22
23
  | renderLinks | Turns link rendering on / off | `true` |
23
24
  | linkColor | The default color to use for links when no link colors are provided, or if the color value in the array is `undefined` or `null`. This can be either a hex color string (e.g., '#666666') or an array of RGBA values in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255 | `#666666` |
25
+ | linkOpacity | Universal opacity value applied to all links. This value multiplies with individual link alpha values (if set via setLinkColors). Useful for dynamically controlling opacity of all links without updating individual RGBA arrays. | `1.0` |
24
26
  | linkGreyoutOpacity | Greyed out link opacity value when the selection is active | `0.1` |
25
27
  | linkWidth | The default width value to use for links when no link widths are provided or if the width value in the array is `undefined` or `null` | `1` |
26
28
  | linkWidthScale | Scale factor for the link width | `1` |
@@ -43,6 +43,13 @@ graph.setPointColors(new Float32Array([
43
43
  graph.render();
44
44
  ```
45
45
 
46
+ ### <a name="get_point_colors" href="#get_point_colors">#</a> graph.<b>getPointColors</b>()
47
+
48
+ This method retrieves the current colors of the graph points that were previously set using `setPointColors`.
49
+
50
+ **Returns:** A Float32Array representing the colors of points in the format `[r1, g1, b1, a1, r2, g2, b2, a2, ..., rN, gN, bN, aN]`, where each color is in RGBA format. Each set of four values (`r`, `g`, `b`, `a`) represents the color of a single point. Returns an empty Float32Array if no point colors are set.
51
+
52
+ The returned array contains the processed point colors used for rendering, including any default values that were applied during processing.
46
53
 
47
54
  ### <a name="set_point_sizes" href="#set_point_sizes">#</a> graph.<b>setPointSizes</b>(<i>pointSizes</i>)
48
55
 
@@ -60,6 +67,14 @@ graph.render();
60
67
 
61
68
  This example sets the size of the first point to 10, the second point to 20, and the third point to 30.
62
69
 
70
+ ### <a name="get_point_sizes" href="#get_point_sizes">#</a> graph.<b>getPointSizes</b>()
71
+
72
+ This method retrieves the current sizes of the graph points that were previously set using `setPointSizes`.
73
+
74
+ **Returns:** A Float32Array representing the sizes of points in the format `[size1, size2, ..., sizeN]`, where each `size` value corresponds to the size of the point at the same index in the graph's data. Returns an empty Float32Array if no point sizes are set.
75
+
76
+ The returned array contains the processed point sizes used for rendering, including any default values that were applied during processing.
77
+
63
78
  ### <a name="set_links" href="#set_links">#</a> graph.<b>setLinks</b>(<i>links</i>)
64
79
 
65
80
  This method sets the links (connections) between points in a cosmos.gl graph.
@@ -105,6 +120,14 @@ graph.render();
105
120
 
106
121
  In this example, the `linkColors` array contains three sets of four elements, each representing the RGBA color for a single link. The first set `[1, 0, 0, 1]` sets the first link to red, the second set `[0, 1, 0, 1]` sets the second link to green, and the third set `[0, 0, 1, 1]` sets the third link to blue.
107
122
 
123
+ ### <a name="get_link_colors" href="#get_link_colors">#</a> graph.<b>getLinkColors</b>()
124
+
125
+ This method retrieves the current colors of the graph links that were previously set using `setLinkColors`.
126
+
127
+ **Returns:** A Float32Array representing the colors of links in the format `[r1, g1, b1, a1, r2, g2, b2, a2, ..., rN, gN, bN, aN]`, where each color is in RGBA format. Each set of four values (`r`, `g`, `b`, `a`) represents the color of a single link. Returns an empty Float32Array if no link colors are set.
128
+
129
+ The returned array contains the processed link colors used for rendering, including any default values that were applied during processing.
130
+
108
131
  ### <a name="set_link_widths" href="#set_link_widths">#</a> graph.<b>setLinkWidths</b>(<i>linkWidths</i>)
109
132
 
110
133
  This method sets the widths for the graph links.
@@ -119,6 +142,14 @@ graph.render();
119
142
 
120
143
  In this example, the `linkWidths` array contains three numerical values. The first value `1` sets the width of the first link, the second value `2` sets the width of the second link, and the third value `3` sets the width of the third link.
121
144
 
145
+ ### <a name="get_link_widths" href="#get_link_widths">#</a> graph.<b>getLinkWidths</b>()
146
+
147
+ This method retrieves the current widths of the graph links that were previously set using `setLinkWidths`.
148
+
149
+ **Returns:** A Float32Array representing the widths of links in the format `[width1, width2, ..., widthN]`, where each `width` value corresponds to the width of the link at the same index in the graph's data. Returns an empty Float32Array if no link widths are set.
150
+
151
+ The returned array contains the processed link widths used for rendering, including any default values that were applied during processing.
152
+
122
153
  ### <a name="set_link_arrows" href="#set_link_arrows">#</a> graph.<b>setLinkArrows</b>(<i>linkArrows</i>)
123
154
 
124
155
  This method sets the arrows for the graph links.
@@ -135,7 +166,6 @@ graph.render();
135
166
 
136
167
  In this example, the `linkArrows` array contains three boolean values. The first value `true` sets an arrow on the first link, the second value `false` leaves the second link without an arrow, and the third value `true` sets an arrow on the third link.
137
168
 
138
-
139
169
  ### <a name="set_link_strengths" href="#set_link_strengths">#</a> graph.<b>setLinkStrength</b>(<i>linkStrength</i>)
140
170
 
141
171
  This method sets the strength of the graph links.
@@ -184,7 +214,6 @@ This method sets the force strength coefficients for clustering points in the gr
184
214
  ```
185
215
  This example sets the force coefficient for point 0 to 1, point 1 to 0.4, and point 2 to 0.3.
186
216
 
187
-
188
217
  ### <a name="render" href="#render">#</a> graph.<b>render</b>([<i>simulationAlpha</i>])
189
218
 
190
219
  The `render` method renders the graph and, optionally, controls the initial energy of the simulation.
@@ -220,7 +249,6 @@ This method centers and zooms the view to fit all points within the scene.
220
249
 
221
250
  The `fitView` method is particularly useful when you want to ensure that all points in the graph are visible within the currently displayed viewport. By fitting the view to include all points, users can get a complete overview of the entire graph.
222
251
 
223
-
224
252
  ### <a name="fit_view_by_point_indices" href="#fit_view_by_point_indices">#</a> graph.<b>fitViewByPointIndices</b>(<i>indices</i>, [<i>duration</i>], [<i>padding</i>])
225
253
 
226
254
  The `fitViewByPointIndices` method centers and zooms the view to fit the points specified by their <i>indices</i> in the scene, with an optional animation <i>duration</i> and <i>padding</i>.
@@ -237,34 +265,52 @@ The `fitViewByPointPositions` method centers and zooms the view to fit the point
237
265
  * **`duration`** (Number, optional): The duration of the animation in milliseconds. Default is 250 ms.
238
266
  * **`padding`** (Number, optional): The padding around the viewport in percentage. This value should be between 0 and 1. Default is 0.1 (10% padding).
239
267
 
240
- ### <a name="get_points_in_range" href="#get_points_in_range">#</a> graph.<b>getPointsInRange</b>(<i>selection</i>)
268
+ ### <a name="get_points_in_rect" href="#get_points_in_rect">#</a> graph.<b>getPointsInRect</b>(<i>selection</i>)
241
269
 
242
270
  Get points as a Float32Array within a rectangular area defined by two corner points `[[left, top], [right, bottom]]`. The `left` and `right` values represent the horizontal position in pixels, relative to the left edge of the canvas, with `0` being the leftmost position and the width of the canvas being the rightmost position.
243
271
 
244
272
  The `top` and `bottom` values represent the vertical position in pixels, relative to the top edge of the canvas, with `0` being the topmost position and the height of the canvas being the bottommost position.
245
273
 
246
- ### <a name="select_points_in_range" href="#select_points_in_range">#</a> graph.<b>selectPointsInRange</b>(<i>selection</i>)
274
+ * **`selection`** (Array): An array containing two coordinate arrays representing the corners of the selection rectangle in the format `[[left, top], [right, bottom]]`.
275
+
276
+ **Returns:** A Float32Array containing the indices of points inside the rectangular area.
277
+
278
+ ### <a name="get_points_in_range" href="#get_points_in_range">#</a> graph.<b>getPointsInRange</b>(<i>selection</i>) <b style={{ color: 'orange' }}>[DEPRECATED]</b>
279
+
280
+ **⚠️ Deprecated:** Use `getPointsInRect` instead. This method will be removed in a future version.
281
+
282
+ Get points as a Float32Array within a rectangular area defined by two corner points `[[left, top], [right, bottom]]`. This method has the same functionality as `getPointsInRect`.
283
+
284
+ ### <a name="select_points_in_rect" href="#select_points_in_rect">#</a> graph.<b>selectPointsInRect</b>(<i>selection</i>)
247
285
 
248
286
  Select points within a rectangular area defined by two corner points `[[left, top], [right, bottom]]`. The `left` and `right` values represent the horizontal position in pixels, relative to the left edge of the canvas, with `0` being the leftmost position and the width of the canvas being the rightmost position.
249
287
 
250
288
  The `top` and `bottom` values represent the vertical position in pixels, relative to the top edge of the canvas, with `0` being the topmost position and the height of the canvas being the bottommost position.
251
289
 
252
- ### <a name="get_points_in_lasso" href="#get_points_in_lasso">#</a> graph.<b>getPointsInLasso</b>(<i>lassoPath</i>)
290
+ * **`selection`** (Array | null): An array containing two coordinate arrays representing the corners of the selection rectangle in the format `[[left, top], [right, bottom]]`, or `null` to clear the current selection.
291
+
292
+ ### <a name="select_points_in_range" href="#select_points_in_range">#</a> graph.<b>selectPointsInRange</b>(<i>selection</i>) <b style={{ color: 'orange' }}>[DEPRECATED]</b>
293
+
294
+ **⚠️ Deprecated:** Use `selectPointsInRect` instead. This method will be removed in a future version.
295
+
296
+ Select points within a rectangular area defined by two corner points `[[left, top], [right, bottom]]`. This method has the same functionality as `selectPointsInRect`.
253
297
 
254
- Get points as a Float32Array within a lasso (polygon) area defined by an array of coordinate points.
298
+ ### <a name="get_points_in_polygon" href="#get_points_in_polygon">#</a> graph.<b>getPointsInPolygon</b>(<i>polygonPath</i>)
255
299
 
256
- * **`lassoPath`** (Array): An array of coordinate points in the format `[[x1, y1], [x2, y2], ..., [xN, yN]]` that defines the lasso polygon. The coordinates should be in pixels relative to the canvas, where:
300
+ Get points as a Float32Array within a polygon area defined by an array of coordinate points.
301
+
302
+ * **`polygonPath`** (Array): An array of coordinate points in the format `[[x1, y1], [x2, y2], ..., [xN, yN]]` that defines the polygon. The coordinates should be in pixels relative to the canvas, where:
257
303
  - **`x`**: Horizontal position from 0 to the width of the canvas
258
304
  - **`y`**: Vertical position from 0 to the height of the canvas
259
305
  - The polygon requires at least 3 points to form a valid selection area
260
306
 
261
- **Returns:** A Float32Array containing the indices of points inside the lasso area.
307
+ **Returns:** A Float32Array containing the indices of points inside the polygon area.
262
308
 
263
- ### <a name="select_points_in_lasso" href="#select_points_in_lasso">#</a> graph.<b>selectPointsInLasso</b>(<i>lassoPath</i>)
309
+ ### <a name="select_points_in_polygon" href="#select_points_in_polygon">#</a> graph.<b>selectPointsInPolygon</b>(<i>polygonPath</i>)
264
310
 
265
- Select points within a lasso (polygon) area defined by an array of coordinate points. This method combines the functionality of `getPointsInLasso` with point selection, making the identified points visually selected in the graph.
311
+ Select points within a polygon area defined by an array of coordinate points. This method combines the functionality of `getPointsInPolygon` with point selection, making the identified points visually selected in the graph.
266
312
 
267
- * **`lassoPath`** (Array | null): An array of coordinate points in the format `[[x1, y1], [x2, y2], ..., [xN, yN]]` that defines the lasso polygon, or `null` to clear the current selection. The coordinates should be in pixels relative to the canvas, where:
313
+ * **`polygonPath`** (Array | null): An array of coordinate points in the format `[[x1, y1], [x2, y2], ..., [xN, yN]]` that defines the polygon, or `null` to clear the current selection. The coordinates should be in pixels relative to the canvas, where:
268
314
  - **`x`**: Horizontal position from 0 to the width of the canvas
269
315
  - **`y`**: Vertical position from 0 to the height of the canvas
270
316
  - The polygon requires at least 3 points to form a valid selection area
@@ -276,24 +322,20 @@ This method selects a point in the graph based on its index.
276
322
  * **`index`** (Number): The index of the point to be selected.
277
323
  * **`selectAdjacentPoints`** (Boolean, optional): If set to `true`, adjacent points to the specified index will also be selected. The default value is `false`.
278
324
 
279
-
280
325
  ### <a name="select_points_by_indices" href="#select_points_by_indices">#</a> graph.<b>selectPointsByIndices</b>(<i>indices</i>)
281
326
 
282
327
  This method selects multiple points in the graph based on their indices.
283
328
 
284
329
  * **`indices`** (Array): An array of numbers representing the indices of the points to be selected.
285
330
 
286
-
287
331
  ### <a name="unselect_points" href="#unselect_points">#</a> graph.<b>unselectPoints</b>()
288
332
 
289
333
  This method unselects all currently selected points in the graph.
290
334
 
291
-
292
335
  ### <a name="get_selected_indices" href="#get_selected_indices">#</a> graph.<b>getSelectedIndices</b>()
293
336
 
294
337
  This method returns an array of indices corresponding to the currently selected points in the graph.
295
338
 
296
-
297
339
  ### <a name="get_adjacent_indices" href="#get_adjacent_indices">#</a> graph.<b>getAdjacentIndices</b>(<i>index</i>)
298
340
 
299
341
  This method returns an array of indices that are adjacent to a specific point in the graph, identified by its <i>index</i>.
@@ -306,28 +348,24 @@ This method method is used to convert X and Y point coordinates from the space c
306
348
 
307
349
  * **`coordinates`** (Array): An array of two numbers in the format `[x, y]`, representing the X and Y coordinates in the space coordinate system.
308
350
 
309
-
310
351
  ### <a name="screen_to_space_position" href="#screen_to_space_position">#</a> graph.<b>screenToSpacePosition</b>(<i>coordinates</i>)
311
352
 
312
353
  This` method converts X and Y point coordinates from the screen coordinate system (which is used for rendering the graph on the display) to the space coordinate system (which is typically used for graph data).
313
354
 
314
355
  * **`coordinates`** (Array): An array of two numbers in the format `[x, y]`, representing the X and Y coordinates in the screen coordinate system.
315
356
 
316
-
317
357
  ### <a name="space_to_screen_radius" href="#space_to_screen_radius">#</a> graph.<b>spaceToScreenRadius</b>(<i>radius</i>)
318
358
 
319
359
  This method is used to convert a <i>radius</i> value from the space coordinate system (which is typically used for graph data) to the screen coordinate system (which is used for rendering the graph on the display).
320
360
 
321
361
  * **`radius`** (Number): The radius value in the space coordinate system that needs to be converted to the screen coordinate system.
322
362
 
323
-
324
363
  ### <a name="get_point_radius_by_index" href="#get_point_radius_by_index">#</a> graph.<b>getPointRadiusByIndex</b>(<i>index</i>)
325
364
 
326
365
  This method retrieves the radius of a point in the graph identified by its <i>index</i>.
327
366
 
328
367
  * **`index`** (Number): The index of the point for which the radius is to be retrieved.
329
368
 
330
-
331
369
  ### <a name="track_point_positions_by_indices" href="#track_point_positions_by_indices">#</a> graph.<b>trackPointPositionsByIndices</b>(<i>indices</i>)
332
370
 
333
371
  This method allows you to monitor the coordinates of specific points over time. This is particularly useful for observing dynamic changes in the positions of points during the simulation. The positions of the tracked points are updated on each tick of the cosmos.gl simulation.
@@ -336,7 +374,6 @@ This method allows you to monitor the coordinates of specific points over time.
336
374
 
337
375
  To retrieve the current positions of the tracked points, use the [**getTrackedPointPositionsMap**](#get_tracked_point_positions_map) method, which returns a `Map` object containing the point coordinates.
338
376
 
339
-
340
377
  ### <a name="get_tracked_point_positions_map" href="#get_tracked_point_positions_map">#</a> graph.<b>getTrackedPointPositionsMap</b>()
341
378
 
342
379
  This method retrieves the current positions of points that are being tracked. This method is particularly useful for monitoring the changing coordinates of specific points over time during the simulation. Using this method in conjunction with the [**trackPointPositionsByIndices**](#track_point_positions_by_indices) method allows for dynamic tracking and retrieval of point positions.
@@ -345,6 +382,15 @@ This method retrieves the current positions of points that are being tracked. Th
345
382
 
346
383
  * A `Map` object where the keys are the indices of the tracked points and the values are their corresponding X and Y coordinates in the form of a `[number, number]` array.
347
384
 
385
+ ### <a name="get_tracked_point_positions_array" href="#get_tracked_point_positions_array">#</a> graph.<b>getTrackedPointPositionsArray</b>()
386
+
387
+ This method retrieves the current positions of points that are being tracked as an array for optimized performance. This method provides the same functionality as `getTrackedPointPositionsMap` but returns data as a flat array instead of a Map object, which can be more efficient for applications that need to process large numbers of tracked points.
388
+
389
+ The positions are returned in the same order as the indices provided to [**trackPointPositionsByIndices**](#track_point_positions_by_indices).
390
+
391
+ **Returns:**
392
+
393
+ * An array of numbers representing the X and Y coordinates of tracked points in the format `[x1, y1, x2, y2, ..., xn, yn]`, where each pair corresponds to a tracked point in the order they were specified for tracking. Returns an empty array if no points are being tracked.
348
394
 
349
395
  ### <a name="get_sampled_point_positions_map" href="#get_sampled_point_positions_map">#</a> graph.<b>getSampledPointPositionsMap</b>()
350
396
 
@@ -356,6 +402,21 @@ The number of sampled points is determined by the `pointSamplingDistance` [confi
356
402
 
357
403
  The sample aims to distribute points evenly across the visible area.
358
404
 
405
+ ### <a name="get_sampled_points" href="#get_sampled_points">#</a> graph.<b>getSampledPoints</b>()
406
+
407
+ This method provides an optimized way to retrieve both point indices and positions for sampled points that are currently visible on the screen. Unlike `getSampledPointPositionsMap`, this method returns the data as arrays rather than a Map.
408
+
409
+ The number of sampled points is determined by the `pointSamplingDistance` [configuration property](../?path=/docs/configuration--docs). This property controls the density of the sampled points:
410
+ * A higher value for `pointSamplingDistance` results in fewer sampled points.
411
+ * A lower value results in more sampled points.
412
+
413
+ The sample aims to distribute points evenly across the visible area.
414
+
415
+ **Returns:**
416
+
417
+ * An object containing:
418
+ - **`indices`**: Array of point indices for the sampled points
419
+ - **`positions`**: Flat array of coordinates in the format `[x1, y1, x2, y2, ..., xn, yn]`, where the coordinates correspond to the points at the same index positions in the `indices` array.
359
420
 
360
421
  ### <a name="start" href="#start">#</a> graph.<b>start</b>([<i>alpha</i>])
361
422
 
@@ -363,22 +424,18 @@ Starts the simulation with an optional <i>alpha</i> parameter, which controls th
363
424
 
364
425
  * **`alpha`** (Number, optional): A number between `0` and `1` representing the initial energy of the simulation. The default value is `1` if not provided. A higher `alpha` value results in more initial energy for the simulation.
365
426
 
366
-
367
427
  ### <a name="pause" href="#pause">#</a> graph.<b>pause</b>()
368
428
 
369
429
  Pauses the current simulation in the graph.
370
430
 
371
-
372
431
  ### <a name="restart" href="#restart">#</a> graph.<b>restart</b>()
373
432
 
374
433
  Restarts the current simulation in the graph.
375
434
 
376
-
377
435
  ### <a name="step" href="#step">#</a> graph.<b>step</b>()
378
436
 
379
437
  Renders a single frame of the simulation and pauses the simulation if it was active.
380
438
 
381
-
382
439
  ### <a name="destroy" href="#destroy">#</a> graph.<b>destroy</b>()
383
440
 
384
441
  Destroys the current cosmos.gl instance.
@@ -387,7 +444,6 @@ Destroys the current cosmos.gl instance.
387
444
 
388
445
  Creates a new cosmos.gl instance.
389
446
 
390
-
391
447
  ### <a name="flatten" href="#flatten">#</a> graph.<b>flatten</b>(<i>pointPositions</i>)
392
448
 
393
449
  This method converts an array of tuple positions into a single, flat array containing all coordinates sequentially.
@@ -400,7 +456,6 @@ This method converts a flat array of point positions into an array of tuple pair
400
456
 
401
457
  * **`pointPositions`** (Array): A flat array of numbers representing the x and y coordinates of points sequentially. For example, `[x1, y1, x2, y2, ..., xn, yn]`.
402
458
 
403
-
404
459
  ### <a name="get_point_positions" href="#get_point_positions">#</a> graph.<b>getPointPositions</b>()
405
460
 
406
461
  This method retrieves the current X and Y coordinates of all points in the graph as an array of numbers. The returned array is in the same order as the point positions were added to the graph.
@@ -119,7 +119,7 @@ export const basicSetUp = (): { graph: Graph; div: HTMLDivElement} => {
119
119
  const top = getRandomInRange([h / 4, h / 2])
120
120
  const bottom = getRandomInRange([top, (h * 3) / 4])
121
121
  pause()
122
- graph.selectPointsInRange([
122
+ graph.selectPointsInRect([
123
123
  [left, top],
124
124
  [right, bottom],
125
125
  ])
@@ -1,9 +1,9 @@
1
1
  import { Graph } from '@cosmos.gl/graph'
2
2
  import { createCosmos } from '../../create-cosmos'
3
3
  import { generateMeshData } from '../../generate-mesh-data'
4
- import { LassoSelection } from './lasso'
4
+ import { PolygonSelection } from './polygon'
5
5
 
6
- export const lassoSelection = (): {div: HTMLDivElement; graph: Graph; destroy: () => void } => {
6
+ export const polygonSelection = (): {div: HTMLDivElement; graph: Graph; destroy: () => void } => {
7
7
  const nClusters = 25
8
8
  const { pointPositions, pointColors, pointClusters } = generateMeshData(150, 150, nClusters, 1.0)
9
9
 
@@ -26,24 +26,24 @@ export const lassoSelection = (): {div: HTMLDivElement; graph: Graph; destroy: (
26
26
 
27
27
  graph.setZoomLevel(0.4)
28
28
 
29
- const lassoSelection = new LassoSelection(div, (lassoPoints) => {
30
- graph.selectPointsInLasso(lassoPoints)
29
+ const polygonSelection = new PolygonSelection(div, (polygonPoints) => {
30
+ graph.selectPointsInPolygon(polygonPoints)
31
31
  })
32
32
 
33
33
  const actionsDiv = document.createElement('div')
34
34
  actionsDiv.className = 'actions'
35
35
  div.appendChild(actionsDiv)
36
36
 
37
- const lassoButton = document.createElement('div')
38
- lassoButton.className = 'action'
39
- lassoButton.textContent = 'Enable Lasso Selection'
40
- lassoButton.addEventListener('click', () => {
41
- lassoSelection.enableLassoMode()
37
+ const polygonButton = document.createElement('div')
38
+ polygonButton.className = 'action'
39
+ polygonButton.textContent = 'Enable Polygon Selection'
40
+ polygonButton.addEventListener('click', () => {
41
+ polygonSelection.enablePolygonMode()
42
42
  })
43
- actionsDiv.appendChild(lassoButton)
43
+ actionsDiv.appendChild(polygonButton)
44
44
 
45
45
  const destroy = (): void => {
46
- lassoSelection.destroy()
46
+ polygonSelection.destroy()
47
47
  if (actionsDiv.parentNode) {
48
48
  actionsDiv.parentNode.removeChild(actionsDiv)
49
49
  }
@@ -1,20 +1,20 @@
1
1
  import './style.css'
2
2
 
3
- export class LassoSelection {
3
+ export class PolygonSelection {
4
4
  private canvas: HTMLCanvasElement
5
5
  private ctx: CanvasRenderingContext2D
6
6
  private isDrawing = false
7
7
  private points: Array<{ x: number; y: number }> = []
8
8
  private graphDiv: HTMLElement
9
- private onLassoComplete?: (points: [number, number][]) => void
9
+ private onPolygonComplete?: (points: [number, number][]) => void
10
10
  private boundStartDrawing: (e: MouseEvent) => void
11
11
  private boundDraw: (e: MouseEvent) => void
12
12
  private boundStopDrawing: () => void
13
13
  private resizeObserver: ResizeObserver
14
14
 
15
- public constructor (graphDiv: HTMLElement, onLassoComplete?: (points: [number, number][]) => void) {
15
+ public constructor (graphDiv: HTMLElement, onPolygonComplete?: (points: [number, number][]) => void) {
16
16
  this.graphDiv = graphDiv
17
- this.onLassoComplete = onLassoComplete
17
+ this.onPolygonComplete = onPolygonComplete
18
18
 
19
19
  // Bind event handlers
20
20
  this.boundStartDrawing = this.startDrawing.bind(this)
@@ -23,7 +23,7 @@ export class LassoSelection {
23
23
 
24
24
  // Create canvas
25
25
  this.canvas = document.createElement('canvas')
26
- this.canvas.className = 'lasso-canvas'
26
+ this.canvas.className = 'polygon-canvas'
27
27
 
28
28
  const ctx = this.canvas.getContext('2d')
29
29
  if (!ctx) throw new Error('Could not get canvas context')
@@ -37,7 +37,7 @@ export class LassoSelection {
37
37
  this.resizeObserver.observe(this.graphDiv)
38
38
  }
39
39
 
40
- public enableLassoMode (): void {
40
+ public enablePolygonMode (): void {
41
41
  this.canvas.style.pointerEvents = 'auto'
42
42
  this.canvas.style.cursor = 'crosshair'
43
43
 
@@ -47,7 +47,7 @@ export class LassoSelection {
47
47
  this.canvas.addEventListener('mouseup', this.boundStopDrawing)
48
48
  }
49
49
 
50
- public disableLassoMode (): void {
50
+ public disablePolygonMode (): void {
51
51
  this.canvas.style.pointerEvents = 'none'
52
52
  this.canvas.style.cursor = 'default'
53
53
 
@@ -61,7 +61,7 @@ export class LassoSelection {
61
61
  }
62
62
 
63
63
  public destroy (): void {
64
- this.disableLassoMode()
64
+ this.disablePolygonMode()
65
65
  this.resizeObserver.disconnect()
66
66
  if (this.canvas.parentNode) {
67
67
  this.canvas.parentNode.removeChild(this.canvas)
@@ -124,20 +124,20 @@ export class LassoSelection {
124
124
  this.ctx.closePath()
125
125
  this.ctx.stroke()
126
126
 
127
- const lassoPoints: [number, number][] = this.points.map(p => [p.x, p.y])
128
- const firstLassoPoint = lassoPoints[0]
129
- const lastLassoPoint = lassoPoints[lassoPoints.length - 1]
130
- if (firstLassoPoint && lastLassoPoint && (firstLassoPoint[0] !== lastLassoPoint[0] || firstLassoPoint[1] !== lastLassoPoint[1])) {
131
- lassoPoints.push(firstLassoPoint)
127
+ const polygonPoints: [number, number][] = this.points.map(p => [p.x, p.y])
128
+ const firstPolygonPoint = polygonPoints[0]
129
+ const lastPolygonPoint = polygonPoints[polygonPoints.length - 1]
130
+ if (firstPolygonPoint && lastPolygonPoint && (firstPolygonPoint[0] !== lastPolygonPoint[0] || firstPolygonPoint[1] !== lastPolygonPoint[1])) {
131
+ polygonPoints.push(firstPolygonPoint)
132
132
  }
133
133
 
134
- if (this.onLassoComplete) {
135
- this.onLassoComplete(lassoPoints)
134
+ if (this.onPolygonComplete) {
135
+ this.onPolygonComplete(polygonPoints)
136
136
  }
137
137
  }
138
138
 
139
139
  const pixelRatio = window.devicePixelRatio || 1
140
140
  this.ctx.clearRect(0, 0, this.canvas.width / pixelRatio, this.canvas.height / pixelRatio)
141
- this.disableLassoMode()
141
+ this.disablePolygonMode()
142
142
  }
143
143
  }
@@ -1,4 +1,4 @@
1
- .lasso-canvas {
1
+ .polygon-canvas {
2
2
  position: absolute;
3
3
  top: 0;
4
4
  left: 0;