Skip to content

Commit

Permalink
fix(select): trigger select events for shift+drag selections (#1133)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Thomaash authored Oct 25, 2020
1 parent ccdd368 commit 4bf8573
Show file tree
Hide file tree
Showing 16 changed files with 2,693 additions and 6,362 deletions.
8 changes: 8 additions & 0 deletions __snapshots__/test/package.test.ts.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ exports['Package Exported files 1'] = {
" declarations/network/modules/components/nodes/util/shapes.d.ts.map",
" declarations/network/modules/layout-engine/index.d.ts",
" declarations/network/modules/layout-engine/index.d.ts.map",
" declarations/network/modules/selection/index.d.ts",
" declarations/network/modules/selection/index.d.ts.map",
" declarations/network/modules/selection/selection-accumulator.d.ts",
" declarations/network/modules/selection/selection-accumulator.d.ts.map",
" declarations/network/options.d.ts",
" declarations/network/shapes.d.ts",
" declarations/network/shapes.d.ts.map",
Expand Down Expand Up @@ -121,6 +125,10 @@ exports['Package Exported files 1'] = {
" dist/types/network/modules/components/nodes/util/shapes.d.ts.map",
" dist/types/network/modules/layout-engine/index.d.ts",
" dist/types/network/modules/layout-engine/index.d.ts.map",
" dist/types/network/modules/selection/index.d.ts",
" dist/types/network/modules/selection/index.d.ts.map",
" dist/types/network/modules/selection/selection-accumulator.d.ts",
" dist/types/network/modules/selection/selection-accumulator.d.ts.map",
" dist/types/network/options.d.ts",
" dist/types/network/shapes.d.ts",
" dist/types/network/shapes.d.ts.map",
Expand Down
119 changes: 119 additions & 0 deletions cypress/integration/functional/selections.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Point, VisEvent } from "../helpers";

const NETWORK_DATA = {
nodes: [
{ id: "N_1", label: "node 1", x: 0, y: 0 },
{ id: "N_2", label: "node 2", x: 200, y: 0 },
{ id: "N_3", label: "node 3", x: 0, y: 200 },
{ id: "N_4", label: "node 4", x: -200, y: 0 },
{ id: "N_5", label: "node 5", x: 0, y: -200 },
],
edges: [
{ id: "E_1-2", label: "edge 1-2", from: "N_1", to: "N_2" },
{ id: "E_1-3", label: "edge 1-3", from: "N_1", to: "N_3" },
{ id: "E_1-4", label: "edge 1-4", from: "N_1", to: "N_4" },
{ id: "E_1-5", label: "edge 1-5", from: "N_1", to: "N_5" },

{ id: "E_2-3", label: "edge 2-3", from: "N_2", to: "N_3" },
{ id: "E_3-4", label: "edge 3-4", from: "N_3", to: "N_4" },
{ id: "E_4-5", label: "edge 4-5", from: "N_4", to: "N_5" },
{ id: "E_5-2", label: "edge 5-2", from: "N_5", to: "N_2" },
],
physics: false,
};

context("Drags", (): void => {
it("Select one by click", function (): void {
cy.visVisitUniversal(NETWORK_DATA);

cy.visClickPoint({ x: 500 + 0, y: 500 + 0 });
cy.visAssertSelection({
nodes: ["N_1"],
edges: ["E_1-2", "E_1-3", "E_1-4", "E_1-5"],
});

cy.visClickPoint({ x: 500 + 200, y: 500 + 0 });
cy.visAssertSelection({
nodes: ["N_2"],
edges: ["E_5-2", "E_1-2", "E_2-3"],
});
});

it("Select none by single drag", function (): void {
cy.visVisitUniversal(NETWORK_DATA);
cy.visDrag([
{
from: { x: 500 + 200 + 70, y: 500 + 200 - 70 },
to: { x: 500 + 200 - 70, y: 500 + 200 + 70 },
button: 0,
shiftKey: true,
},
]);
cy.visAssertSelection({
nodes: [],
edges: [],
});
});

it("Select one by single drag (TL to BR)", function (): void {
cy.visVisitUniversal(NETWORK_DATA);
cy.visDrag([
{
from: { x: 500 + 0 - 70, y: 500 + 0 - 70 },
to: { x: 500 + 0 + 70, y: 500 + 0 + 70 },
button: 0,
shiftKey: true,
},
]);
cy.visAssertSelection({
nodes: ["N_1"],
edges: ["E_1-2", "E_1-3", "E_1-4", "E_1-5"],
});
});

it("Select three by single drag (BR to TL)", function (): void {
cy.visVisitUniversal(NETWORK_DATA);
cy.visDrag([
{
from: { x: 500 + 200 + 70, y: 500 + 200 + 70 },
to: { x: 500 + 0 - 70, y: 500 + 0 - 70 },
button: 0,
shiftKey: true,
},
]);
cy.visAssertSelection({
nodes: ["N_1", "N_2", "N_3"],
edges: ["E_1-2", "E_1-3", "E_1-4", "E_1-5", "E_3-4", "E_2-3", "E_5-2"],
});
});

it("Select three by two drags (TR to BL then BL to TR)", function (): void {
cy.visVisitUniversal(NETWORK_DATA);

cy.visDrag([
{
from: { x: 500 + 0 + 70, y: 500 + 0 - 70 },
to: { x: 500 + 0 - 70, y: 500 + 200 + 70 },
button: 0,
shiftKey: true,
},
]);
cy.visAssertSelection({
nodes: ["N_1", "N_3"],
edges: ["E_1-2", "E_1-3", "E_1-4", "E_1-5", "E_3-4", "E_2-3"],
});

cy.visDrag([
{
from: { x: 500 + 200 - 70, y: 500 + 0 + 70 },
to: { x: 500 + 200 + 70, y: 500 + 0 - 70 },
button: 0,
shiftKey: true,
},
]);
cy.visAssertSelection({
nodes: ["N_1", "N_2", "N_3"],
edges: ["E_1-2", "E_1-3", "E_1-4", "E_1-5", "E_3-4", "E_2-3", "E_5-2"],
});
});
});
25 changes: 21 additions & 4 deletions cypress/pages/standard-cytest-script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,27 @@ type VisUtil = typeof visUtil;
throw new Error("Element #mynetwork was not found in the DOM.");
}

const $events = document.getElementById("events")!;
const $events = document.getElementById("events");
if ($events == null) {
throw new Error("Element #events was not found in the DOM.");
}

const $selection = document.getElementById("selection")!;
const $selection = document.getElementById("selection");
if ($selection == null) {
throw new Error("Element #selection was not found in the DOM.");
}

const $version = document.getElementById("version")!;
const $selectionJSON = document.getElementById("selection-json");
if ($selectionJSON == null) {
throw new Error("Element #selection-json was not found in the DOM.");
}

const $version = document.getElementById("version");
if ($version == null) {
throw new Error("Element #version was not found in the DOM.");
}

const $status = document.getElementById("status")!;
const $status = document.getElementById("status");
if ($status == null) {
throw new Error("Element #status was not found in the DOM.");
}
Expand Down Expand Up @@ -191,6 +196,16 @@ type VisUtil = typeof visUtil;
});
});

const updateSelectionJSON = (): void => {
const selection = network.getSelection();
$selectionJSON.innerText = JSON.stringify({
nodes: [...selection.nodes].sort(),
edges: [...selection.edges].sort(),
});
};
// Make sure the selection is always filled in.
updateSelectionJSON();

// Selection events:
([
"deselectEdge",
Expand All @@ -199,6 +214,8 @@ type VisUtil = typeof visUtil;
"selectEdge",
"selectNode",
] as const).forEach((eventName): void => {
network.on(eventName, updateSelectionJSON);

network.on(eventName, (): void => {
const selection = [
["node", network.getSelectedNodes()],
Expand Down
1 change: 1 addition & 0 deletions cypress/pages/universal.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ <h1>Info</h1>
<div>
<h1>Selection</h1>
<div id="selection"></div>
<pre id="selection-json"></pre>
</div>

<div>
Expand Down
1 change: 1 addition & 0 deletions cypress/support/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./types";

export * from "./vis-assert-selection";
export * from "./vis-check-ids";
export * from "./vis-click-betweek-points";
export * from "./vis-click-edge";
Expand Down
2 changes: 2 additions & 0 deletions cypress/support/commands/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ export interface UniversalNetworkConfig {
export interface UniversalConfig extends UniversalNetworkConfig {
version: null | "latest";
}

export type IdType = string | number;
41 changes: 41 additions & 0 deletions cypress/support/commands/vis-assert-selection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { IdType } from "./types";

declare global {
namespace Cypress {
interface Chainable<Subject> {
/**
* Check selected nodes and edges.
*
* @param selection - The same format as in Network.getSelection().
*/
visAssertSelection(selection: {
nodes: IdType[];
edges: IdType[];
}): Chainable<Subject>;
}
}
}

function sortSelection(selection: {
nodes: IdType[];
edges: IdType[];
}): {
nodes: IdType[];
edges: IdType[];
} {
return {
nodes: [...selection.nodes].sort(),
edges: [...selection.edges].sort(),
};
}

export function visAssertSelection(expectedSelection: {
nodes: IdType[];
edges: IdType[];
}): void {
cy.get("#selection-json").should(
"have.text",
JSON.stringify(sortSelection(expectedSelection))
);
}
Cypress.Commands.add("visAssertSelection", visAssertSelection);
4 changes: 2 additions & 2 deletions cypress/support/commands/vis-drag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export function visDrag(paths: readonly DragPath[]): void {
)) {
cy.get("#mynetwork canvas").trigger(
"pointermove",
from.x + to.x * relativeDistance,
from.y + to.y * relativeDistance,
from.x + (to.x - from.x) * relativeDistance,
from.y + (to.y - from.y) * relativeDistance,
{
button,
shiftKey,
Expand Down
4 changes: 2 additions & 2 deletions lib/network/Network.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,13 +675,13 @@ Network.prototype.setSelection = function () {
);
};
Network.prototype.getSelectedNodes = function () {
return this.selectionHandler.getSelectedNodes.apply(
return this.selectionHandler.getSelectedNodeIds.apply(
this.selectionHandler,
arguments
);
};
Network.prototype.getSelectedEdges = function () {
return this.selectionHandler.getSelectedEdges.apply(
return this.selectionHandler.getSelectedEdgeIds.apply(
this.selectionHandler,
arguments
);
Expand Down
Loading

0 comments on commit 4bf8573

Please sign in to comment.