@neo4j-nvl/interaction-handlers 0.2.51 → 0.2.52

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.
@@ -4,8 +4,9 @@ import type { NVL } from '@neo4j-nvl/core';
4
4
  * @abstract
5
5
  * @internal
6
6
  */
7
- declare abstract class BaseInteraction<T extends Record<string, ((...args: unknown[]) => void) | boolean>> {
7
+ declare abstract class BaseInteraction<T extends Record<string, ((...args: unknown[]) => void) | boolean>, P extends Record<string, unknown>> {
8
8
  private readonly nvl;
9
+ private readonly options;
9
10
  private readonly container;
10
11
  /**
11
12
  * @internal
@@ -14,11 +15,12 @@ declare abstract class BaseInteraction<T extends Record<string, ((...args: unkno
14
15
  /**
15
16
  * @internal
16
17
  */
17
- constructor(nvl: NVL);
18
+ constructor(nvl: NVL, options: P);
18
19
  /**
19
20
  * @internal
20
21
  */
21
22
  get nvlInstance(): NVL;
23
+ get currentOptions(): P;
22
24
  /**
23
25
  * @internal
24
26
  */
@@ -34,7 +36,7 @@ declare abstract class BaseInteraction<T extends Record<string, ((...args: unkno
34
36
  /**
35
37
  * @internal
36
38
  */
37
- callCallbackIfRegistered: (name: keyof T | string, ...args: unknown[]) => void;
39
+ callCallbackIfRegistered: (name: keyof T, ...args: unknown[]) => void;
38
40
  /**
39
41
  * Add or update a callback for a given event of type.
40
42
  * @param name - The name of the event
@@ -7,13 +7,19 @@ class BaseInteraction {
7
7
  /**
8
8
  * @internal
9
9
  */
10
- constructor(nvl) {
10
+ constructor(nvl, options) {
11
11
  Object.defineProperty(this, "nvl", {
12
12
  enumerable: true,
13
13
  configurable: true,
14
14
  writable: true,
15
15
  value: void 0
16
16
  });
17
+ Object.defineProperty(this, "options", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: void 0
22
+ });
17
23
  Object.defineProperty(this, "container", {
18
24
  enumerable: true,
19
25
  configurable: true,
@@ -91,6 +97,7 @@ class BaseInteraction {
91
97
  }
92
98
  });
93
99
  this.nvl = nvl;
100
+ this.options = options;
94
101
  this.container = this.nvl.getContainer();
95
102
  this.callbackMap = new Map();
96
103
  }
@@ -100,6 +107,9 @@ class BaseInteraction {
100
107
  get nvlInstance() {
101
108
  return this.nvl;
102
109
  }
110
+ get currentOptions() {
111
+ return this.options;
112
+ }
103
113
  /**
104
114
  * @internal
105
115
  */
@@ -15,7 +15,7 @@ export type BoxSelectInteractionCallbacks = {
15
15
  * Called once when the user presses the mouse on the canvas, starting the box selection.
16
16
  * @param event - The original mouse event
17
17
  */
18
- onBoxStarted?: (event: MouseEvent) => void;
18
+ onBoxStarted?: ((event: MouseEvent) => void) | boolean;
19
19
  /**
20
20
  * Called after once the user releases the mouse after multi-selecting.
21
21
  * @param selectionObject - The selected nodes and relationships
@@ -40,12 +40,11 @@ export type BoxSelectInteractionCallbacks = {
40
40
  * console.log('Selected elements:', nodes, rels)
41
41
  * })
42
42
  */
43
- export declare class BoxSelectInteraction extends BaseInteraction<BoxSelectInteractionCallbacks> {
43
+ export declare class BoxSelectInteraction extends BaseInteraction<BoxSelectInteractionCallbacks, BoxSelectInteractionOptions> {
44
44
  private mousePosition;
45
45
  private startWorldPosition;
46
46
  private overlayRenderer;
47
47
  private isBoxSelecting;
48
- private readonly options;
49
48
  /**
50
49
  * Creates a new instance of the multi-select interaction handler.
51
50
  * @param nvl - The NVL instance to attach the interaction handler to
@@ -23,7 +23,7 @@ export class BoxSelectInteraction extends BaseInteraction {
23
23
  * @param options - Options for the multi-select interaction handler to customize its behavior
24
24
  */
25
25
  constructor(nvl, options = { selectOnRelease: false }) {
26
- super(nvl);
26
+ super(nvl, options);
27
27
  Object.defineProperty(this, "mousePosition", {
28
28
  enumerable: true,
29
29
  configurable: true,
@@ -48,12 +48,6 @@ export class BoxSelectInteraction extends BaseInteraction {
48
48
  writable: true,
49
49
  value: void 0
50
50
  });
51
- Object.defineProperty(this, "options", {
52
- enumerable: true,
53
- configurable: true,
54
- writable: true,
55
- value: void 0
56
- });
57
51
  Object.defineProperty(this, "handleMouseDown", {
58
52
  enumerable: true,
59
53
  configurable: true,
@@ -129,7 +123,7 @@ export class BoxSelectInteraction extends BaseInteraction {
129
123
  const endPosition = getCanvasPosition(this.containerInstance, event);
130
124
  const endWorldPosition = getWorldPosition(this.nvlInstance, endPosition);
131
125
  const { nodes, rels } = this.getHitsInBox(this.startWorldPosition, endWorldPosition);
132
- if (this.options.selectOnRelease) {
126
+ if (this.currentOptions.selectOnRelease) {
133
127
  this.nvlInstance.updateElementsInGraph(nodes.map((node) => ({ id: node.id, selected: true })), rels.map((rel) => ({ id: rel.id, selected: true })));
134
128
  }
135
129
  this.callCallbackIfRegistered('onBoxSelect', { nodes, rels }, event);
@@ -139,7 +133,6 @@ export class BoxSelectInteraction extends BaseInteraction {
139
133
  this.startWorldPosition = { x: 0, y: 0 };
140
134
  this.overlayRenderer = new OverlayRenderer(this.containerInstance);
141
135
  this.isBoxSelecting = false;
142
- this.options = options;
143
136
  this.addEventListener('mousedown', this.handleMouseDown, true);
144
137
  this.addEventListener('mousemove', this.handleDrag, true);
145
138
  this.addEventListener('mouseup', this.endBoxSelect, true);
@@ -164,7 +157,7 @@ export class BoxSelectInteraction extends BaseInteraction {
164
157
  }
165
158
  else {
166
159
  this.isBoxSelecting = true;
167
- if (this.options.selectOnRelease) {
160
+ if (this.currentOptions.selectOnRelease) {
168
161
  this.nvlInstance.deselectAll();
169
162
  }
170
163
  }
@@ -88,9 +88,8 @@ export type ClickInteractionCallbacks = {
88
88
  * })
89
89
  * ```
90
90
  */
91
- export declare class ClickInteraction extends BaseInteraction<ClickInteractionCallbacks> {
91
+ export declare class ClickInteraction extends BaseInteraction<ClickInteractionCallbacks, ClickInteractionOptions> {
92
92
  private moved;
93
- private readonly options;
94
93
  private mousePosition;
95
94
  /**
96
95
  * Creates a new click interaction handler.
@@ -23,19 +23,13 @@ export class ClickInteraction extends BaseInteraction {
23
23
  * @param options - Options for the click interaction handler
24
24
  */
25
25
  constructor(nvl, options = { selectOnClick: false }) {
26
- super(nvl);
26
+ super(nvl, options);
27
27
  Object.defineProperty(this, "moved", {
28
28
  enumerable: true,
29
29
  configurable: true,
30
30
  writable: true,
31
31
  value: void 0
32
32
  });
33
- Object.defineProperty(this, "options", {
34
- enumerable: true,
35
- configurable: true,
36
- writable: true,
37
- value: void 0
38
- });
39
33
  Object.defineProperty(this, "mousePosition", {
40
34
  enumerable: true,
41
35
  configurable: true,
@@ -100,7 +94,7 @@ export class ClickInteraction extends BaseInteraction {
100
94
  const { nvlTargets } = this.nvlInstance.getHits(event);
101
95
  const { nodes = [], relationships = [] } = nvlTargets;
102
96
  if (nodes.length === 0 && relationships.length === 0) {
103
- if (this.options.selectOnClick) {
97
+ if (this.currentOptions.selectOnClick) {
104
98
  this.nvlInstance.deselectAll();
105
99
  }
106
100
  this.callCallbackIfRegistered('onCanvasClick', event);
@@ -108,7 +102,7 @@ export class ClickInteraction extends BaseInteraction {
108
102
  }
109
103
  if (nodes.length > 0) {
110
104
  const hitNodeData = nodes.map((node) => node.data);
111
- if (this.options.selectOnClick) {
105
+ if (this.currentOptions.selectOnClick) {
112
106
  const selectedNodes = this.nvlInstance.getSelectedNodes();
113
107
  const selectedRelationships = this.nvlInstance.getSelectedRelationships();
114
108
  const nodeUpdates = [
@@ -122,7 +116,7 @@ export class ClickInteraction extends BaseInteraction {
122
116
  }
123
117
  else if (relationships.length > 0) {
124
118
  const hitRelationshipData = relationships.map((relationship) => relationship.data);
125
- if (this.options.selectOnClick) {
119
+ if (this.currentOptions.selectOnClick) {
126
120
  const selectedNodes = this.nvlInstance.getSelectedNodes();
127
121
  const selectedRelationships = this.nvlInstance.getSelectedRelationships();
128
122
  const nodeUpdates = selectedNodes.map((node) => ({ id: node.id, selected: false }));
@@ -150,7 +144,6 @@ export class ClickInteraction extends BaseInteraction {
150
144
  this.removeEventListener('contextmenu', this.handleRightClick, true);
151
145
  }
152
146
  });
153
- this.options = options;
154
147
  this.mousePosition = { x: 0, y: 0 };
155
148
  this.addEventListener('mousedown', this.handleMouseDown, true);
156
149
  this.addEventListener('click', this.handleClick, true);
@@ -15,13 +15,13 @@ export type DragNodeInteractionCallbacks = {
15
15
  * @param nodes - The node(s) being dragged
16
16
  * @param event - The original mouse event
17
17
  */
18
- onDragStart?: (nodes: Node[], evt: MouseEvent) => void;
18
+ onDragStart?: ((nodes: Node[], evt: MouseEvent) => void) | boolean;
19
19
  /**
20
20
  * Called once when node(s) are finished being dragged
21
21
  * @param nodes - The node(s) being dragged
22
22
  * @param event - The original mouse event
23
23
  */
24
- onDragEnd?: (nodes: Node[], evt: MouseEvent) => void;
24
+ onDragEnd?: ((nodes: Node[], evt: MouseEvent) => void) | boolean;
25
25
  };
26
26
  /**
27
27
  * Interaction handler for dragging nodes.
@@ -38,7 +38,7 @@ export type DragNodeInteractionCallbacks = {
38
38
  * })
39
39
  * ```
40
40
  */
41
- export declare class DragNodeInteraction extends BaseInteraction<DragNodeInteractionCallbacks> {
41
+ export declare class DragNodeInteraction extends BaseInteraction<DragNodeInteractionCallbacks, Record<string, never>> {
42
42
  private mousePosition;
43
43
  private mouseDownNode;
44
44
  private isDragging;
@@ -49,7 +49,7 @@ export declare class DragNodeInteraction extends BaseInteraction<DragNodeInterac
49
49
  * Creates a new instance of the drag node interaction handler.
50
50
  * @param nvl - The NVL instance to attach the interaction handler to
51
51
  */
52
- constructor(nvl: NVL);
52
+ constructor(nvl: NVL, options?: {});
53
53
  private handleMouseDown;
54
54
  private handleMouseMove;
55
55
  private handleMouseUp;
@@ -21,8 +21,8 @@ export class DragNodeInteraction extends BaseInteraction {
21
21
  * Creates a new instance of the drag node interaction handler.
22
22
  * @param nvl - The NVL instance to attach the interaction handler to
23
23
  */
24
- constructor(nvl) {
25
- super(nvl);
24
+ constructor(nvl, options = {}) {
25
+ super(nvl, options);
26
26
  Object.defineProperty(this, "mousePosition", {
27
27
  enumerable: true,
28
28
  configurable: true,
@@ -5,14 +5,14 @@ import { BaseInteraction } from './base';
5
5
  * @experimental
6
6
  */
7
7
  export type DrawInteractionCallbacks = {
8
+ onHoverNodeMargin?: ((hoveredNode: Node | null, evt: MouseEvent) => void) | boolean;
8
9
  onDrawEnd?: ((newRelationshipToAdd: Relationship | null, newTargetNodeToAdd: Node | null, event: MouseEvent) => void) | boolean;
9
10
  };
10
11
  /**
11
12
  * @internal
12
13
  * @experimental
13
14
  */
14
- export declare class DrawInteraction extends BaseInteraction<DrawInteractionCallbacks> {
15
- private overlayRenderer;
15
+ export declare class DrawInteraction extends BaseInteraction<DrawInteractionCallbacks, Record<string, never>> {
16
16
  private isMoved;
17
17
  private isDrawing;
18
18
  private isDraggingNode;
@@ -23,9 +23,8 @@ export declare class DrawInteraction extends BaseInteraction<DrawInteractionCall
23
23
  private newTempSelfReferredRelationship;
24
24
  private newTargetNodeToAdd;
25
25
  private newRelationshipToAdd;
26
- constructor(nvl: NVL);
26
+ constructor(nvl: NVL, options?: {});
27
27
  private handleMouseMove;
28
- private handleWheel;
29
28
  private setNewRegularRelationship;
30
29
  private setNewRegularRelationshipToNewTempTargetNode;
31
30
  private setNewRegularRelationshipToExistingNode;
@@ -1,5 +1,5 @@
1
+ /* eslint-disable @typescript-eslint/strict-boolean-expressions */
1
2
  import { NODE_EDGE_WIDTH } from '../constants';
2
- import { OverlayRenderer } from '../overlay-renderer/overlay-renderer';
3
3
  import { BaseInteraction } from './base';
4
4
  import { generateUniqueId, getCanvasPosition, getWorldPosition } from './utils';
5
5
  /**
@@ -7,14 +7,8 @@ import { generateUniqueId, getCanvasPosition, getWorldPosition } from './utils';
7
7
  * @experimental
8
8
  */
9
9
  export class DrawInteraction extends BaseInteraction {
10
- constructor(nvl) {
11
- super(nvl);
12
- Object.defineProperty(this, "overlayRenderer", {
13
- enumerable: true,
14
- configurable: true,
15
- writable: true,
16
- value: void 0
17
- });
10
+ constructor(nvl, options = {}) {
11
+ super(nvl, options);
18
12
  Object.defineProperty(this, "isMoved", {
19
13
  enumerable: true,
20
14
  configurable: true,
@@ -83,11 +77,10 @@ export class DrawInteraction extends BaseInteraction {
83
77
  var _a, _b, _c, _d, _e, _f;
84
78
  this.isMoved = true;
85
79
  if (this.isDrawing) {
86
- this.overlayRenderer.clear();
87
80
  const canvasPos = getCanvasPosition(this.containerInstance, event);
88
81
  const pos = getWorldPosition(this.nvlInstance, canvasPos);
89
82
  const hits = this.nvlInstance.getHits(event, ['node']);
90
- const hitNode = hits.nvlTargets.nodes.filter((n) => n.data.id !== this.newTempTargetNode.id)[0];
83
+ const [hitNode] = hits.nvlTargets.nodes.filter((n) => n.data.id !== this.newTempTargetNode.id);
91
84
  const targetNode = hitNode
92
85
  ? {
93
86
  id: hitNode.data.id,
@@ -96,7 +89,9 @@ export class DrawInteraction extends BaseInteraction {
96
89
  size: hitNode.data.size
97
90
  }
98
91
  : undefined;
99
- // ArrowBundler has race-condition to update the dataset, if we remove the node with the same ID after mouse releases, the same node will be removed then be added again, which will cause the issue.
92
+ // ArrowBundler has race-condition to update the dataset,
93
+ // if we remove the node with the same ID after mouse releases,
94
+ // the same node will be removed then be added again, which will cause the issue.
100
95
  // So always make sure the new node id to be added to the dataset after mouse releasing is a new id.
101
96
  const newTargetNodeId = generateUniqueId(13);
102
97
  const newTargetNode = targetNode ? null : { id: newTargetNodeId, size: 25, selected: false, x: pos.x, y: pos.y };
@@ -155,30 +150,21 @@ export class DrawInteraction extends BaseInteraction {
155
150
  const hits = this.nvlInstance.getHits(event, ['node'], { hitNodeMarginWidth: NODE_EDGE_WIDTH });
156
151
  const hitNodeEdges = hits.nvlTargets.nodes.filter((node) => !node.insideNode);
157
152
  if (hitNodeEdges.length > 0) {
158
- const node = hitNodeEdges[0];
159
- const zoom = this.nvlInstance.getScale();
160
- const { x, y } = this.nvlInstance.getPan();
161
- this.overlayRenderer.drawNodeRing(node.targetCoordinates.x, node.targetCoordinates.y, node.data.size, zoom, x, y);
153
+ const [node] = hitNodeEdges;
154
+ this.callCallbackIfRegistered('onHoverNodeMargin', node.data);
162
155
  }
163
156
  else {
164
- this.overlayRenderer.clear();
157
+ this.callCallbackIfRegistered('onHoverNodeMargin', null);
165
158
  }
166
159
  }
167
160
  }
168
161
  });
169
- Object.defineProperty(this, "handleWheel", {
170
- enumerable: true,
171
- configurable: true,
172
- writable: true,
173
- value: () => {
174
- this.overlayRenderer.clear();
175
- }
176
- });
177
162
  Object.defineProperty(this, "handleMouseDown", {
178
163
  enumerable: true,
179
164
  configurable: true,
180
165
  writable: true,
181
166
  value: (event) => {
167
+ this.callCallbackIfRegistered('onHoverNodeMargin', null);
182
168
  this.isMoved = false;
183
169
  this.newRelationshipToAdd = null;
184
170
  this.newTargetNodeToAdd = null;
@@ -226,8 +212,10 @@ export class DrawInteraction extends BaseInteraction {
226
212
  ]);
227
213
  this.nvlInstance.removeNodesWithIds([(_d = this.newTempTargetNode) === null || _d === void 0 ? void 0 : _d.id]);
228
214
  if (this.isDrawing && this.isMoved) {
229
- this.newTargetNodeToAdd && this.nvlInstance.setNodePositions([this.newTargetNodeToAdd]);
230
- // Avoid relationship glitch
215
+ if (this.newTargetNodeToAdd) {
216
+ this.nvlInstance.setNodePositions([this.newTargetNodeToAdd]);
217
+ }
218
+ // Avoid relationship glitch.
231
219
  this.nvlInstance.addAndUpdateElementsInGraph(this.newTargetNodeToAdd ? [{ id: this.newTargetNodeToAdd.id }] : [], [this.newRelationshipToAdd]);
232
220
  this.callCallbackIfRegistered('onDrawEnd', this.newRelationshipToAdd, this.newTargetNodeToAdd, event);
233
221
  }
@@ -238,7 +226,6 @@ export class DrawInteraction extends BaseInteraction {
238
226
  this.isMoved = false;
239
227
  this.isDrawing = false;
240
228
  this.isDraggingNode = false;
241
- this.overlayRenderer.clear();
242
229
  }
243
230
  });
244
231
  Object.defineProperty(this, "destroy", {
@@ -247,25 +234,21 @@ export class DrawInteraction extends BaseInteraction {
247
234
  writable: true,
248
235
  value: () => {
249
236
  this.removeEventListener('mousemove', this.handleMouseMove, true);
250
- this.removeEventListener('wheel', this.handleWheel, true);
251
237
  this.removeEventListener('mousedown', this.handleMouseDown, true);
252
238
  this.removeEventListener('mouseup', this.handleMouseUp, true);
253
- this.overlayRenderer.destroy();
254
239
  }
255
240
  });
256
- this.overlayRenderer = new OverlayRenderer(this.containerInstance);
257
241
  this.isMoved = false;
258
242
  this.isDrawing = false;
259
243
  this.isDraggingNode = false;
260
244
  this.nvlInstance.setLayout('free');
261
245
  this.addEventListener('mousemove', this.handleMouseMove, true);
262
- this.addEventListener('wheel', this.handleWheel, true);
263
246
  this.addEventListener('mousedown', this.handleMouseDown, true);
264
247
  this.addEventListener('mouseup', this.handleMouseUp, true);
265
248
  }
266
249
  setNewRegularRelationship(targetId) {
267
250
  if (!this.mouseDownNode) {
268
- return;
251
+ return null;
269
252
  }
270
253
  return {
271
254
  id: generateUniqueId(13),
@@ -39,11 +39,10 @@ export type HoverInteractionCallbacks = {
39
39
  * })
40
40
  * ```
41
41
  */
42
- export declare class HoverInteraction extends BaseInteraction<HoverInteractionCallbacks> {
42
+ export declare class HoverInteraction extends BaseInteraction<HoverInteractionCallbacks, HoverInteractionOptions> {
43
43
  private currentHoveredElement;
44
44
  private currentHoveredElementIsNode;
45
45
  private readonly updates;
46
- private readonly options;
47
46
  constructor(nvl: NVL, options?: HoverInteractionOptions);
48
47
  /**
49
48
  * Handle mouse hover events
@@ -16,7 +16,7 @@ import { BaseInteraction } from './base';
16
16
  */
17
17
  export class HoverInteraction extends BaseInteraction {
18
18
  constructor(nvl, options = { drawShadowOnHover: false }) {
19
- super(nvl);
19
+ super(nvl, options);
20
20
  Object.defineProperty(this, "currentHoveredElement", {
21
21
  enumerable: true,
22
22
  configurable: true,
@@ -35,12 +35,6 @@ export class HoverInteraction extends BaseInteraction {
35
35
  writable: true,
36
36
  value: void 0
37
37
  });
38
- Object.defineProperty(this, "options", {
39
- enumerable: true,
40
- configurable: true,
41
- writable: true,
42
- value: void 0
43
- });
44
38
  /**
45
39
  * Handle mouse hover events
46
40
  * @param {MouseEvent} event - The mouse event
@@ -64,6 +58,7 @@ export class HoverInteraction extends BaseInteraction {
64
58
  this.currentHoveredElementIsNode = true;
65
59
  }
66
60
  else if (mainTarget !== undefined) {
61
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
67
62
  const { id, from, to } = hoveredElement;
68
63
  this.updates.relationships.push({ id, from, to, hovered: true });
69
64
  this.currentHoveredElement = hoveredElement;
@@ -75,7 +70,7 @@ export class HoverInteraction extends BaseInteraction {
75
70
  }
76
71
  this.callCallbackIfRegistered('onHover', this.currentHoveredElement, nvlTargets, event);
77
72
  // Use pure update API to avoid the previous removed node to be re-added to the scene.
78
- if (this.options.drawShadowOnHover) {
73
+ if (this.currentOptions.drawShadowOnHover) {
79
74
  const currentNodes = this.nvlInstance.getNodes();
80
75
  if (currentNodes.length > 0) {
81
76
  this.nvlInstance.updateElementsInGraph(this.updates.nodes, this.updates.relationships);
@@ -88,7 +83,6 @@ export class HoverInteraction extends BaseInteraction {
88
83
  nodes: [],
89
84
  relationships: []
90
85
  };
91
- this.options = options;
92
86
  this.addEventListener('mousemove', this.handleHover, true);
93
87
  }
94
88
  clearUpdates() {
@@ -107,6 +101,7 @@ export class HoverInteraction extends BaseInteraction {
107
101
  this.updates.nodes.push(update);
108
102
  }
109
103
  else {
104
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
110
105
  const { from, to } = this.currentHoveredElement;
111
106
  this.updates.relationships.push(Object.assign(Object.assign({}, update), { from, to }));
112
107
  }
@@ -15,7 +15,7 @@ export type LassoInteractionCallbacks = {
15
15
  * Called once when the user presses the mouse on the canvas, starting the lasso.
16
16
  * @param event - The original mouse event
17
17
  */
18
- onLassoStarted?: (event: MouseEvent) => void;
18
+ onLassoStarted?: ((event: MouseEvent) => void) | boolean;
19
19
  /**
20
20
  * Called once when the user releases the mouse after lasso selecting.
21
21
  * @param selectionObject - The selected node and relationship ids
@@ -40,11 +40,10 @@ export type LassoInteractionCallbacks = {
40
40
  * console.log('Selected elements:', nodes, rels)
41
41
  * })
42
42
  */
43
- export declare class LassoInteraction extends BaseInteraction<LassoInteractionCallbacks> {
43
+ export declare class LassoInteraction extends BaseInteraction<LassoInteractionCallbacks, LassoInteractionOptions> {
44
44
  private active;
45
45
  private points;
46
46
  private overlayRenderer;
47
- private readonly options;
48
47
  /**
49
48
  * Creates a new instance of the lasso interaction handler.
50
49
  * @param nvl - The NVL instance to attach the interaction handler to
@@ -25,7 +25,7 @@ export class LassoInteraction extends BaseInteraction {
25
25
  * @param options - Options for the lasso interaction handler to customize its behavior
26
26
  */
27
27
  constructor(nvl, options = { selectOnRelease: false }) {
28
- super(nvl);
28
+ super(nvl, options);
29
29
  Object.defineProperty(this, "active", {
30
30
  enumerable: true,
31
31
  configurable: true,
@@ -44,12 +44,6 @@ export class LassoInteraction extends BaseInteraction {
44
44
  writable: true,
45
45
  value: void 0
46
46
  });
47
- Object.defineProperty(this, "options", {
48
- enumerable: true,
49
- configurable: true,
50
- writable: true,
51
- value: void 0
52
- });
53
47
  Object.defineProperty(this, "startLasso", {
54
48
  enumerable: true,
55
49
  configurable: true,
@@ -154,7 +148,7 @@ export class LassoInteraction extends BaseInteraction {
154
148
  this.overlayRenderer.drawLasso(hull, false, true);
155
149
  setTimeout(() => this.overlayRenderer.clear(), shapeShowTime);
156
150
  const hitItems = this.getLassoItems(hull);
157
- if (this.options.selectOnRelease) {
151
+ if (this.currentOptions.selectOnRelease) {
158
152
  this.nvlInstance.updateElementsInGraph(hitItems.nodes.map((node) => ({ id: node.id, selected: true })), hitItems.rels.map((rel) => ({ id: rel.id, selected: true })));
159
153
  }
160
154
  this.callCallbackIfRegistered('onLassoSelect', hitItems, event);
@@ -162,7 +156,6 @@ export class LassoInteraction extends BaseInteraction {
162
156
  });
163
157
  this.overlayRenderer = new OverlayRenderer(this.containerInstance);
164
158
  this.active = false;
165
- this.options = options;
166
159
  this.addEventListener('mousedown', this.handleMouseDown, true);
167
160
  this.addEventListener('mousemove', this.handleDrag, true);
168
161
  this.addEventListener('mouseup', this.handleMouseUp, true);
@@ -37,10 +37,9 @@ export type PanInteractionCallbacks = {
37
37
  * console.log('Panning:', panning)
38
38
  * })
39
39
  */
40
- export declare class PanInteraction extends BaseInteraction<PanInteractionCallbacks> {
40
+ export declare class PanInteraction extends BaseInteraction<PanInteractionCallbacks, PanInteractionOptions> {
41
41
  private mousePosition;
42
42
  private targets;
43
- private readonly options;
44
43
  private shouldPan;
45
44
  /**
46
45
  * Creates a new instance of the pan interaction handler.
@@ -20,7 +20,7 @@ export class PanInteraction extends BaseInteraction {
20
20
  * @param nvl - The NVL instance to attach the interaction handler to
21
21
  */
22
22
  constructor(nvl, options = { excludeNodeMargin: false }) {
23
- super(nvl);
23
+ super(nvl, options);
24
24
  Object.defineProperty(this, "mousePosition", {
25
25
  enumerable: true,
26
26
  configurable: true,
@@ -33,12 +33,6 @@ export class PanInteraction extends BaseInteraction {
33
33
  writable: true,
34
34
  value: void 0
35
35
  });
36
- Object.defineProperty(this, "options", {
37
- enumerable: true,
38
- configurable: true,
39
- writable: true,
40
- value: void 0
41
- });
42
36
  Object.defineProperty(this, "shouldPan", {
43
37
  enumerable: true,
44
38
  configurable: true,
@@ -63,7 +57,7 @@ export class PanInteraction extends BaseInteraction {
63
57
  writable: true,
64
58
  value: (targets, excludeNodeMargin) => {
65
59
  this.targets = targets;
66
- this.options.excludeNodeMargin = excludeNodeMargin;
60
+ this.currentOptions.excludeNodeMargin = excludeNodeMargin;
67
61
  }
68
62
  });
69
63
  Object.defineProperty(this, "handleMouseDown", {
@@ -72,7 +66,7 @@ export class PanInteraction extends BaseInteraction {
72
66
  writable: true,
73
67
  value: (event) => {
74
68
  const hits = this.nvlInstance.getHits(event, difference(['node', 'relationship'], this.targets), {
75
- hitNodeMarginWidth: this.options.excludeNodeMargin ? NODE_EDGE_WIDTH : 0
69
+ hitNodeMarginWidth: this.currentOptions.excludeNodeMargin ? NODE_EDGE_WIDTH : 0
76
70
  });
77
71
  if (hits.nvlTargets.nodes.length > 0 || hits.nvlTargets.relationships.length > 0) {
78
72
  this.shouldPan = false;
@@ -110,7 +104,6 @@ export class PanInteraction extends BaseInteraction {
110
104
  });
111
105
  this.mousePosition = { x: 0, y: 0 };
112
106
  this.targets = [];
113
- this.options = options;
114
107
  this.shouldPan = false;
115
108
  this.addEventListener('mousedown', this.handleMouseDown, true);
116
109
  this.addEventListener('mousemove', this.handleMouseMove, true);
@@ -25,12 +25,12 @@ export type ZoomInteractionCallbacks = {
25
25
  * })
26
26
  * ```
27
27
  */
28
- export declare class ZoomInteraction extends BaseInteraction<ZoomInteractionCallbacks> {
28
+ export declare class ZoomInteraction extends BaseInteraction<ZoomInteractionCallbacks, Record<string, never>> {
29
29
  /**
30
30
  * Creates a new instance of the zoom interaction handler.
31
31
  * @param nvl - The NVL instance to attach the interaction handler to
32
32
  */
33
- constructor(nvl: NVL);
33
+ constructor(nvl: NVL, options?: {});
34
34
  /**
35
35
  * Throttled zoom function to avoid events happening too fast.
36
36
  * @param event - The original mouse wheel event
@@ -20,8 +20,8 @@ export class ZoomInteraction extends BaseInteraction {
20
20
  * Creates a new instance of the zoom interaction handler.
21
21
  * @param nvl - The NVL instance to attach the interaction handler to
22
22
  */
23
- constructor(nvl) {
24
- super(nvl);
23
+ constructor(nvl, options = {}) {
24
+ super(nvl, options);
25
25
  /**
26
26
  * Throttled zoom function to avoid events happening too fast.
27
27
  * @param event - The original mouse wheel event
@@ -4,13 +4,11 @@ export declare class OverlayRenderer {
4
4
  private removeResizeListener;
5
5
  constructor(canvasParent: HTMLElement);
6
6
  private fixCanvasSize;
7
- private zoomAndPan;
8
7
  drawBox(startX: number, startY: number, endX: number, endY: number): void;
9
8
  drawLasso(points: {
10
9
  x: number;
11
10
  y: number;
12
11
  }[], stroke: boolean, fill: boolean): void;
13
- drawNodeRing(x: number, y: number, radius: number, zoom: number, panX: number, panY: number): void;
14
12
  clear(): void;
15
13
  destroy(): void;
16
14
  }
@@ -1,4 +1,3 @@
1
- import { drawCircleBand } from '@neo4j-nvl/core';
2
1
  import onResize from 'resizelistener';
3
2
  const marquee = {
4
3
  frameWidth: 2,
@@ -35,8 +34,6 @@ export class OverlayRenderer {
35
34
  canvas.style.right = '0';
36
35
  // These are needed for touchpad zoom on Edge
37
36
  canvas.style.touchAction = 'none';
38
- // @ts-expect-error revisit later
39
- canvas.style.msTouchAction = 'none';
40
37
  canvasParent.appendChild(canvas);
41
38
  const context = canvas.getContext('2d');
42
39
  this.ctx = context;
@@ -57,16 +54,6 @@ export class OverlayRenderer {
57
54
  canvas.style.width = `${width}px`;
58
55
  canvas.style.height = `${height}px`;
59
56
  }
60
- // Can be extracted as a util
61
- zoomAndPan(zoom, panX, panY) {
62
- const { ctx, canvas } = this;
63
- const { width, height } = canvas;
64
- ctx.translate((-width / 2) * zoom, (-height / 2) * zoom);
65
- ctx.translate(-panX * zoom, -panY * zoom);
66
- ctx.scale(zoom, zoom);
67
- ctx.translate(width / 2 / zoom, height / 2 / zoom);
68
- ctx.translate(width / 2, height / 2);
69
- }
70
57
  drawBox(startX, startY, endX, endY) {
71
58
  const { ctx } = this;
72
59
  if (ctx === null) {
@@ -116,17 +103,6 @@ export class OverlayRenderer {
116
103
  }
117
104
  ctx.restore();
118
105
  }
119
- drawNodeRing(x, y, radius, zoom, panX, panY) {
120
- const { ctx } = this;
121
- this.clear();
122
- ctx.save();
123
- const devicePixelRatio = window.devicePixelRatio || 1;
124
- this.zoomAndPan(zoom, panX, panY);
125
- // TODO: make 0.2 configurable from state and same as colour
126
- const width = (radius !== null && radius !== void 0 ? radius : 25) * devicePixelRatio * 0.2;
127
- drawCircleBand(ctx, x, y, (radius !== null && radius !== void 0 ? radius : 25) * devicePixelRatio, [{ width, color: 'blue' }]);
128
- ctx.restore();
129
- }
130
106
  clear() {
131
107
  const { ctx, canvas } = this;
132
108
  if (ctx === null) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neo4j-nvl/interaction-handlers",
3
- "version": "0.2.51",
3
+ "version": "0.2.52",
4
4
  "license": "SEE LICENSE IN 'Neo4j Early Access Agreement - Visualization Library.pdf'",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",