Skip to content

Commit 40e93b4

Browse files
feat: implement programmatic lasso selection (#236)
* feat: implement programmatic lasso selection - Add polygon selection API to select() method - Accepts array of [x,y] coordinate pairs in data space - Reuses existing findPointsInLasso() with KD-tree - Supports merge and remove modes - Add programmatic-lasso.js example with interactive demo - Update README with API documentation and examples - Add to Examples menu in Tweakpane * update changelog.md * refactor: add dedicated lassoSelect() method per code review - Replace overloaded select(polygon) with lassoSelect(vertices) API - Add isVertices() validation checking all vertices - Add verticesToPolygon() helper to auto-close polygons - Rename polygonDataToGl to verticesFromDataToGl for clarity - Addtests - Update programmatic-lasso example to use new API - Update changelog.md * docs: add lassoSelect() method documentation to README
1 parent 7666ec6 commit 40e93b4

File tree

8 files changed

+804
-3
lines changed

8 files changed

+804
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.15.0
2+
3+
- Feat: add programmatic lasso selection API via new `lassoSelect()` method that accept a polygon in either data or GL space. This enables automated point selection without manual interaction. Supports `merge` and `remove` options. Note, vertices in data space requires `xScale` and `yScale` to be defined.
4+
15
## 1.14.1
26

37
- Fix: ensure view aspect ratio is updated before the scales are updated on resize

README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,85 @@ scatterplot.draw([
516516
scatterplot.select([0, 1]);
517517
```
518518

519+
<a name="scatterplot.lassoSelect" href="#scatterplot.lassoSelect">#</a> scatterplot.<b>lassoSelect</b>(<i>vertices</i>, <i>options = {}</i>)
520+
521+
Programmatically select points within a polygon region. This enables automated point selection without manual lasso interaction. This will trigger a `select` event (and `lassoEnd` event) unless `options.preventEvent === true`.
522+
523+
**Arguments:**
524+
525+
- `vertices` is an array of `[x, y]` coordinate pairs defining the polygon (minimum 3 vertices required). Coordinates are in **data space** by default (requires `xScale` and `yScale`), or **GL space** if `options.isGl === true`.
526+
- `options` [optional] is an object with the following properties:
527+
- `merge`: if `true`, add the selected points to the current selection instead of replacing it.
528+
- `remove`: if `true`, remove the selected points from the current selection.
529+
- `isGl`: if `true`, interpret vertices as GL space coordinates (NDC). If `false` (default), interpret vertices as data space coordinates.
530+
- `preventEvent`: if `true` the `select` and `lassoEnd` events will not be published.
531+
532+
**Notes:**
533+
534+
- Polygons are automatically closed if the first and last vertices differ.
535+
- Data space coordinates require `xScale` and `yScale` to be defined during scatterplot initialization.
536+
- GL space coordinates work without scales and are useful for direct NDC coordinate selection.
537+
538+
**Examples:**
539+
540+
```javascript
541+
import { scaleLinear } from 'd3-scale';
542+
543+
// Create scatterplot with scales for data space coordinates
544+
const scatterplot = createScatterplot({
545+
canvas,
546+
xScale: scaleLinear().domain([0, 100]),
547+
yScale: scaleLinear().domain([0, 100]),
548+
});
549+
550+
// Draw points (internally stored in NDC, but we think in data space)
551+
scatterplot.draw([
552+
[-0.8, -0.8], // corresponds to data coords ~[10, 10]
553+
[0.8, 0.8], // corresponds to data coords ~[90, 90]
554+
[0, 0], // corresponds to data coords [50, 50]
555+
]);
556+
557+
// Select points within a triangular region (data space coordinates)
558+
scatterplot.lassoSelect([
559+
[10, 20],
560+
[50, 80],
561+
[90, 30]
562+
]);
563+
564+
// Select points within a rectangle, merging with current selection
565+
scatterplot.lassoSelect(
566+
[
567+
[0, 0],
568+
[100, 0],
569+
[100, 100],
570+
[0, 100]
571+
],
572+
{ merge: true }
573+
);
574+
575+
// Remove points in a polygon from the current selection
576+
scatterplot.lassoSelect(
577+
[
578+
[40, 40],
579+
[60, 40],
580+
[60, 60],
581+
[40, 60]
582+
],
583+
{ remove: true }
584+
);
585+
586+
// Use GL space coordinates (useful without scales)
587+
scatterplot.lassoSelect(
588+
[
589+
[-0.5, -0.5],
590+
[0.5, -0.5],
591+
[0.5, 0.5],
592+
[-0.5, 0.5]
593+
],
594+
{ isGl: true }
595+
);
596+
```
597+
519598
<a name="scatterplot.deselect" href="#scatterplot.deselect">#</a> scatterplot.<b>deselect</b>(<i>options = {}</i>)
520599

521600
Deselect all selected points. This will trigger a `deselect` event unless `options.preventEvent === true`.

example/menu.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,13 @@ export function createMenu({
230230
active: pathname === 'annotations.html',
231231
});
232232

233+
examples.addBlade({
234+
view: 'link',
235+
label: 'Programmatic Lasso',
236+
link: 'programmatic-lasso.html',
237+
active: pathname === 'programmatic-lasso.html',
238+
});
239+
233240
examples.addBlade({
234241
view: 'link',
235242
label: 'Multiple Instances',

0 commit comments

Comments
 (0)