@neo4j-nvl/interaction-handlers 0.2.53 → 0.2.54
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.
- package/lib/index.d.ts +2 -2
- package/lib/interaction-handlers/base.js +43 -88
- package/lib/interaction-handlers/box-select-interaction.js +63 -106
- package/lib/interaction-handlers/click-interaction.js +92 -120
- package/lib/interaction-handlers/drag-node-interaction.js +88 -138
- package/lib/interaction-handlers/draw-interaction.d.ts +8 -2
- package/lib/interaction-handlers/draw-interaction.js +180 -231
- package/lib/interaction-handlers/hover-interaction.js +47 -64
- package/lib/interaction-handlers/lasso-interaction.js +92 -127
- package/lib/interaction-handlers/pan-interaction.js +46 -81
- package/lib/interaction-handlers/zoom-interaction.js +32 -47
- package/lib/overlay-renderer/overlay-renderer.js +14 -24
- package/package.json +4 -4
package/lib/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { ClickInteraction } from './interaction-handlers/click-interaction';
|
|
|
5
5
|
import { DragNodeInteraction } from './interaction-handlers/drag-node-interaction';
|
|
6
6
|
import type { DragNodeInteractionCallbacks } from './interaction-handlers/drag-node-interaction';
|
|
7
7
|
import { DrawInteraction } from './interaction-handlers/draw-interaction';
|
|
8
|
-
import type { DrawInteractionCallbacks } from './interaction-handlers/draw-interaction';
|
|
8
|
+
import type { DrawInteractionCallbacks, DrawInteractionOptions } from './interaction-handlers/draw-interaction';
|
|
9
9
|
import type { HoverInteractionCallbacks, HoverInteractionOptions } from './interaction-handlers/hover-interaction';
|
|
10
10
|
import { HoverInteraction } from './interaction-handlers/hover-interaction';
|
|
11
11
|
import { LassoInteraction } from './interaction-handlers/lasso-interaction';
|
|
@@ -14,5 +14,5 @@ import type { PanInteractionCallbacks, PanInteractionOptions } from './interacti
|
|
|
14
14
|
import { PanInteraction } from './interaction-handlers/pan-interaction';
|
|
15
15
|
import type { ZoomInteractionCallbacks } from './interaction-handlers/zoom-interaction';
|
|
16
16
|
import { ZoomInteraction } from './interaction-handlers/zoom-interaction';
|
|
17
|
-
export type { BoxSelectInteractionOptions, BoxSelectInteractionCallbacks, ClickInteractionOptions, HoverInteractionOptions, HoverInteractionCallbacks, DragNodeInteractionCallbacks, ClickInteractionCallbacks, PanInteractionCallbacks, DrawInteractionCallbacks, PanInteractionOptions, ZoomInteractionCallbacks, LassoInteractionOptions, LassoInteractionCallbacks };
|
|
17
|
+
export type { BoxSelectInteractionOptions, BoxSelectInteractionCallbacks, ClickInteractionOptions, HoverInteractionOptions, HoverInteractionCallbacks, DragNodeInteractionCallbacks, ClickInteractionCallbacks, PanInteractionCallbacks, DrawInteractionCallbacks, PanInteractionOptions, ZoomInteractionCallbacks, LassoInteractionOptions, LassoInteractionCallbacks, DrawInteractionOptions };
|
|
18
18
|
export { ZoomInteraction, PanInteraction, BoxSelectInteraction, ClickInteraction, HoverInteraction, DragNodeInteraction, DrawInteraction, LassoInteraction };
|
|
@@ -4,98 +4,17 @@
|
|
|
4
4
|
* @internal
|
|
5
5
|
*/
|
|
6
6
|
class BaseInteraction {
|
|
7
|
+
nvl;
|
|
8
|
+
options;
|
|
9
|
+
container;
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
callbackMap;
|
|
7
14
|
/**
|
|
8
15
|
* @internal
|
|
9
16
|
*/
|
|
10
17
|
constructor(nvl, options) {
|
|
11
|
-
Object.defineProperty(this, "nvl", {
|
|
12
|
-
enumerable: true,
|
|
13
|
-
configurable: true,
|
|
14
|
-
writable: true,
|
|
15
|
-
value: void 0
|
|
16
|
-
});
|
|
17
|
-
Object.defineProperty(this, "options", {
|
|
18
|
-
enumerable: true,
|
|
19
|
-
configurable: true,
|
|
20
|
-
writable: true,
|
|
21
|
-
value: void 0
|
|
22
|
-
});
|
|
23
|
-
Object.defineProperty(this, "container", {
|
|
24
|
-
enumerable: true,
|
|
25
|
-
configurable: true,
|
|
26
|
-
writable: true,
|
|
27
|
-
value: void 0
|
|
28
|
-
});
|
|
29
|
-
/**
|
|
30
|
-
* @internal
|
|
31
|
-
*/
|
|
32
|
-
Object.defineProperty(this, "callbackMap", {
|
|
33
|
-
enumerable: true,
|
|
34
|
-
configurable: true,
|
|
35
|
-
writable: true,
|
|
36
|
-
value: void 0
|
|
37
|
-
});
|
|
38
|
-
/**
|
|
39
|
-
* @internal
|
|
40
|
-
*/
|
|
41
|
-
Object.defineProperty(this, "addEventListener", {
|
|
42
|
-
enumerable: true,
|
|
43
|
-
configurable: true,
|
|
44
|
-
writable: true,
|
|
45
|
-
value: (type, listener, options) => {
|
|
46
|
-
this.container.addEventListener(type, listener, options);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
/**
|
|
50
|
-
* @internal
|
|
51
|
-
*/
|
|
52
|
-
Object.defineProperty(this, "removeEventListener", {
|
|
53
|
-
enumerable: true,
|
|
54
|
-
configurable: true,
|
|
55
|
-
writable: true,
|
|
56
|
-
value: (type, listener, options) => {
|
|
57
|
-
this.container.removeEventListener(type, listener, options);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
/**
|
|
61
|
-
* @internal
|
|
62
|
-
*/
|
|
63
|
-
Object.defineProperty(this, "callCallbackIfRegistered", {
|
|
64
|
-
enumerable: true,
|
|
65
|
-
configurable: true,
|
|
66
|
-
writable: true,
|
|
67
|
-
value: (name, ...args) => {
|
|
68
|
-
const callback = this.callbackMap.get(name);
|
|
69
|
-
if (typeof callback === 'function') {
|
|
70
|
-
callback(...args);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
/**
|
|
75
|
-
* Add or update a callback for a given event of type.
|
|
76
|
-
* @param name - The name of the event
|
|
77
|
-
* @param callback - The callback to be called when the event is triggered
|
|
78
|
-
*/
|
|
79
|
-
Object.defineProperty(this, "updateCallback", {
|
|
80
|
-
enumerable: true,
|
|
81
|
-
configurable: true,
|
|
82
|
-
writable: true,
|
|
83
|
-
value: (name, callback) => {
|
|
84
|
-
this.callbackMap.set(name, callback);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
/**
|
|
88
|
-
* Remove a callback for a given event of type.
|
|
89
|
-
* @param name - The name of the event
|
|
90
|
-
*/
|
|
91
|
-
Object.defineProperty(this, "removeCallback", {
|
|
92
|
-
enumerable: true,
|
|
93
|
-
configurable: true,
|
|
94
|
-
writable: true,
|
|
95
|
-
value: (name) => {
|
|
96
|
-
this.callbackMap.delete(name);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
18
|
this.nvl = nvl;
|
|
100
19
|
this.options = options;
|
|
101
20
|
this.container = this.nvl.getContainer();
|
|
@@ -116,5 +35,41 @@ class BaseInteraction {
|
|
|
116
35
|
get containerInstance() {
|
|
117
36
|
return this.container;
|
|
118
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
addEventListener = (type, listener, options) => {
|
|
42
|
+
this.container.addEventListener(type, listener, options);
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
removeEventListener = (type, listener, options) => {
|
|
48
|
+
this.container.removeEventListener(type, listener, options);
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
53
|
+
callCallbackIfRegistered = (name, ...args) => {
|
|
54
|
+
const callback = this.callbackMap.get(name);
|
|
55
|
+
if (typeof callback === 'function') {
|
|
56
|
+
callback(...args);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Add or update a callback for a given event of type.
|
|
61
|
+
* @param name - The name of the event
|
|
62
|
+
* @param callback - The callback to be called when the event is triggered
|
|
63
|
+
*/
|
|
64
|
+
updateCallback = (name, callback) => {
|
|
65
|
+
this.callbackMap.set(name, callback);
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Remove a callback for a given event of type.
|
|
69
|
+
* @param name - The name of the event
|
|
70
|
+
*/
|
|
71
|
+
removeCallback = (name) => {
|
|
72
|
+
this.callbackMap.delete(name);
|
|
73
|
+
};
|
|
119
74
|
}
|
|
120
75
|
export { BaseInteraction };
|
|
@@ -17,6 +17,10 @@ import { getCanvasPosition, getWorldPosition } from './utils';
|
|
|
17
17
|
* })
|
|
18
18
|
*/
|
|
19
19
|
export class BoxSelectInteraction extends BaseInteraction {
|
|
20
|
+
mousePosition;
|
|
21
|
+
startWorldPosition;
|
|
22
|
+
overlayRenderer;
|
|
23
|
+
isBoxSelecting;
|
|
20
24
|
/**
|
|
21
25
|
* Creates a new instance of the multi-select interaction handler.
|
|
22
26
|
* @param nvl - The NVL instance to attach the interaction handler to
|
|
@@ -24,111 +28,6 @@ export class BoxSelectInteraction extends BaseInteraction {
|
|
|
24
28
|
*/
|
|
25
29
|
constructor(nvl, options = { selectOnRelease: false }) {
|
|
26
30
|
super(nvl, options);
|
|
27
|
-
Object.defineProperty(this, "mousePosition", {
|
|
28
|
-
enumerable: true,
|
|
29
|
-
configurable: true,
|
|
30
|
-
writable: true,
|
|
31
|
-
value: void 0
|
|
32
|
-
});
|
|
33
|
-
Object.defineProperty(this, "startWorldPosition", {
|
|
34
|
-
enumerable: true,
|
|
35
|
-
configurable: true,
|
|
36
|
-
writable: true,
|
|
37
|
-
value: void 0
|
|
38
|
-
});
|
|
39
|
-
Object.defineProperty(this, "overlayRenderer", {
|
|
40
|
-
enumerable: true,
|
|
41
|
-
configurable: true,
|
|
42
|
-
writable: true,
|
|
43
|
-
value: void 0
|
|
44
|
-
});
|
|
45
|
-
Object.defineProperty(this, "isBoxSelecting", {
|
|
46
|
-
enumerable: true,
|
|
47
|
-
configurable: true,
|
|
48
|
-
writable: true,
|
|
49
|
-
value: void 0
|
|
50
|
-
});
|
|
51
|
-
Object.defineProperty(this, "handleMouseDown", {
|
|
52
|
-
enumerable: true,
|
|
53
|
-
configurable: true,
|
|
54
|
-
writable: true,
|
|
55
|
-
value: (event) => {
|
|
56
|
-
if (event.button !== 0) {
|
|
57
|
-
this.isBoxSelecting = false;
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
this.turnOnBoxSelect(event);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
Object.defineProperty(this, "handleDrag", {
|
|
64
|
-
enumerable: true,
|
|
65
|
-
configurable: true,
|
|
66
|
-
writable: true,
|
|
67
|
-
value: (event) => {
|
|
68
|
-
if (this.isBoxSelecting) {
|
|
69
|
-
const curPos = getCanvasPosition(this.containerInstance, event);
|
|
70
|
-
this.overlayRenderer.drawBox(this.mousePosition.x, this.mousePosition.y, curPos.x, curPos.y);
|
|
71
|
-
}
|
|
72
|
-
else if (event.buttons === 1) {
|
|
73
|
-
this.turnOnBoxSelect(event);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
Object.defineProperty(this, "getHitsInBox", {
|
|
78
|
-
enumerable: true,
|
|
79
|
-
configurable: true,
|
|
80
|
-
writable: true,
|
|
81
|
-
value: (startPos, endPos) => {
|
|
82
|
-
const inside = (pos, start, end) => {
|
|
83
|
-
const minX = Math.min(start.x, end.x);
|
|
84
|
-
const maxX = Math.max(start.x, end.x);
|
|
85
|
-
const minY = Math.min(start.y, end.y);
|
|
86
|
-
const maxY = Math.max(start.y, end.y);
|
|
87
|
-
return pos.x >= minX && pos.x <= maxX && pos.y >= minY && pos.y <= maxY;
|
|
88
|
-
};
|
|
89
|
-
const positions = this.nvlInstance.getNodePositions();
|
|
90
|
-
const hitNodes = new Set();
|
|
91
|
-
for (const pos of positions) {
|
|
92
|
-
if (pos.x === undefined || pos.y === undefined || pos.id === undefined) {
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
if (inside(pos, startPos, endPos)) {
|
|
96
|
-
hitNodes.add(pos.id);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
const rels = this.nvlInstance.getRelationships();
|
|
100
|
-
const hitRels = [];
|
|
101
|
-
for (const rel of rels) {
|
|
102
|
-
if (hitNodes.has(rel.from) && hitNodes.has(rel.to)) {
|
|
103
|
-
hitRels.push(rel);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
const hitNodeArray = Array.from(hitNodes).map((id) => this.nvlInstance.getNodeById(id));
|
|
107
|
-
return {
|
|
108
|
-
nodes: hitNodeArray,
|
|
109
|
-
rels: hitRels
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
Object.defineProperty(this, "endBoxSelect", {
|
|
114
|
-
enumerable: true,
|
|
115
|
-
configurable: true,
|
|
116
|
-
writable: true,
|
|
117
|
-
value: (event) => {
|
|
118
|
-
if (!this.isBoxSelecting) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
this.isBoxSelecting = false;
|
|
122
|
-
this.overlayRenderer.clear();
|
|
123
|
-
const endPosition = getCanvasPosition(this.containerInstance, event);
|
|
124
|
-
const endWorldPosition = getWorldPosition(this.nvlInstance, endPosition);
|
|
125
|
-
const { nodes, rels } = this.getHitsInBox(this.startWorldPosition, endWorldPosition);
|
|
126
|
-
if (this.currentOptions.selectOnRelease) {
|
|
127
|
-
this.nvlInstance.updateElementsInGraph(nodes.map((node) => ({ id: node.id, selected: true })), rels.map((rel) => ({ id: rel.id, selected: true })));
|
|
128
|
-
}
|
|
129
|
-
this.callCallbackIfRegistered('onBoxSelect', { nodes, rels }, event);
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
31
|
this.mousePosition = { x: 0, y: 0 };
|
|
133
32
|
this.startWorldPosition = { x: 0, y: 0 };
|
|
134
33
|
this.overlayRenderer = new OverlayRenderer(this.containerInstance);
|
|
@@ -138,6 +37,64 @@ export class BoxSelectInteraction extends BaseInteraction {
|
|
|
138
37
|
this.addEventListener('mouseup', this.endBoxSelect, true);
|
|
139
38
|
this.addEventListener('mouseleave', this.endBoxSelect, true);
|
|
140
39
|
}
|
|
40
|
+
handleMouseDown = (event) => {
|
|
41
|
+
if (event.button !== 0) {
|
|
42
|
+
this.isBoxSelecting = false;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.turnOnBoxSelect(event);
|
|
46
|
+
};
|
|
47
|
+
handleDrag = (event) => {
|
|
48
|
+
if (this.isBoxSelecting) {
|
|
49
|
+
const curPos = getCanvasPosition(this.containerInstance, event);
|
|
50
|
+
this.overlayRenderer.drawBox(this.mousePosition.x, this.mousePosition.y, curPos.x, curPos.y);
|
|
51
|
+
}
|
|
52
|
+
else if (event.buttons === 1) {
|
|
53
|
+
this.turnOnBoxSelect(event);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
getHitsInBox = (startPos, endPos) => {
|
|
57
|
+
const inside = (pos, start, end) => {
|
|
58
|
+
const minX = Math.min(start.x, end.x);
|
|
59
|
+
const maxX = Math.max(start.x, end.x);
|
|
60
|
+
const minY = Math.min(start.y, end.y);
|
|
61
|
+
const maxY = Math.max(start.y, end.y);
|
|
62
|
+
return pos.x >= minX && pos.x <= maxX && pos.y >= minY && pos.y <= maxY;
|
|
63
|
+
};
|
|
64
|
+
const positions = this.nvlInstance.getNodePositions();
|
|
65
|
+
const hitNodes = new Set();
|
|
66
|
+
for (const pos of positions) {
|
|
67
|
+
if (inside(pos, startPos, endPos)) {
|
|
68
|
+
hitNodes.add(pos.id);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const rels = this.nvlInstance.getRelationships();
|
|
72
|
+
const hitRels = [];
|
|
73
|
+
for (const rel of rels) {
|
|
74
|
+
if (hitNodes.has(rel.from) && hitNodes.has(rel.to)) {
|
|
75
|
+
hitRels.push(rel);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const hitNodeArray = Array.from(hitNodes).map((id) => this.nvlInstance.getNodeById(id));
|
|
79
|
+
return {
|
|
80
|
+
nodes: hitNodeArray,
|
|
81
|
+
rels: hitRels
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
endBoxSelect = (event) => {
|
|
85
|
+
if (!this.isBoxSelecting) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
this.isBoxSelecting = false;
|
|
89
|
+
this.overlayRenderer.clear();
|
|
90
|
+
const endPosition = getCanvasPosition(this.containerInstance, event);
|
|
91
|
+
const endWorldPosition = getWorldPosition(this.nvlInstance, endPosition);
|
|
92
|
+
const { nodes, rels } = this.getHitsInBox(this.startWorldPosition, endWorldPosition);
|
|
93
|
+
if (this.currentOptions.selectOnRelease === true) {
|
|
94
|
+
this.nvlInstance.updateElementsInGraph(nodes.map((node) => ({ id: node.id, selected: true })), rels.map((rel) => ({ id: rel.id, selected: true })));
|
|
95
|
+
}
|
|
96
|
+
this.callCallbackIfRegistered('onBoxSelect', { nodes, rels }, event);
|
|
97
|
+
};
|
|
141
98
|
/**
|
|
142
99
|
* Removes all related event listeners and the overlay renderer for the box.
|
|
143
100
|
*/
|
|
@@ -157,7 +114,7 @@ export class BoxSelectInteraction extends BaseInteraction {
|
|
|
157
114
|
}
|
|
158
115
|
else {
|
|
159
116
|
this.isBoxSelecting = true;
|
|
160
|
-
if (this.currentOptions.selectOnRelease) {
|
|
117
|
+
if (this.currentOptions.selectOnRelease === true) {
|
|
161
118
|
this.nvlInstance.deselectAll();
|
|
162
119
|
}
|
|
163
120
|
}
|
|
@@ -17,6 +17,8 @@ import { isDraggingMovement } from './utils';
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
export class ClickInteraction extends BaseInteraction {
|
|
20
|
+
moved;
|
|
21
|
+
mousePosition;
|
|
20
22
|
/**
|
|
21
23
|
* Creates a new click interaction handler.
|
|
22
24
|
* @param nvl - The NVL instance to attach the interaction handler to
|
|
@@ -24,130 +26,100 @@ export class ClickInteraction extends BaseInteraction {
|
|
|
24
26
|
*/
|
|
25
27
|
constructor(nvl, options = { selectOnClick: false }) {
|
|
26
28
|
super(nvl, options);
|
|
27
|
-
Object.defineProperty(this, "moved", {
|
|
28
|
-
enumerable: true,
|
|
29
|
-
configurable: true,
|
|
30
|
-
writable: true,
|
|
31
|
-
value: void 0
|
|
32
|
-
});
|
|
33
|
-
Object.defineProperty(this, "mousePosition", {
|
|
34
|
-
enumerable: true,
|
|
35
|
-
configurable: true,
|
|
36
|
-
writable: true,
|
|
37
|
-
value: void 0
|
|
38
|
-
});
|
|
39
|
-
Object.defineProperty(this, "handleMouseDown", {
|
|
40
|
-
enumerable: true,
|
|
41
|
-
configurable: true,
|
|
42
|
-
writable: true,
|
|
43
|
-
value: (event) => {
|
|
44
|
-
this.mousePosition = { x: event.clientX, y: event.clientY };
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
Object.defineProperty(this, "handleRightClick", {
|
|
48
|
-
enumerable: true,
|
|
49
|
-
configurable: true,
|
|
50
|
-
writable: true,
|
|
51
|
-
value: (event) => {
|
|
52
|
-
event.preventDefault();
|
|
53
|
-
const { nvlTargets } = this.nvlInstance.getHits(event);
|
|
54
|
-
const { nodes = [], relationships = [] } = nvlTargets;
|
|
55
|
-
if (nodes.length === 0 && relationships.length === 0) {
|
|
56
|
-
this.callCallbackIfRegistered('onCanvasRightClick', event);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
if (nodes.length > 0) {
|
|
60
|
-
this.callCallbackIfRegistered('onNodeRightClick', nodes[0].data, nvlTargets, event);
|
|
61
|
-
}
|
|
62
|
-
else if (relationships.length > 0) {
|
|
63
|
-
this.callCallbackIfRegistered('onRelationshipRightClick', relationships[0].data, nvlTargets, event);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
Object.defineProperty(this, "handleDoubleClick", {
|
|
68
|
-
enumerable: true,
|
|
69
|
-
configurable: true,
|
|
70
|
-
writable: true,
|
|
71
|
-
value: (event) => {
|
|
72
|
-
const { nvlTargets } = this.nvlInstance.getHits(event);
|
|
73
|
-
const { nodes = [], relationships = [] } = nvlTargets;
|
|
74
|
-
if (nodes.length === 0 && relationships.length === 0) {
|
|
75
|
-
this.callCallbackIfRegistered('onCanvasDoubleClick', event);
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (nodes.length > 0) {
|
|
79
|
-
this.callCallbackIfRegistered('onNodeDoubleClick', nodes[0].data, nvlTargets, event);
|
|
80
|
-
}
|
|
81
|
-
else if (relationships.length > 0) {
|
|
82
|
-
this.callCallbackIfRegistered('onRelationshipDoubleClick', relationships[0].data, nvlTargets, event);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
Object.defineProperty(this, "handleClick", {
|
|
87
|
-
enumerable: true,
|
|
88
|
-
configurable: true,
|
|
89
|
-
writable: true,
|
|
90
|
-
value: (event) => {
|
|
91
|
-
if (isDraggingMovement(event, this.mousePosition) || event.button !== 0) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
const { nvlTargets } = this.nvlInstance.getHits(event);
|
|
95
|
-
const { nodes = [], relationships = [] } = nvlTargets;
|
|
96
|
-
if (nodes.length === 0 && relationships.length === 0) {
|
|
97
|
-
if (this.currentOptions.selectOnClick) {
|
|
98
|
-
this.nvlInstance.deselectAll();
|
|
99
|
-
}
|
|
100
|
-
this.callCallbackIfRegistered('onCanvasClick', event);
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
if (nodes.length > 0) {
|
|
104
|
-
const hitNodeData = nodes.map((node) => node.data);
|
|
105
|
-
if (this.currentOptions.selectOnClick) {
|
|
106
|
-
const selectedNodes = this.nvlInstance.getSelectedNodes();
|
|
107
|
-
const selectedRelationships = this.nvlInstance.getSelectedRelationships();
|
|
108
|
-
const nodeUpdates = [
|
|
109
|
-
...selectedNodes.map((node) => ({ id: node.id, selected: false })),
|
|
110
|
-
{ id: hitNodeData[0].id, selected: true }
|
|
111
|
-
];
|
|
112
|
-
const relationshipUpdates = selectedRelationships.map((relationship) => (Object.assign(Object.assign({}, relationship), { selected: false })));
|
|
113
|
-
this.nvlInstance.updateElementsInGraph(nodeUpdates, relationshipUpdates);
|
|
114
|
-
}
|
|
115
|
-
this.callCallbackIfRegistered('onNodeClick', nodes[0].data, nvlTargets, event);
|
|
116
|
-
}
|
|
117
|
-
else if (relationships.length > 0) {
|
|
118
|
-
const hitRelationshipData = relationships.map((relationship) => relationship.data);
|
|
119
|
-
if (this.currentOptions.selectOnClick) {
|
|
120
|
-
const selectedNodes = this.nvlInstance.getSelectedNodes();
|
|
121
|
-
const selectedRelationships = this.nvlInstance.getSelectedRelationships();
|
|
122
|
-
const nodeUpdates = selectedNodes.map((node) => ({ id: node.id, selected: false }));
|
|
123
|
-
const relationshipUpdates = [
|
|
124
|
-
{ id: hitRelationshipData[0].id, selected: true },
|
|
125
|
-
...selectedRelationships.map((relationship) => (Object.assign(Object.assign({}, relationship), { selected: false })))
|
|
126
|
-
];
|
|
127
|
-
this.nvlInstance.updateElementsInGraph(nodeUpdates, relationshipUpdates);
|
|
128
|
-
}
|
|
129
|
-
this.callCallbackIfRegistered('onRelationshipClick', relationships[0].data, nvlTargets, event);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
/**
|
|
134
|
-
* Removes all related event listeners from the container.
|
|
135
|
-
*/
|
|
136
|
-
Object.defineProperty(this, "destroy", {
|
|
137
|
-
enumerable: true,
|
|
138
|
-
configurable: true,
|
|
139
|
-
writable: true,
|
|
140
|
-
value: () => {
|
|
141
|
-
this.removeEventListener('mousedown', this.handleMouseDown, true);
|
|
142
|
-
this.removeEventListener('click', this.handleClick, true);
|
|
143
|
-
this.removeEventListener('dblclick', this.handleClick, true);
|
|
144
|
-
this.removeEventListener('contextmenu', this.handleRightClick, true);
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
29
|
this.mousePosition = { x: 0, y: 0 };
|
|
148
30
|
this.addEventListener('mousedown', this.handleMouseDown, true);
|
|
149
31
|
this.addEventListener('click', this.handleClick, true);
|
|
150
32
|
this.addEventListener('dblclick', this.handleDoubleClick, true);
|
|
151
33
|
this.addEventListener('contextmenu', this.handleRightClick, true);
|
|
152
34
|
}
|
|
35
|
+
handleMouseDown = (event) => {
|
|
36
|
+
this.mousePosition = { x: event.clientX, y: event.clientY };
|
|
37
|
+
};
|
|
38
|
+
handleRightClick = (event) => {
|
|
39
|
+
event.preventDefault();
|
|
40
|
+
const { nvlTargets } = this.nvlInstance.getHits(event);
|
|
41
|
+
const { nodes = [], relationships = [] } = nvlTargets;
|
|
42
|
+
if (nodes.length === 0 && relationships.length === 0) {
|
|
43
|
+
this.callCallbackIfRegistered('onCanvasRightClick', event);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (nodes.length > 0) {
|
|
47
|
+
this.callCallbackIfRegistered('onNodeRightClick', nodes[0]?.data, nvlTargets, event);
|
|
48
|
+
}
|
|
49
|
+
else if (relationships.length > 0) {
|
|
50
|
+
this.callCallbackIfRegistered('onRelationshipRightClick', relationships[0]?.data, nvlTargets, event);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
handleDoubleClick = (event) => {
|
|
54
|
+
const { nvlTargets } = this.nvlInstance.getHits(event);
|
|
55
|
+
const { nodes = [], relationships = [] } = nvlTargets;
|
|
56
|
+
if (nodes.length === 0 && relationships.length === 0) {
|
|
57
|
+
this.callCallbackIfRegistered('onCanvasDoubleClick', event);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (nodes.length > 0) {
|
|
61
|
+
this.callCallbackIfRegistered('onNodeDoubleClick', nodes[0]?.data, nvlTargets, event);
|
|
62
|
+
}
|
|
63
|
+
else if (relationships.length > 0) {
|
|
64
|
+
this.callCallbackIfRegistered('onRelationshipDoubleClick', relationships[0]?.data, nvlTargets, event);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
handleClick = (event) => {
|
|
68
|
+
if (isDraggingMovement(event, this.mousePosition) || event.button !== 0) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const { nvlTargets } = this.nvlInstance.getHits(event);
|
|
72
|
+
const { nodes = [], relationships = [] } = nvlTargets;
|
|
73
|
+
if (nodes.length === 0 && relationships.length === 0) {
|
|
74
|
+
if (this.currentOptions.selectOnClick === true) {
|
|
75
|
+
this.nvlInstance.deselectAll();
|
|
76
|
+
}
|
|
77
|
+
this.callCallbackIfRegistered('onCanvasClick', event);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (nodes.length > 0) {
|
|
81
|
+
const hitNodeData = nodes.map((node) => node.data);
|
|
82
|
+
if (this.currentOptions.selectOnClick === true) {
|
|
83
|
+
const selectedNodes = this.nvlInstance.getSelectedNodes();
|
|
84
|
+
const selectedRelationships = this.nvlInstance.getSelectedRelationships();
|
|
85
|
+
const newSelectedNodes = hitNodeData[0] ? [{ id: hitNodeData[0].id, selected: true }] : [];
|
|
86
|
+
const nodeUpdates = [...newSelectedNodes, ...selectedNodes.map((node) => ({ id: node.id, selected: false }))];
|
|
87
|
+
const relationshipUpdates = selectedRelationships.map((relationship) => ({
|
|
88
|
+
...relationship,
|
|
89
|
+
selected: false
|
|
90
|
+
}));
|
|
91
|
+
this.nvlInstance.updateElementsInGraph(nodeUpdates, relationshipUpdates);
|
|
92
|
+
}
|
|
93
|
+
this.callCallbackIfRegistered('onNodeClick', nodes[0]?.data, nvlTargets, event);
|
|
94
|
+
}
|
|
95
|
+
else if (relationships.length > 0) {
|
|
96
|
+
const hitRelationshipData = relationships.map((relationship) => relationship.data);
|
|
97
|
+
if (this.currentOptions.selectOnClick === true) {
|
|
98
|
+
const selectedNodes = this.nvlInstance.getSelectedNodes();
|
|
99
|
+
const selectedRelationships = this.nvlInstance.getSelectedRelationships();
|
|
100
|
+
const nodeUpdates = selectedNodes.map((node) => ({ id: node.id, selected: false }));
|
|
101
|
+
const newSelectedRelationships = hitRelationshipData[0]
|
|
102
|
+
? [{ id: hitRelationshipData[0].id, selected: true }]
|
|
103
|
+
: [];
|
|
104
|
+
const relationshipUpdates = [
|
|
105
|
+
...newSelectedRelationships,
|
|
106
|
+
...selectedRelationships.map((relationship) => ({
|
|
107
|
+
...relationship,
|
|
108
|
+
selected: false
|
|
109
|
+
}))
|
|
110
|
+
];
|
|
111
|
+
this.nvlInstance.updateElementsInGraph(nodeUpdates, relationshipUpdates);
|
|
112
|
+
}
|
|
113
|
+
this.callCallbackIfRegistered('onRelationshipClick', relationships[0]?.data, nvlTargets, event);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Removes all related event listeners from the container.
|
|
118
|
+
*/
|
|
119
|
+
destroy = () => {
|
|
120
|
+
this.removeEventListener('mousedown', this.handleMouseDown, true);
|
|
121
|
+
this.removeEventListener('click', this.handleClick, true);
|
|
122
|
+
this.removeEventListener('dblclick', this.handleClick, true);
|
|
123
|
+
this.removeEventListener('contextmenu', this.handleRightClick, true);
|
|
124
|
+
};
|
|
153
125
|
}
|