@neo4j-nvl/interaction-handlers 0.2.52 → 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
|
@@ -17,150 +17,18 @@ import { isDraggingMovement } from './utils';
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
export class DragNodeInteraction extends BaseInteraction {
|
|
20
|
+
mousePosition;
|
|
21
|
+
mouseDownNode;
|
|
22
|
+
isDragging;
|
|
23
|
+
isDrawing;
|
|
24
|
+
selectedNodes;
|
|
25
|
+
moveSelectedNodes;
|
|
20
26
|
/**
|
|
21
27
|
* Creates a new instance of the drag node interaction handler.
|
|
22
28
|
* @param nvl - The NVL instance to attach the interaction handler to
|
|
23
29
|
*/
|
|
24
30
|
constructor(nvl, options = {}) {
|
|
25
31
|
super(nvl, options);
|
|
26
|
-
Object.defineProperty(this, "mousePosition", {
|
|
27
|
-
enumerable: true,
|
|
28
|
-
configurable: true,
|
|
29
|
-
writable: true,
|
|
30
|
-
value: void 0
|
|
31
|
-
});
|
|
32
|
-
Object.defineProperty(this, "mouseDownNode", {
|
|
33
|
-
enumerable: true,
|
|
34
|
-
configurable: true,
|
|
35
|
-
writable: true,
|
|
36
|
-
value: void 0
|
|
37
|
-
});
|
|
38
|
-
Object.defineProperty(this, "isDragging", {
|
|
39
|
-
enumerable: true,
|
|
40
|
-
configurable: true,
|
|
41
|
-
writable: true,
|
|
42
|
-
value: void 0
|
|
43
|
-
});
|
|
44
|
-
Object.defineProperty(this, "isDrawing", {
|
|
45
|
-
enumerable: true,
|
|
46
|
-
configurable: true,
|
|
47
|
-
writable: true,
|
|
48
|
-
value: void 0
|
|
49
|
-
});
|
|
50
|
-
Object.defineProperty(this, "selectedNodes", {
|
|
51
|
-
enumerable: true,
|
|
52
|
-
configurable: true,
|
|
53
|
-
writable: true,
|
|
54
|
-
value: void 0
|
|
55
|
-
});
|
|
56
|
-
Object.defineProperty(this, "moveSelectedNodes", {
|
|
57
|
-
enumerable: true,
|
|
58
|
-
configurable: true,
|
|
59
|
-
writable: true,
|
|
60
|
-
value: void 0
|
|
61
|
-
});
|
|
62
|
-
Object.defineProperty(this, "handleMouseDown", {
|
|
63
|
-
enumerable: true,
|
|
64
|
-
configurable: true,
|
|
65
|
-
writable: true,
|
|
66
|
-
value: (event) => {
|
|
67
|
-
this.mousePosition = { x: event.clientX, y: event.clientY };
|
|
68
|
-
const hits = this.nvlInstance.getHits(event, ['node'], { hitNodeMarginWidth: NODE_EDGE_WIDTH });
|
|
69
|
-
const hitNodes = hits.nvlTargets.nodes.filter((node) => node.insideNode);
|
|
70
|
-
const hitNodeEdges = hits.nvlTargets.nodes.filter((node) => !node.insideNode);
|
|
71
|
-
if (hitNodeEdges.length > 0) {
|
|
72
|
-
this.isDrawing = true;
|
|
73
|
-
this.mouseDownNode = null;
|
|
74
|
-
}
|
|
75
|
-
else if (hitNodes.length > 0) {
|
|
76
|
-
this.mouseDownNode = hits.nvlTargets.nodes[0];
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
this.mouseDownNode = null;
|
|
80
|
-
}
|
|
81
|
-
this.selectedNodes = this.nvlInstance.getSelectedNodes();
|
|
82
|
-
if (this.mouseDownNode !== null && this.selectedNodes.map((node) => node.id).includes(this.mouseDownNode.data.id)) {
|
|
83
|
-
this.moveSelectedNodes = true;
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
this.moveSelectedNodes = false;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
Object.defineProperty(this, "handleMouseMove", {
|
|
91
|
-
enumerable: true,
|
|
92
|
-
configurable: true,
|
|
93
|
-
writable: true,
|
|
94
|
-
value: (evt) => {
|
|
95
|
-
// Avoid conflicts on moving node position in drawing process.
|
|
96
|
-
if (this.mouseDownNode === null || evt.buttons !== 1 || this.isDrawing) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
if (!isDraggingMovement(evt, this.mousePosition)) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
if (!this.isDragging) {
|
|
103
|
-
if (this.moveSelectedNodes) {
|
|
104
|
-
this.callCallbackIfRegistered('onDragStart', this.selectedNodes, evt);
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
this.callCallbackIfRegistered('onDragStart', [this.mouseDownNode.data], evt);
|
|
108
|
-
}
|
|
109
|
-
this.isDragging = true;
|
|
110
|
-
}
|
|
111
|
-
const zoom = this.nvlInstance.getScale();
|
|
112
|
-
const dx = ((evt.clientX - this.mousePosition.x) / zoom) * window.devicePixelRatio;
|
|
113
|
-
const dy = ((evt.clientY - this.mousePosition.y) / zoom) * window.devicePixelRatio;
|
|
114
|
-
if (this.moveSelectedNodes) {
|
|
115
|
-
this.nvlInstance.setNodePositions(this.selectedNodes.map((node) => ({ id: node.id, x: node.x + dx, y: node.y + dy, pinned: true })), true);
|
|
116
|
-
this.callCallbackIfRegistered('onDrag', this.selectedNodes, evt);
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
this.nvlInstance.setNodePositions([
|
|
120
|
-
{
|
|
121
|
-
id: this.mouseDownNode.data.id,
|
|
122
|
-
x: this.mouseDownNode.targetCoordinates.x + dx,
|
|
123
|
-
y: this.mouseDownNode.targetCoordinates.y + dy,
|
|
124
|
-
pinned: true
|
|
125
|
-
}
|
|
126
|
-
], true);
|
|
127
|
-
this.callCallbackIfRegistered('onDrag', [this.mouseDownNode.data], evt);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
Object.defineProperty(this, "handleMouseUp", {
|
|
132
|
-
enumerable: true,
|
|
133
|
-
configurable: true,
|
|
134
|
-
writable: true,
|
|
135
|
-
value: (evt) => {
|
|
136
|
-
if (this.isDragging) {
|
|
137
|
-
if (this.moveSelectedNodes) {
|
|
138
|
-
this.callCallbackIfRegistered('onDragEnd', this.selectedNodes, evt);
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
this.callCallbackIfRegistered('onDragEnd', [this.mouseDownNode.data], evt);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
this.isDragging = false;
|
|
145
|
-
this.mouseDownNode = null;
|
|
146
|
-
this.isDrawing = false;
|
|
147
|
-
this.selectedNodes = [];
|
|
148
|
-
this.moveSelectedNodes = false;
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
/**
|
|
152
|
-
* Removes all related event listeners from the container.
|
|
153
|
-
*/
|
|
154
|
-
Object.defineProperty(this, "destroy", {
|
|
155
|
-
enumerable: true,
|
|
156
|
-
configurable: true,
|
|
157
|
-
writable: true,
|
|
158
|
-
value: () => {
|
|
159
|
-
this.removeEventListener('mousedown', this.handleMouseDown);
|
|
160
|
-
this.removeEventListener('mousemove', this.handleMouseMove);
|
|
161
|
-
this.removeEventListener('mouseup', this.handleMouseUp);
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
32
|
this.mousePosition = { x: 0, y: 0 };
|
|
165
33
|
this.isDragging = false;
|
|
166
34
|
this.isDrawing = false;
|
|
@@ -170,4 +38,86 @@ export class DragNodeInteraction extends BaseInteraction {
|
|
|
170
38
|
this.addEventListener('mousemove', this.handleMouseMove);
|
|
171
39
|
this.addEventListener('mouseup', this.handleMouseUp);
|
|
172
40
|
}
|
|
41
|
+
handleMouseDown = (event) => {
|
|
42
|
+
this.mousePosition = { x: event.clientX, y: event.clientY };
|
|
43
|
+
const hits = this.nvlInstance.getHits(event, ['node'], { hitNodeMarginWidth: NODE_EDGE_WIDTH });
|
|
44
|
+
const hitNodes = hits.nvlTargets.nodes.filter((node) => node.insideNode);
|
|
45
|
+
const hitNodeEdges = hits.nvlTargets.nodes.filter((node) => !node.insideNode);
|
|
46
|
+
if (hitNodeEdges.length > 0) {
|
|
47
|
+
this.isDrawing = true;
|
|
48
|
+
this.mouseDownNode = null;
|
|
49
|
+
}
|
|
50
|
+
else if (hitNodes.length > 0) {
|
|
51
|
+
this.mouseDownNode = hits.nvlTargets.nodes[0] ?? null;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
this.mouseDownNode = null;
|
|
55
|
+
}
|
|
56
|
+
this.selectedNodes = this.nvlInstance.getSelectedNodes();
|
|
57
|
+
if (this.mouseDownNode !== null && this.selectedNodes.map((node) => node.id).includes(this.mouseDownNode.data.id)) {
|
|
58
|
+
this.moveSelectedNodes = true;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
this.moveSelectedNodes = false;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
handleMouseMove = (evt) => {
|
|
65
|
+
// Avoid conflicts on moving node position in drawing process.
|
|
66
|
+
if (this.mouseDownNode === null || evt.buttons !== 1 || this.isDrawing) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (!isDraggingMovement(evt, this.mousePosition)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (!this.isDragging) {
|
|
73
|
+
if (this.moveSelectedNodes) {
|
|
74
|
+
this.callCallbackIfRegistered('onDragStart', this.selectedNodes, evt);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.callCallbackIfRegistered('onDragStart', [this.mouseDownNode.data], evt);
|
|
78
|
+
}
|
|
79
|
+
this.isDragging = true;
|
|
80
|
+
}
|
|
81
|
+
const zoom = this.nvlInstance.getScale();
|
|
82
|
+
const dx = ((evt.clientX - this.mousePosition.x) / zoom) * window.devicePixelRatio;
|
|
83
|
+
const dy = ((evt.clientY - this.mousePosition.y) / zoom) * window.devicePixelRatio;
|
|
84
|
+
if (this.moveSelectedNodes) {
|
|
85
|
+
this.nvlInstance.setNodePositions(this.selectedNodes.map((node) => ({ id: node.id, x: node.x + dx, y: node.y + dy, pinned: true })), true);
|
|
86
|
+
this.callCallbackIfRegistered('onDrag', this.selectedNodes, evt);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.nvlInstance.setNodePositions([
|
|
90
|
+
{
|
|
91
|
+
id: this.mouseDownNode.data.id,
|
|
92
|
+
x: this.mouseDownNode.targetCoordinates.x + dx,
|
|
93
|
+
y: this.mouseDownNode.targetCoordinates.y + dy,
|
|
94
|
+
pinned: true
|
|
95
|
+
}
|
|
96
|
+
], true);
|
|
97
|
+
this.callCallbackIfRegistered('onDrag', [this.mouseDownNode.data], evt);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
handleMouseUp = (evt) => {
|
|
101
|
+
if (this.isDragging) {
|
|
102
|
+
if (this.moveSelectedNodes) {
|
|
103
|
+
this.callCallbackIfRegistered('onDragEnd', this.selectedNodes, evt);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
this.callCallbackIfRegistered('onDragEnd', [this.mouseDownNode?.data], evt);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
this.isDragging = false;
|
|
110
|
+
this.mouseDownNode = null;
|
|
111
|
+
this.isDrawing = false;
|
|
112
|
+
this.selectedNodes = [];
|
|
113
|
+
this.moveSelectedNodes = false;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Removes all related event listeners from the container.
|
|
117
|
+
*/
|
|
118
|
+
destroy = () => {
|
|
119
|
+
this.removeEventListener('mousedown', this.handleMouseDown);
|
|
120
|
+
this.removeEventListener('mousemove', this.handleMouseMove);
|
|
121
|
+
this.removeEventListener('mouseup', this.handleMouseUp);
|
|
122
|
+
};
|
|
173
123
|
}
|
|
@@ -8,11 +8,17 @@ export type DrawInteractionCallbacks = {
|
|
|
8
8
|
onHoverNodeMargin?: ((hoveredNode: Node | null, evt: MouseEvent) => void) | boolean;
|
|
9
9
|
onDrawEnd?: ((newRelationshipToAdd: Relationship | null, newTargetNodeToAdd: Node | null, event: MouseEvent) => void) | boolean;
|
|
10
10
|
};
|
|
11
|
+
export type DrawInteractionOptions = {
|
|
12
|
+
ghostGraphStyling?: {
|
|
13
|
+
node?: Pick<Node, 'color' | 'size'>;
|
|
14
|
+
relationship?: Pick<Relationship, 'color' | 'width'>;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
11
17
|
/**
|
|
12
18
|
* @internal
|
|
13
19
|
* @experimental
|
|
14
20
|
*/
|
|
15
|
-
export declare class DrawInteraction extends BaseInteraction<DrawInteractionCallbacks,
|
|
21
|
+
export declare class DrawInteraction extends BaseInteraction<DrawInteractionCallbacks, DrawInteractionOptions> {
|
|
16
22
|
private isMoved;
|
|
17
23
|
private isDrawing;
|
|
18
24
|
private isDraggingNode;
|
|
@@ -23,7 +29,7 @@ export declare class DrawInteraction extends BaseInteraction<DrawInteractionCall
|
|
|
23
29
|
private newTempSelfReferredRelationship;
|
|
24
30
|
private newTargetNodeToAdd;
|
|
25
31
|
private newRelationshipToAdd;
|
|
26
|
-
constructor(nvl: NVL, options?:
|
|
32
|
+
constructor(nvl: NVL, options?: DrawInteractionOptions);
|
|
27
33
|
private handleMouseMove;
|
|
28
34
|
private setNewRegularRelationship;
|
|
29
35
|
private setNewRegularRelationshipToNewTempTargetNode;
|