From 4046ad09dbe944c946bf9a4fdb64e38f1f386282 Mon Sep 17 00:00:00 2001 From: Manuel Date: Tue, 17 Dec 2024 18:12:10 -0300 Subject: [PATCH 1/5] feat: changing layer view --- src/context.ts | 6 +++ src/index.ts | 22 +++++----- src/types/devices/utils.ts | 15 +++++++ src/types/graphs/datagraph.ts | 2 +- src/types/graphs/viewgraph.ts | 79 ++++++++++++++++++++++++++++------- 5 files changed, 96 insertions(+), 28 deletions(-) diff --git a/src/context.ts b/src/context.ts index 3a86d22e..6492a640 100644 --- a/src/context.ts +++ b/src/context.ts @@ -6,6 +6,7 @@ import { saveToLocalStorage, } from "./types/viewportManager"; import { Layer } from "./types/devices/device"; +import { layerFromName } from "./types/devices/utils"; export class GlobalContext { private viewport: Viewport = null; @@ -42,6 +43,11 @@ export class GlobalContext { return this.datagraph; } + changeViewGraph(selectedLayer: string) { + const layer = layerFromName(selectedLayer); + this.setNetwork(this.datagraph, layer); + } + private setupAutoSave() { this.clearAutoSave(); diff --git a/src/index.ts b/src/index.ts index bc230eb9..f1f93ffa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -125,20 +125,20 @@ import PauseSvg from "./assets/pause-icon.svg"; pauseButton.onclick = triggerPause; // (!) For layer abstraction functionality - // const layerSelect = document.getElementById( - // "layer-select", - // ) as HTMLSelectElement; + const layerSelect = document.getElementById( + "layer-select", + ) as HTMLSelectElement; - // const selectNewLayer = (event: Event) => { - // const selectedLayer = (event.target as HTMLSelectElement).value; - // console.log(`Layer selected: ${selectedLayer}`); + const selectNewLayer = (event: Event) => { + const selectedLayer = (event.target as HTMLSelectElement).value; + console.log(`Layer selected: ${selectedLayer}`); - // if (selectElement) { - // ctx.changeViewGraph(selectedLayer); - // } - // }; + if (selectedLayer) { + ctx.changeViewGraph(selectedLayer); + } + }; - // layerSelect.onchange = selectNewLayer; + layerSelect.onchange = selectNewLayer; document.body.onkeyup = function (e) { if (e.key === " " || e.code === "Space") { diff --git a/src/types/devices/utils.ts b/src/types/devices/utils.ts index 5606b3b7..d6683f44 100644 --- a/src/types/devices/utils.ts +++ b/src/types/devices/utils.ts @@ -45,3 +45,18 @@ export function layerFromName(name: string): Layer { return Layer.Link; } } + +export function layerIncluded(layer1: Layer, layer2: Layer) { + // Determines whether layer1 is included within layer2’s abstraction. + console.log(`${layer1.valueOf()} <= ${layer2.valueOf()}`); + return layer1.valueOf() <= layer2.valueOf(); +} + +export function layerFromType(type: DeviceType) { + switch (type) { + case DeviceType.Router: + return Layer.Network; + case DeviceType.Host: + return Layer.App; + } +} diff --git a/src/types/graphs/datagraph.ts b/src/types/graphs/datagraph.ts index 56e73814..5dfcc1a4 100644 --- a/src/types/graphs/datagraph.ts +++ b/src/types/graphs/datagraph.ts @@ -24,7 +24,7 @@ export interface NewDevice { } export class DataGraph { - private devices = new Map(); + devices = new Map(); private idCounter = 1; private onChanges: (() => void)[] = []; diff --git a/src/types/graphs/viewgraph.ts b/src/types/graphs/viewgraph.ts index 46d2ea4a..de6dfe6c 100644 --- a/src/types/graphs/viewgraph.ts +++ b/src/types/graphs/viewgraph.ts @@ -1,9 +1,14 @@ import { Device } from "./../devices/index"; // Import the Device class import { Edge } from "./../edge"; -import { DataGraph } from "./datagraph"; +import { DataGraph, GraphNode } from "./datagraph"; import { Viewport } from "../../graphics/viewport"; import { Layer } from "../devices/device"; -import { createDevice } from "../devices/utils"; +import { createDevice, layerFromType, layerIncluded } from "../devices/utils"; + +interface Connection { + id1: number; + id2: number; +} export class ViewGraph { private devices: Map = new Map(); @@ -23,26 +28,38 @@ export class ViewGraph { private constructView() { // TODO: Adjust construction based on the selected layer in the future console.log("Constructing ViewGraph from DataGraph"); - const connections = new Set<{ deviceId: number; adyacentId: number }>(); + const connections = new Set(); this.datagraph.getDevices().forEach(([deviceId, graphNode]) => { - const deviceInfo = { ...graphNode, id: deviceId }; - const device: Device = createDevice(deviceInfo, this); + if (layerIncluded(layerFromType(graphNode.type), this.layer)) { + const deviceInfo = { ...graphNode, id: deviceId }; + const device: Device = createDevice(deviceInfo, this); - this.viewport.addChild(device); + this.viewport.addChild(device); - this.addDevice(device); - graphNode.connections.forEach((adyacentId) => { - if (!connections.has({ deviceId: adyacentId, adyacentId: deviceId })) { - connections.add({ deviceId, adyacentId }); - } - }); + this.addDevice(device); + + this.layer_dfs( + this.datagraph.devices, + deviceId, + deviceId, + new Set([deviceId]), + connections, + ); + // graphNode.connections.forEach((adyacentId) => { + // if (!connections.has({ id1: adyacentId, id2: deviceId })) { + // connections.add({ id1: deviceId, id2: adyacentId }); + // } + // }); + } }); - console.log("Finished creating devices in ViewGraph"); - connections.forEach(({ deviceId, adyacentId }) => { - const device1 = this.getDevice(deviceId); - const device2 = this.getDevice(adyacentId); + console.log("Finished creating devices in ViewGraph, connections are"); + console.log(connections); + connections.forEach(({ id1, id2 }) => { + console.log(`${id1}, ${id2}`); + const device1 = this.getDevice(id1); + const device2 = this.getDevice(id2); device1.connectTo(device2.id); }); console.log("Finished constructing ViewGraph"); @@ -265,4 +282,34 @@ export class ViewGraph { } return path.reverse(); } + + private layer_dfs( + graph: Map, + s: number, // source node + v: number, + visited: Set, + connections: Set, + ) { + const node = this.datagraph.getDevice(v); + graph.get(v).connections.forEach((w) => { + console.log(`Se accede a ${w} desde ${v}`); + if (!visited.has(w)) { + console.log(`Se visita ${w}`); + const adyacent = this.datagraph.getDevice(w); + // mark node as visited + visited.add(w); + if (layerIncluded(layerFromType(adyacent.type), this.layer)) { + // add connection between v and w + const connection: Connection = { id1: w, id2: s }; + if (!connections.has(connection)) { + console.log(`Dispositivos agregados a conexion`); + connections.add({ id1: s, id2: w }); + } + } else { + // continue with recursive search + this.layer_dfs(graph, s, w, visited, connections); + } + } + }); + } } From 912d0a1ded5f7ea77b9b20217d12b53106c59bad Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 18 Dec 2024 15:06:33 -0300 Subject: [PATCH 2/5] refactor: split viegraph tasks, adding new edge and drawing the edge --- src/types/graphs/viewgraph.ts | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/types/graphs/viewgraph.ts b/src/types/graphs/viewgraph.ts index 3368f612..85de8f4e 100644 --- a/src/types/graphs/viewgraph.ts +++ b/src/types/graphs/viewgraph.ts @@ -45,7 +45,9 @@ export class ViewGraph { connections.forEach(({ deviceId, adyacentId }) => { const device1 = this.getDevice(deviceId); const device2 = this.getDevice(adyacentId); - device1.connectTo(device2.id); + const edge = this.drawEdge(device1, device2); + device1.addConnection(edge.id, device2.id); + device2.addConnection(edge.id, device1.id); }); console.log("Finished constructing ViewGraph"); } @@ -60,6 +62,19 @@ export class ViewGraph { } } + drawEdge(device1: Device, device2: Device): Edge { + const edge = new Edge( + this.idCounter++, + { n1: device1.id, n2: device2.id }, + device1, + device2, + this, + ); + this.edges.set(edge.id, edge); + this.viewport.addChild(edge); + return edge; + } + // Add a connection between two devices addEdge(device1Id: DeviceId, device2Id: DeviceId): EdgeId | null { if (device1Id === device2Id) { @@ -92,17 +107,9 @@ export class ViewGraph { const device2 = this.devices.get(device2Id); if (device1 && device2) { - const edge = new Edge( - this.idCounter++, - { n1: device1Id, n2: device2Id }, - device1, - device2, - this, - ); - this.edges.set(edge.id, edge); + const edge = this.drawEdge(device1, device2); this.datagraph.addEdge(device1Id, device2Id); - this.viewport.addChild(edge); console.log( `Connection created between devices ID: ${device1Id} and ID: ${device2Id}`, From a6e76c4a0c4a6187c205b009de2b2c14cbe2f6e9 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 18 Dec 2024 16:43:24 -0300 Subject: [PATCH 3/5] fix: merging inconsistencies resolved --- src/types/graphs/datagraph.ts | 6 +++--- src/types/graphs/viewgraph.ts | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/types/graphs/datagraph.ts b/src/types/graphs/datagraph.ts index 53382aa9..48d94189 100644 --- a/src/types/graphs/datagraph.ts +++ b/src/types/graphs/datagraph.ts @@ -80,7 +80,7 @@ export class DataGraph { const graphData: GraphData = []; // Serialize nodes - this.getDevices().forEach(([id, info]) => { + this.getDevices().forEach((info, id) => { const graphNode: GraphDataNode = { id, x: info.x, @@ -206,8 +206,8 @@ export class DataGraph { } // Get all devices in the graph - getDevices(): [DeviceId, GraphNode][] { - return Array.from(this.devices.entries()); + getDevices(): Map { + return this.devices; } // Get the number of devices in the graph diff --git a/src/types/graphs/viewgraph.ts b/src/types/graphs/viewgraph.ts index da9da52b..45763c57 100644 --- a/src/types/graphs/viewgraph.ts +++ b/src/types/graphs/viewgraph.ts @@ -1,13 +1,13 @@ import { Device } from "./../devices/index"; // Import the Device class import { Edge } from "./../edge"; -import { DataGraph, DeviceId, isRouter } from "./datagraph"; +import { DataGraph, DeviceId, GraphNode, isRouter } from "./datagraph"; import { Viewport } from "../../graphics/viewport"; import { Layer } from "../devices/device"; import { createDevice, layerFromType, layerIncluded } from "../devices/utils"; interface Connection { - id1: number; - id2: number; + id1: DeviceId; + id2: DeviceId; } export type EdgeId = number; @@ -32,7 +32,7 @@ export class ViewGraph { console.log("Constructing ViewGraph from DataGraph"); const connections = new Set(); - this.datagraph.getDevices().forEach(([deviceId, graphNode]) => { + this.datagraph.getDevices().forEach((graphNode, deviceId) => { if (layerIncluded(layerFromType(graphNode.type), this.layer)) { const deviceInfo = { ...graphNode, id: deviceId }; const device: Device = createDevice(deviceInfo, this); @@ -42,7 +42,7 @@ export class ViewGraph { this.addDevice(device); this.layer_dfs( - this.datagraph.devices, + this.datagraph.getDevices(), deviceId, deviceId, new Set([deviceId]), @@ -294,7 +294,7 @@ export class ViewGraph { } private layer_dfs( - graph: Map, + graph: Map, s: number, // source node v: number, visited: Set, From e549deeedf82b9a986abd4eaa2d33f03f4f95cfb Mon Sep 17 00:00:00 2001 From: Manuel Date: Sun, 29 Dec 2024 23:31:30 -0300 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20devices=E2=80=99=20buttons=20change?= =?UTF-8?q?d=20when=20switching=20layer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/graphics/left_bar.ts | 4 ++++ src/index.ts | 26 ++++++++++++++++++++++++++ src/types/devices/utils.ts | 1 - src/types/graphs/viewgraph.ts | 4 ---- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/graphics/left_bar.ts b/src/graphics/left_bar.ts index 4e425442..90a19fd0 100644 --- a/src/graphics/left_bar.ts +++ b/src/graphics/left_bar.ts @@ -22,4 +22,8 @@ export class LeftBar { img.classList.add("icon-img"); button.appendChild(img); } + + clear() { + this.leftBar.textContent = ""; + } } diff --git a/src/index.ts b/src/index.ts index 0fa6f9f0..0b2d60fc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -135,6 +135,32 @@ import PauseSvg from "./assets/pause-icon.svg"; if (selectedLayer) { ctx.changeViewGraph(selectedLayer); + + // LeftBar is reset + leftBar.clear(); + switch (selectedLayer) { + case "application": + case "transport": + leftBar.addButton( + ComputerSvg, + () => AddDevice(ctx, DeviceType.Host), + "Add Host", + ); + break; + case "network": + case "link": + leftBar.addButton( + RouterSvg, + () => AddDevice(ctx, DeviceType.Router), + "Add Router", + ); + leftBar.addButton( + ComputerSvg, + () => AddDevice(ctx, DeviceType.Host), + "Add Host", + ); + break; + } } }; diff --git a/src/types/devices/utils.ts b/src/types/devices/utils.ts index 2b7224d6..cd0e25dd 100644 --- a/src/types/devices/utils.ts +++ b/src/types/devices/utils.ts @@ -53,7 +53,6 @@ export function layerFromName(name: string): Layer { export function layerIncluded(layer1: Layer, layer2: Layer) { // Determines whether layer1 is included within layer2’s abstraction. - console.log(`${layer1.valueOf()} <= ${layer2.valueOf()}`); return layer1.valueOf() <= layer2.valueOf(); } diff --git a/src/types/graphs/viewgraph.ts b/src/types/graphs/viewgraph.ts index de345b36..77d4e7ec 100644 --- a/src/types/graphs/viewgraph.ts +++ b/src/types/graphs/viewgraph.ts @@ -57,7 +57,6 @@ export class ViewGraph { } }); - console.log("Finished creating devices in ViewGraph"); connections.forEach((key) => { const connection = parseConnectionKey(key); const device1 = this.getDevice(connection.id1); @@ -308,9 +307,7 @@ export class ViewGraph { connections: Set, ) { graph.get(v).connections.forEach((w) => { - console.log(`Se accede a ${w} desde ${v}`); if (!visited.has(w)) { - console.log(`Se visita ${w}`); const adyacent = this.datagraph.getDevice(w); // mark node as visited visited.add(w); @@ -318,7 +315,6 @@ export class ViewGraph { // add connection between v and w const connectionKey: string = generateConnectionKey(w, s); if (!connections.has(connectionKey)) { - console.log(`Dispositivos agregados a conexion`); connections.add(connectionKey); } } else { From 03af0d24283f53b01b700ce433f71db9c61292b3 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 30 Dec 2024 10:37:31 -0300 Subject: [PATCH 5/5] lint fix --- src/types/viewportManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/viewportManager.ts b/src/types/viewportManager.ts index adb5dca6..740bd03b 100644 --- a/src/types/viewportManager.ts +++ b/src/types/viewportManager.ts @@ -4,7 +4,7 @@ import { Device } from "./devices/index"; import { Edge } from "./edge"; import { RightBar } from "../graphics/right_bar"; import { Packet } from "./packet"; -import { DeviceType, Layer } from "./devices/device"; +import { DeviceType } from "./devices/device"; import { createDevice, layerFromName } from "./devices/utils"; type Selectable = Device | Edge | Packet;