Skip to content

Commit a81aa43

Browse files
authored
Switch layer (#67)
Done #19 Different set of devices are shown for each layer, depending on which devices belong to the abstraction layer. Also, abstracted connections are made for upper layers to show connection between to devices.
1 parent 60cc9ee commit a81aa43

File tree

5 files changed

+114
-40
lines changed

5 files changed

+114
-40
lines changed

src/context.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from "./types/viewportManager";
88
import { Layer } from "./types/devices/device";
99
import { IpAddressGenerator } from "./packets/ip";
10+
import { layerFromName } from "./types/devices/utils";
1011

1112
export class GlobalContext {
1213
private viewport: Viewport = null;
@@ -52,6 +53,11 @@ export class GlobalContext {
5253
return this.datagraph;
5354
}
5455

56+
changeViewGraph(selectedLayer: string) {
57+
const layer = layerFromName(selectedLayer);
58+
this.setNetwork(this.datagraph, layer);
59+
}
60+
5561
private setupAutoSave() {
5662
this.clearAutoSave();
5763

src/index.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -125,20 +125,20 @@ import PauseSvg from "./assets/pause-icon.svg";
125125
pauseButton.onclick = triggerPause;
126126

127127
// (!) For layer abstraction functionality
128-
// const layerSelect = document.getElementById(
129-
// "layer-select",
130-
// ) as HTMLSelectElement;
128+
const layerSelect = document.getElementById(
129+
"layer-select",
130+
) as HTMLSelectElement;
131131

132-
// const selectNewLayer = (event: Event) => {
133-
// const selectedLayer = (event.target as HTMLSelectElement).value;
134-
// console.log(`Layer selected: ${selectedLayer}`);
132+
const selectNewLayer = (event: Event) => {
133+
const selectedLayer = (event.target as HTMLSelectElement).value;
134+
console.log(`Layer selected: ${selectedLayer}`);
135135

136-
// if (selectElement) {
137-
// ctx.changeViewGraph(selectedLayer);
138-
// }
139-
// };
136+
if (selectedLayer) {
137+
ctx.changeViewGraph(selectedLayer);
138+
}
139+
};
140140

141-
// layerSelect.onchange = selectNewLayer;
141+
layerSelect.onchange = selectNewLayer;
142142

143143
document.body.onkeyup = function (e) {
144144
if (e.key === " " || e.code === "Space") {

src/types/devices/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,18 @@ export function layerFromName(name: string): Layer {
5050
return Layer.Link;
5151
}
5252
}
53+
54+
export function layerIncluded(layer1: Layer, layer2: Layer) {
55+
// Determines whether layer1 is included within layer2’s abstraction.
56+
console.log(`${layer1.valueOf()} <= ${layer2.valueOf()}`);
57+
return layer1.valueOf() <= layer2.valueOf();
58+
}
59+
60+
export function layerFromType(type: DeviceType) {
61+
switch (type) {
62+
case DeviceType.Router:
63+
return Layer.Network;
64+
case DeviceType.Host:
65+
return Layer.App;
66+
}
67+
}

src/types/graphs/datagraph.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export class DataGraph {
8080
const graphData: GraphData = [];
8181

8282
// Serialize nodes
83-
this.getDevices().forEach(([id, info]) => {
83+
this.getDevices().forEach((info, id) => {
8484
const graphNode: GraphDataNode = {
8585
id,
8686
x: info.x,
@@ -206,8 +206,8 @@ export class DataGraph {
206206
}
207207

208208
// Get all devices in the graph
209-
getDevices(): [DeviceId, GraphNode][] {
210-
return Array.from(this.devices.entries());
209+
getDevices(): Map<DeviceId, GraphNode> {
210+
return this.devices;
211211
}
212212

213213
// Get the number of devices in the graph

src/types/graphs/viewgraph.ts

Lines changed: 79 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
import { Device } from "./../devices/index"; // Import the Device class
22
import { Edge } from "./../edge";
3-
import { DataGraph, DeviceId, isRouter } from "./datagraph";
3+
import { DataGraph, DeviceId, GraphNode, isRouter } from "./datagraph";
44
import { Viewport } from "../../graphics/viewport";
55
import { Layer } from "../devices/device";
6-
import { createDevice } from "../devices/utils";
6+
import { createDevice, layerFromType, layerIncluded } from "../devices/utils";
77

88
export type EdgeId = number;
99

10+
function generateConnectionKey(id1: number, id2: number): string {
11+
return [id1, id2].sort().join(",");
12+
}
13+
14+
function parseConnectionKey(key: string): { id1: number; id2: number } {
15+
const connection: number[] = key
16+
.split(",")
17+
.map((value) => parseInt(value.trim()));
18+
return { id1: connection[0], id2: connection[1] };
19+
}
20+
1021
export class ViewGraph {
1122
private devices: Map<DeviceId, Device> = new Map<DeviceId, Device>();
1223
private edges: Map<EdgeId, Edge> = new Map<EdgeId, Edge>();
@@ -25,27 +36,35 @@ export class ViewGraph {
2536
private constructView() {
2637
// TODO: Adjust construction based on the selected layer in the future
2738
console.log("Constructing ViewGraph from DataGraph");
28-
const connections = new Set<{ deviceId: DeviceId; adyacentId: DeviceId }>();
39+
const connections = new Set<string>();
2940

30-
this.datagraph.getDevices().forEach(([deviceId, graphNode]) => {
31-
const deviceInfo = { ...graphNode, id: deviceId };
32-
const device: Device = createDevice(deviceInfo, this);
41+
this.datagraph.getDevices().forEach((graphNode, deviceId) => {
42+
if (layerIncluded(layerFromType(graphNode.type), this.layer)) {
43+
const deviceInfo = { ...graphNode, id: deviceId };
44+
const device: Device = createDevice(deviceInfo, this);
3345

34-
this.viewport.addChild(device);
46+
this.viewport.addChild(device);
3547

36-
this.addDevice(device);
37-
graphNode.connections.forEach((adyacentId) => {
38-
if (!connections.has({ deviceId: adyacentId, adyacentId: deviceId })) {
39-
connections.add({ deviceId, adyacentId });
40-
}
41-
});
48+
this.addDevice(device);
49+
50+
this.layer_dfs(
51+
this.datagraph.getDevices(),
52+
deviceId,
53+
deviceId,
54+
new Set([deviceId]),
55+
connections,
56+
);
57+
}
4258
});
4359

4460
console.log("Finished creating devices in ViewGraph");
45-
connections.forEach(({ deviceId, adyacentId }) => {
46-
const device1 = this.getDevice(deviceId);
47-
const device2 = this.getDevice(adyacentId);
48-
device1.connectTo(device2.id);
61+
connections.forEach((key) => {
62+
const connection = parseConnectionKey(key);
63+
const device1 = this.getDevice(connection.id1);
64+
const device2 = this.getDevice(connection.id2);
65+
const edge = this.drawEdge(device1, device2);
66+
device1.addConnection(edge.id, device2.id);
67+
device2.addConnection(edge.id, device1.id);
4968
});
5069
console.log("Finished constructing ViewGraph");
5170
}
@@ -60,6 +79,19 @@ export class ViewGraph {
6079
}
6180
}
6281

82+
drawEdge(device1: Device, device2: Device): Edge {
83+
const edge = new Edge(
84+
this.idCounter++,
85+
{ n1: device1.id, n2: device2.id },
86+
device1,
87+
device2,
88+
this,
89+
);
90+
this.edges.set(edge.id, edge);
91+
this.viewport.addChild(edge);
92+
return edge;
93+
}
94+
6395
// Add a connection between two devices
6496
addEdge(device1Id: DeviceId, device2Id: DeviceId): EdgeId | null {
6597
if (device1Id === device2Id) {
@@ -92,17 +124,9 @@ export class ViewGraph {
92124
const device2 = this.devices.get(device2Id);
93125

94126
if (device1 && device2) {
95-
const edge = new Edge(
96-
this.idCounter++,
97-
{ n1: device1Id, n2: device2Id },
98-
device1,
99-
device2,
100-
this,
101-
);
102-
this.edges.set(edge.id, edge);
127+
const edge = this.drawEdge(device1, device2);
103128

104129
this.datagraph.addEdge(device1Id, device2Id);
105-
this.viewport.addChild(edge);
106130

107131
console.log(
108132
`Connection created between devices ID: ${device1Id} and ID: ${device2Id}`,
@@ -275,4 +299,33 @@ export class ViewGraph {
275299
}
276300
return path.reverse();
277301
}
302+
303+
private layer_dfs(
304+
graph: Map<DeviceId, GraphNode>,
305+
s: number, // source node
306+
v: number,
307+
visited: Set<number>,
308+
connections: Set<string>,
309+
) {
310+
graph.get(v).connections.forEach((w) => {
311+
console.log(`Se accede a ${w} desde ${v}`);
312+
if (!visited.has(w)) {
313+
console.log(`Se visita ${w}`);
314+
const adyacent = this.datagraph.getDevice(w);
315+
// mark node as visited
316+
visited.add(w);
317+
if (layerIncluded(layerFromType(adyacent.type), this.layer)) {
318+
// add connection between v and w
319+
const connectionKey: string = generateConnectionKey(w, s);
320+
if (!connections.has(connectionKey)) {
321+
console.log(`Dispositivos agregados a conexion`);
322+
connections.add(connectionKey);
323+
}
324+
} else {
325+
// continue with recursive search
326+
this.layer_dfs(graph, s, w, visited, connections);
327+
}
328+
}
329+
});
330+
}
278331
}

0 commit comments

Comments
 (0)