Skip to content

Commit 0b7626b

Browse files
authored
Highlight all merged edges and unify information (#242)
close #201
1 parent 3817fe1 commit 0b7626b

File tree

8 files changed

+101
-18
lines changed

8 files changed

+101
-18
lines changed

src/graphics/renderables/base_info.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ export abstract class BaseInfo implements Renderable {
1111

1212
constructor(title: string) {
1313
this.information = new TextInfo(title);
14-
this.addDivider();
1514
this.addCommonButtons();
16-
this.addDivider();
1715
}
1816

1917
protected abstract addCommonInfoFields(): void;

src/graphics/renderables/device_info.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export class DeviceInfo extends BaseInfo {
5050
}
5151

5252
protected addCommonButtons(): void {
53+
this.addDivider();
5354
const connectButton = new Button({
5455
text: TOOLTIP_KEYS.CONNECT_DEVICE,
5556
onClick: () => this.device.selectToConnect(),
@@ -75,6 +76,7 @@ export class DeviceInfo extends BaseInfo {
7576
});
7677

7778
this.inputFields.push(connectButton.toHTML(), deleteButton.toHTML());
79+
this.addDivider();
7880
}
7981

8082
addProgramRunner(runner: ProgramRunner, programs: ProgramInfo[]): void {

src/graphics/renderables/edge_info.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export class EdgeInfo extends BaseInfo {
6565

6666
protected addCommonButtons(): void {
6767
// Button to delete the edge
68+
this.addDivider();
6869
const deleteEdgeButton = new Button({
6970
text: TOOLTIP_KEYS.DELETE_EDGE_BUTTON,
7071
onClick: () => {
@@ -84,6 +85,7 @@ export class EdgeInfo extends BaseInfo {
8485

8586
// Add the button to the inputFields array
8687
this.inputFields.push(deleteEdgeButton.toHTML());
88+
this.addDivider();
8789
}
8890

8991
protected addInterfaceDropdowns(): void {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Edge } from "../../types/edge";
2+
import { BaseInfo } from "./base_info";
3+
import { TOOLTIP_KEYS } from "../../utils/constants/tooltips_constants";
4+
5+
export class MultiEdgeInfo extends BaseInfo {
6+
protected addCommonInfoFields(): void {
7+
return;
8+
}
9+
protected addCommonButtons(): void {
10+
return;
11+
}
12+
readonly edges: Edge[];
13+
14+
constructor(edges: Edge[]) {
15+
super(TOOLTIP_KEYS.EDGE_INFORMATION);
16+
this.edges = edges;
17+
this.addCombinedInfoFields();
18+
}
19+
20+
protected addCombinedInfoFields(): void {
21+
const visibleDevices = new Set<number>();
22+
23+
this.edges.forEach((edge) => {
24+
const fromDevice = edge.viewgraph.getDevice(edge.data.from.id);
25+
const toDevice = edge.viewgraph.getDevice(edge.data.to.id);
26+
27+
if (fromDevice && fromDevice.visible) {
28+
visibleDevices.add(fromDevice.id);
29+
}
30+
if (toDevice && toDevice.visible) {
31+
visibleDevices.add(toDevice.id);
32+
}
33+
});
34+
35+
this.information.addListField(
36+
"Connected Devices",
37+
Array.from(visibleDevices),
38+
TOOLTIP_KEYS.MULTI_EDGE_CONNECTED_DEVICES,
39+
);
40+
}
41+
}

src/graphics/renderables/packet_info.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class PacketInfo extends BaseInfo {
8686
}
8787

8888
protected addCommonButtons(): void {
89-
// Botón para descartar el paquete
89+
this.addDivider();
9090
const discardPacketButton = new Button({
9191
text: TOOLTIP_KEYS.DISCARD_PACKET_BUTTON,
9292
onClick: () => {
@@ -100,18 +100,16 @@ export class PacketInfo extends BaseInfo {
100100
tooltip: TOOLTIP_KEYS.DISCARD_PACKET_BUTTON,
101101
});
102102

103-
// Agregar el botón al array de inputFields
104103
this.inputFields.push(discardPacketButton.toHTML());
104+
this.addDivider();
105105
}
106106

107107
private addToggleInfo(): void {
108-
// Obtener los detalles del paquete
109108
const packetDetails = this.packet.getPacketDetails(
110109
this.packet.viewgraph.getLayer(),
111110
this.packet.rawPacket,
112111
);
113112

114-
// Crear un ToggleInfo para los detalles del paquete
115113
const toggleInfo = new ToggleInfo({
116114
title: "Packet Details",
117115
fields: Object.entries(packetDetails).map(([key, value]) => ({
@@ -124,7 +122,6 @@ export class PacketInfo extends BaseInfo {
124122
},
125123
});
126124

127-
// Agregar el ToggleInfo al array de inputFields
128125
this.inputFields.push(toggleInfo.toHTML());
129126
}
130127
}

src/types/edge.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Packet } from "./packet";
88
import { EdgeInfo } from "../graphics/renderables/edge_info";
99
import { DataEdge, DeviceId } from "./graphs/datagraph";
1010
import { MacAddress } from "../packets/ethernet";
11+
import { MultiEdgeInfo } from "../graphics/renderables/multi_edge_info";
1112
import {
1213
hideTooltip,
1314
removeTooltip,
@@ -18,8 +19,9 @@ export class Edge extends Graphics {
1819
private _data: DataEdge;
1920
private startPos: Point;
2021
private endPos: Point;
21-
private startTooltip: Text | null = null; // Tooltip para el extremo inicial
22-
private endTooltip: Text | null = null; // Tooltip para el extremo final
22+
private highlightedEdges: Edge[] = [];
23+
private startTooltip: Text | null = null; // Tooltip for the start of the edge
24+
private endTooltip: Text | null = null; // Tooltip for the end of the edge
2325

2426
viewgraph: ViewGraph;
2527

@@ -104,12 +106,15 @@ export class Edge extends Graphics {
104106
}
105107

106108
select() {
107-
this.highlight();
109+
this.highlightedEdges = this.viewgraph.findConnectedEdges(this);
110+
this.highlightedEdges.forEach((edge) => edge.highlight());
108111
this.showInfo();
109112
}
110113

111114
deselect() {
112-
this.removeHighlight();
115+
// remove highlight from all edges
116+
this.highlightedEdges.forEach((edge) => edge.removeHighlight());
117+
this.highlightedEdges = [];
113118
}
114119

115120
highlight() {
@@ -120,10 +125,14 @@ export class Edge extends Graphics {
120125
this.drawEdge(this.startPos, this.endPos, Colors.Lightblue);
121126
}
122127

123-
// Method to show the Edge information
124128
showInfo() {
125-
const edgeInfo = new EdgeInfo(this);
126-
RightBar.getInstance().renderInfo(edgeInfo);
129+
if (this.highlightedEdges && this.highlightedEdges.length > 1) {
130+
const multiEdgeInfo = new MultiEdgeInfo(this.highlightedEdges);
131+
RightBar.getInstance().renderInfo(multiEdgeInfo);
132+
} else {
133+
const edgeInfo = new EdgeInfo(this);
134+
RightBar.getInstance().renderInfo(edgeInfo);
135+
}
127136
}
128137

129138
destroy(): void {
@@ -244,12 +253,15 @@ export class Edge extends Graphics {
244253

245254
private setupHoverTooltip() {
246255
this.on("mouseover", () => {
247-
this.showTooltips();
248-
this.fixTooltipPositions(); // fixes the tooltip positions
256+
const group = this.viewgraph.findConnectedEdges(this);
257+
group.forEach((edge) => {
258+
edge.showTooltips();
259+
edge.fixTooltipPositions();
260+
});
249261
});
250-
251262
this.on("mouseout", () => {
252-
this.hideTooltips();
263+
const group = this.viewgraph.findConnectedEdges(this);
264+
group.forEach((edge) => edge.hideTooltips());
253265
});
254266
}
255267

src/types/graphs/viewgraph.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,34 @@ export class ViewGraph {
486486
}
487487
this.graph.clear();
488488
}
489+
490+
/**
491+
* Finds all edges connected to the given edge, ignoring nodes that are not visible.
492+
*/
493+
findConnectedEdges(edge: Edge): Edge[] {
494+
const visitedEdges = new Set<Edge>();
495+
const queue: Edge[] = [edge];
496+
497+
while (queue.length > 0) {
498+
const currentEdge = queue.shift();
499+
if (!currentEdge || visitedEdges.has(currentEdge)) continue;
500+
visitedEdges.add(currentEdge);
501+
502+
for (const nodeId of currentEdge.getDeviceIds()) {
503+
const device = this.getDevice(nodeId);
504+
if (device && device.visible) {
505+
continue;
506+
}
507+
const edges = this.getConnections(nodeId);
508+
for (const e of edges) {
509+
if (!visitedEdges.has(e)) {
510+
queue.push(e);
511+
}
512+
}
513+
}
514+
}
515+
return Array.from(visitedEdges);
516+
}
489517
}
490518

491519
function layerDFS(

src/utils/constants/tooltips_constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export const TOOLTIP_KEYS = {
6868
IP_REQUEST: "IP to Request",
6969
ARP_TABLE: "ARP Table",
7070
IFACE_EDITOR: "iface-editor",
71+
MULTI_EDGE_CONNECTED_DEVICES: "Multi Edge Connected Devices",
7172
} as const;
7273

7374
// Tooltip Content
@@ -190,6 +191,8 @@ export const TOOLTIP_CONTENT = {
190191
"The ARP (Address Resolution Protocol) table maps IP addresses to MAC addresses. It is used to resolve the hardware address of a device in the same local network.",
191192
[TOOLTIP_KEYS.IFACE_EDITOR]:
192193
"Modify the network interface used by this device.",
194+
[TOOLTIP_KEYS.MULTI_EDGE_CONNECTED_DEVICES]:
195+
"This field shows the devices connected to the selected edge. It provides a list of all devices that are directly connected.",
193196
[TOOLTIP_KEYS.SEND_ARP_REQUEST]:
194197
"Send an ARP request to a specified IP address. This command is used to resolve the MAC address of a device in the same local network.",
195198
[TOOLTIP_KEYS.SERVE_HTTP_REQUESTS]:

0 commit comments

Comments
 (0)