Skip to content

Commit 4bf8573

Browse files
authored
fix(select): trigger select events for shift+drag selections (#1133)
* fix(select): trigger select events for shift+drag selections This also includes some refactoring (selection is now encapsulated in a class, some underscore convention fixes and dead code removal) and E2E test. * chore(package): regenerate package lock
1 parent ccdd368 commit 4bf8573

File tree

16 files changed

+2693
-6362
lines changed

16 files changed

+2693
-6362
lines changed

__snapshots__/test/package.test.ts.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ exports['Package Exported files 1'] = {
5353
" declarations/network/modules/components/nodes/util/shapes.d.ts.map",
5454
" declarations/network/modules/layout-engine/index.d.ts",
5555
" declarations/network/modules/layout-engine/index.d.ts.map",
56+
" declarations/network/modules/selection/index.d.ts",
57+
" declarations/network/modules/selection/index.d.ts.map",
58+
" declarations/network/modules/selection/selection-accumulator.d.ts",
59+
" declarations/network/modules/selection/selection-accumulator.d.ts.map",
5660
" declarations/network/options.d.ts",
5761
" declarations/network/shapes.d.ts",
5862
" declarations/network/shapes.d.ts.map",
@@ -121,6 +125,10 @@ exports['Package Exported files 1'] = {
121125
" dist/types/network/modules/components/nodes/util/shapes.d.ts.map",
122126
" dist/types/network/modules/layout-engine/index.d.ts",
123127
" dist/types/network/modules/layout-engine/index.d.ts.map",
128+
" dist/types/network/modules/selection/index.d.ts",
129+
" dist/types/network/modules/selection/index.d.ts.map",
130+
" dist/types/network/modules/selection/selection-accumulator.d.ts",
131+
" dist/types/network/modules/selection/selection-accumulator.d.ts.map",
124132
" dist/types/network/options.d.ts",
125133
" dist/types/network/shapes.d.ts",
126134
" dist/types/network/shapes.d.ts.map",
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { Point, VisEvent } from "../helpers";
2+
3+
const NETWORK_DATA = {
4+
nodes: [
5+
{ id: "N_1", label: "node 1", x: 0, y: 0 },
6+
{ id: "N_2", label: "node 2", x: 200, y: 0 },
7+
{ id: "N_3", label: "node 3", x: 0, y: 200 },
8+
{ id: "N_4", label: "node 4", x: -200, y: 0 },
9+
{ id: "N_5", label: "node 5", x: 0, y: -200 },
10+
],
11+
edges: [
12+
{ id: "E_1-2", label: "edge 1-2", from: "N_1", to: "N_2" },
13+
{ id: "E_1-3", label: "edge 1-3", from: "N_1", to: "N_3" },
14+
{ id: "E_1-4", label: "edge 1-4", from: "N_1", to: "N_4" },
15+
{ id: "E_1-5", label: "edge 1-5", from: "N_1", to: "N_5" },
16+
17+
{ id: "E_2-3", label: "edge 2-3", from: "N_2", to: "N_3" },
18+
{ id: "E_3-4", label: "edge 3-4", from: "N_3", to: "N_4" },
19+
{ id: "E_4-5", label: "edge 4-5", from: "N_4", to: "N_5" },
20+
{ id: "E_5-2", label: "edge 5-2", from: "N_5", to: "N_2" },
21+
],
22+
physics: false,
23+
};
24+
25+
context("Drags", (): void => {
26+
it("Select one by click", function (): void {
27+
cy.visVisitUniversal(NETWORK_DATA);
28+
29+
cy.visClickPoint({ x: 500 + 0, y: 500 + 0 });
30+
cy.visAssertSelection({
31+
nodes: ["N_1"],
32+
edges: ["E_1-2", "E_1-3", "E_1-4", "E_1-5"],
33+
});
34+
35+
cy.visClickPoint({ x: 500 + 200, y: 500 + 0 });
36+
cy.visAssertSelection({
37+
nodes: ["N_2"],
38+
edges: ["E_5-2", "E_1-2", "E_2-3"],
39+
});
40+
});
41+
42+
it("Select none by single drag", function (): void {
43+
cy.visVisitUniversal(NETWORK_DATA);
44+
cy.visDrag([
45+
{
46+
from: { x: 500 + 200 + 70, y: 500 + 200 - 70 },
47+
to: { x: 500 + 200 - 70, y: 500 + 200 + 70 },
48+
button: 0,
49+
shiftKey: true,
50+
},
51+
]);
52+
cy.visAssertSelection({
53+
nodes: [],
54+
edges: [],
55+
});
56+
});
57+
58+
it("Select one by single drag (TL to BR)", function (): void {
59+
cy.visVisitUniversal(NETWORK_DATA);
60+
cy.visDrag([
61+
{
62+
from: { x: 500 + 0 - 70, y: 500 + 0 - 70 },
63+
to: { x: 500 + 0 + 70, y: 500 + 0 + 70 },
64+
button: 0,
65+
shiftKey: true,
66+
},
67+
]);
68+
cy.visAssertSelection({
69+
nodes: ["N_1"],
70+
edges: ["E_1-2", "E_1-3", "E_1-4", "E_1-5"],
71+
});
72+
});
73+
74+
it("Select three by single drag (BR to TL)", function (): void {
75+
cy.visVisitUniversal(NETWORK_DATA);
76+
cy.visDrag([
77+
{
78+
from: { x: 500 + 200 + 70, y: 500 + 200 + 70 },
79+
to: { x: 500 + 0 - 70, y: 500 + 0 - 70 },
80+
button: 0,
81+
shiftKey: true,
82+
},
83+
]);
84+
cy.visAssertSelection({
85+
nodes: ["N_1", "N_2", "N_3"],
86+
edges: ["E_1-2", "E_1-3", "E_1-4", "E_1-5", "E_3-4", "E_2-3", "E_5-2"],
87+
});
88+
});
89+
90+
it("Select three by two drags (TR to BL then BL to TR)", function (): void {
91+
cy.visVisitUniversal(NETWORK_DATA);
92+
93+
cy.visDrag([
94+
{
95+
from: { x: 500 + 0 + 70, y: 500 + 0 - 70 },
96+
to: { x: 500 + 0 - 70, y: 500 + 200 + 70 },
97+
button: 0,
98+
shiftKey: true,
99+
},
100+
]);
101+
cy.visAssertSelection({
102+
nodes: ["N_1", "N_3"],
103+
edges: ["E_1-2", "E_1-3", "E_1-4", "E_1-5", "E_3-4", "E_2-3"],
104+
});
105+
106+
cy.visDrag([
107+
{
108+
from: { x: 500 + 200 - 70, y: 500 + 0 + 70 },
109+
to: { x: 500 + 200 + 70, y: 500 + 0 - 70 },
110+
button: 0,
111+
shiftKey: true,
112+
},
113+
]);
114+
cy.visAssertSelection({
115+
nodes: ["N_1", "N_2", "N_3"],
116+
edges: ["E_1-2", "E_1-3", "E_1-4", "E_1-5", "E_3-4", "E_2-3", "E_5-2"],
117+
});
118+
});
119+
});

cypress/pages/standard-cytest-script.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,27 @@ type VisUtil = typeof visUtil;
2727
throw new Error("Element #mynetwork was not found in the DOM.");
2828
}
2929

30-
const $events = document.getElementById("events")!;
30+
const $events = document.getElementById("events");
3131
if ($events == null) {
3232
throw new Error("Element #events was not found in the DOM.");
3333
}
3434

35-
const $selection = document.getElementById("selection")!;
35+
const $selection = document.getElementById("selection");
3636
if ($selection == null) {
3737
throw new Error("Element #selection was not found in the DOM.");
3838
}
3939

40-
const $version = document.getElementById("version")!;
40+
const $selectionJSON = document.getElementById("selection-json");
41+
if ($selectionJSON == null) {
42+
throw new Error("Element #selection-json was not found in the DOM.");
43+
}
44+
45+
const $version = document.getElementById("version");
4146
if ($version == null) {
4247
throw new Error("Element #version was not found in the DOM.");
4348
}
4449

45-
const $status = document.getElementById("status")!;
50+
const $status = document.getElementById("status");
4651
if ($status == null) {
4752
throw new Error("Element #status was not found in the DOM.");
4853
}
@@ -191,6 +196,16 @@ type VisUtil = typeof visUtil;
191196
});
192197
});
193198

199+
const updateSelectionJSON = (): void => {
200+
const selection = network.getSelection();
201+
$selectionJSON.innerText = JSON.stringify({
202+
nodes: [...selection.nodes].sort(),
203+
edges: [...selection.edges].sort(),
204+
});
205+
};
206+
// Make sure the selection is always filled in.
207+
updateSelectionJSON();
208+
194209
// Selection events:
195210
([
196211
"deselectEdge",
@@ -199,6 +214,8 @@ type VisUtil = typeof visUtil;
199214
"selectEdge",
200215
"selectNode",
201216
] as const).forEach((eventName): void => {
217+
network.on(eventName, updateSelectionJSON);
218+
202219
network.on(eventName, (): void => {
203220
const selection = [
204221
["node", network.getSelectedNodes()],

cypress/pages/universal.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ <h1>Info</h1>
8181
<div>
8282
<h1>Selection</h1>
8383
<div id="selection"></div>
84+
<pre id="selection-json"></pre>
8485
</div>
8586

8687
<div>

cypress/support/commands/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from "./types";
22

3+
export * from "./vis-assert-selection";
34
export * from "./vis-check-ids";
45
export * from "./vis-click-betweek-points";
56
export * from "./vis-click-edge";

cypress/support/commands/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@ export interface UniversalNetworkConfig {
4141
export interface UniversalConfig extends UniversalNetworkConfig {
4242
version: null | "latest";
4343
}
44+
45+
export type IdType = string | number;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { IdType } from "./types";
2+
3+
declare global {
4+
namespace Cypress {
5+
interface Chainable<Subject> {
6+
/**
7+
* Check selected nodes and edges.
8+
*
9+
* @param selection - The same format as in Network.getSelection().
10+
*/
11+
visAssertSelection(selection: {
12+
nodes: IdType[];
13+
edges: IdType[];
14+
}): Chainable<Subject>;
15+
}
16+
}
17+
}
18+
19+
function sortSelection(selection: {
20+
nodes: IdType[];
21+
edges: IdType[];
22+
}): {
23+
nodes: IdType[];
24+
edges: IdType[];
25+
} {
26+
return {
27+
nodes: [...selection.nodes].sort(),
28+
edges: [...selection.edges].sort(),
29+
};
30+
}
31+
32+
export function visAssertSelection(expectedSelection: {
33+
nodes: IdType[];
34+
edges: IdType[];
35+
}): void {
36+
cy.get("#selection-json").should(
37+
"have.text",
38+
JSON.stringify(sortSelection(expectedSelection))
39+
);
40+
}
41+
Cypress.Commands.add("visAssertSelection", visAssertSelection);

cypress/support/commands/vis-drag.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ export function visDrag(paths: readonly DragPath[]): void {
2626
)) {
2727
cy.get("#mynetwork canvas").trigger(
2828
"pointermove",
29-
from.x + to.x * relativeDistance,
30-
from.y + to.y * relativeDistance,
29+
from.x + (to.x - from.x) * relativeDistance,
30+
from.y + (to.y - from.y) * relativeDistance,
3131
{
3232
button,
3333
shiftKey,

lib/network/Network.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,13 +675,13 @@ Network.prototype.setSelection = function () {
675675
);
676676
};
677677
Network.prototype.getSelectedNodes = function () {
678-
return this.selectionHandler.getSelectedNodes.apply(
678+
return this.selectionHandler.getSelectedNodeIds.apply(
679679
this.selectionHandler,
680680
arguments
681681
);
682682
};
683683
Network.prototype.getSelectedEdges = function () {
684-
return this.selectionHandler.getSelectedEdges.apply(
684+
return this.selectionHandler.getSelectedEdgeIds.apply(
685685
this.selectionHandler,
686686
arguments
687687
);

0 commit comments

Comments
 (0)