Commit 3174a624 authored by Nils Richerzhagen's avatar Nils Richerzhagen
Browse files

Visualization for ModelBased FiveG

parent 439b8773
......@@ -802,10 +802,29 @@ public class VisualizationTopologyView extends JFrame
SCALE = scale;
}
/**
* Returns the SCALED value of the given value. This is to be used by
* visualizations!
*
* @param value
* @return
*/
public static int scaleValue(double value) {
return (int) (value * getScale());
}
/**
* Returns the original value (in meters) of the given scaled value.
* This should be used if you need map values in meters from a scaled
* value. E.g. to find segments in a to meters mapped vector.
*
* @param value
* @return
*/
public static double originalValue(int value) {
return value * (1 / getScale());
}
/**
* Recommended way to add a custom visualization layer.
*
......
......@@ -34,6 +34,21 @@ import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Time;
/**
* A grid based FiveG model-based database.
*
* This module allows to add transmission models to each segment of the map to
* accommodate different behaviors of wireless network transmission
* technologies. It enables the developer to define different models for
* **Latency**, **Bandwidth** and **Drop Rate** (called *characteristics*), for
* **Upload** and **Download** and for every **Segment**.
*
* For more information see README.md in
* de.tud.kom.p2psim.impl.topology.views.fiveg.models.README.md
*
* @author Nils Richerzhagen
* @version 1.0, Jul 7, 2017
*/
public class ModelBasedSegmentDatabase
extends AbstractGridBasedTopologyDatabase {
......
......@@ -206,8 +206,8 @@ public class FiveGVisualization extends JComponent
// 17 == Shift
if (enableCellDestruction && modifier == 17) {
int segID = database.getSegmentID(
x * (1 / VisualizationInjector.getScale()),
y * (1 / VisualizationInjector.getScale()));
VisualizationInjector.originalValue(x),
VisualizationInjector.originalValue(y));
Entry entry = database.getEntryFor(segID, false);
entry.setAvailability(!entry.isAvailable());
needsRedraw = true;
......
......@@ -20,16 +20,6 @@
package de.tud.kom.p2psim.impl.topology.views.visualization.world;
import de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector.MouseClickListener;
import de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase;
import de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase.ModelBasedEntry;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.Direction;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.ParameterType;
import de.tud.kom.p2psim.impl.topology.views.fiveg.FiveGTopologyDatabase.Entry;
import de.tud.kom.p2psim.impl.topology.views.visualization.ui.VisualizationComponent;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
......@@ -42,17 +32,29 @@ import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.HashSet;
import javax.swing.*;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import de.tud.kom.p2psim.api.topology.Topology;
import de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector.MouseClickListener;
import de.tud.kom.p2psim.impl.topology.views.fiveg.FiveGTopologyDatabase.Entry;
import de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase;
import de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase.ModelBasedEntry;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.Direction;
import de.tud.kom.p2psim.impl.topology.views.fiveg.utils.ParameterType;
import de.tud.kom.p2psim.impl.topology.views.visualization.ui.VisualizationComponent;
import de.tudarmstadt.maki.simonstrator.api.Binder;
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
/**
* Visualization for the {@link FiveGTopologyView}
*
* Added 06.10.2016 Nils Richerzhagen, Clemens Krug Functionality to 'destroy'
* cells using SHIFT + Left-click. Enable/Disable using the
* enableCellDestruction
* Visualization for the {@link FiveGTopologyView} using the
* {@link ModelBasedSegmentDatabase}.
*
* @author Bjoern Richerzhagen
* @version 1.0, Nov 5, 2015
* @author Marc Schiller, Nils Richerzhagen
* @version 1.0, Jul 7, 2017
*/
public class ModelFiveGVisualization extends JComponent
implements VisualizationComponent, ActionListener, MouseClickListener {
......@@ -72,7 +74,7 @@ public class ModelFiveGVisualization extends JComponent
private ParameterType selectedType = null;
private HashSet<JCheckBoxMenuItem> menuItems = new HashSet<>(6);
private Boolean showText = true;
private ModelFiveGVisualization() {
......@@ -187,98 +189,125 @@ public class ModelFiveGVisualization extends JComponent
boolean isUpload = selectedDirection.equals(Direction.UPLOAD) ? true
: false;
// Loop through world
for (int x = 0; x < VisualizationInjector.getWorldX(); x += stepSize) {
for (int y = 0; y < VisualizationInjector
.getWorldY(); y += stepSize) {
// Fetch entry
ModelBasedEntry entry = (ModelBasedEntry) database
.getEntryFor(database.getSegmentID(x, y), false);
// Skip cell if no entry is found
if (entry == null) {
continue;
}
int status = entry.getStatus(selectedType, selectedDirection);
Color color = null;
if (entry.isAvailable() && status == 0) {
// Cell is ok => green
color = new Color(0, 128, 0, 40);
} else if (entry.isAvailable() && status == 1) {
// Cell is shortly before overload
color = new Color(255, 255, 0, 40);
} else if (!entry.isAvailable() || status == 2) {
// Cell is overloaded or unavailable
color = new Color(255, 0, 0, 100);
}
try {
// Loop through world
for (int x = 0; x < Binder.getComponent(Topology.class)
.getWorldDimensions().getX(); x += stepSize) {
for (int y = 0; y < Binder.getComponent(Topology.class)
.getWorldDimensions().getY(); y += stepSize) {
// Fetch entry
ModelBasedEntry entry = (ModelBasedEntry) database
.getEntryFor(database.getSegmentID(x, y), false);
// Skip cell if no entry is found
if (entry == null) {
continue;
}
// Fill with color for given metric
g2.setColor(color);
g2.fillRect(x, y, stepSize, stepSize);
int status = entry.getStatus(selectedType,
selectedDirection);
Color color = null;
if (entry.isAvailable() && status == 0) {
// Cell is ok => green
color = new Color(0, 128, 0, 40);
} else if (entry.isAvailable() && status == 1) {
// Cell is shortly before overload
color = new Color(255, 255, 0, 40);
} else if (!entry.isAvailable() || status == 2) {
// Cell is overloaded or unavailable
color = new Color(255, 0, 0, 100);
}
// Draw border
// TODO: Draw red border if segment is overload if
// (entry.isAvailable() && !entry.isOverloaded()) {
if (entry.isAvailable()) {
g2.setColor(new Color(255, 0, 0, 10));
g2.setStroke(new BasicStroke(1));
// Fill with color for given metric
g2.setColor(color);
g2.fillRect(VisualizationInjector.scaleValue(x),
VisualizationInjector.scaleValue(y),
VisualizationInjector.scaleValue(stepSize),
VisualizationInjector.scaleValue(stepSize));
} else {
g2.setColor(new Color(255, 0, 0, 100));
g2.setStroke(new BasicStroke(5));
}
g2.drawRect(x, y, stepSize, stepSize);
// Write current values to cell
// Set text color for yellow to grey else to white
if(status== 1) {
g2.setColor(new Color(160, 160, 160, 255));
} else {
g2.setColor(new Color(255, 255, 255, 255));
}
// Draw border
// TODO: Draw red border if segment is overload if
// (entry.isAvailable() && !entry.isOverloaded()) {
if (entry.isAvailable()) {
g2.setColor(new Color(255, 0, 0, 10));
g2.setStroke(new BasicStroke(1));
if (showText) {
} else {
g2.setColor(new Color(255, 0, 0, 100));
g2.setStroke(new BasicStroke(5));
}
g2.drawRect(VisualizationInjector.scaleValue(x),
VisualizationInjector.scaleValue(y),
VisualizationInjector.scaleValue(stepSize),
VisualizationInjector.scaleValue(stepSize));
// Write current values to cell
// Set text color for yellow to grey else to white
if (status == 1) {
g2.setColor(new Color(160, 160, 160, 255));
} else {
g2.setColor(new Color(255, 255, 255, 255));
}
// Latency
if (entry.isAvailable() && !entry.isOverloaded()) {
if (showText) {
// Latency
if (entry.isAvailable() && !entry.isOverloaded()) {
g2.drawString(
"L: " + entry.getLatency(isUpload) + " ms",
VisualizationInjector.scaleValue(x + 10),
VisualizationInjector.scaleValue(y + 15));
} else {
g2.drawString("L: ∞ ms",
VisualizationInjector.scaleValue(x + 10),
VisualizationInjector.scaleValue(y + 15));
}
// Droprate
g2.drawString(
"L: " + entry.getLatency(isUpload) + " ms",
x + 10, y + 15);
} else {
g2.drawString("L: ∞ ms", x + 10, y + 15);
"D: " + (int) (entry
.getDropProbability(isUpload) * 100)
+ " %",
VisualizationInjector.scaleValue(x + 10),
VisualizationInjector.scaleValue(y + 35));
// Bandwidth
g2.drawString("B: " + entry.getBandwidth(isUpload)
+ " kBit/s",
VisualizationInjector.scaleValue(x + 10),
VisualizationInjector.scaleValue(y + 55));
// SegmentID
g2.drawString("S:" + entry.getSegmentID(),
VisualizationInjector.scaleValue(x + 10),
VisualizationInjector.scaleValue(y + 75));
// Current Hosts in Segment
g2.drawString("H:" + entry.getHostsInSegment(),
VisualizationInjector.scaleValue(x + 10),
VisualizationInjector.scaleValue(y + 95));
}
// Droprate
g2.drawString("D: "
+ (int) (entry.getDropProbability(isUpload) * 100)
+ " %", x + 10, y + 25);
// Bandwidth
g2.drawString(
"B: " + entry.getBandwidth(isUpload) + " kBit/s",
x + 10, y + 35);
// SegmentID
g2.drawString("S:" + entry.getSegmentID(), x + 10, y + 45);
// Current Hosts in Segment
g2.drawString("H:" + entry.getHostsInSegment(), x + 10,
y + 55);
}
// Segment is overloaded
if (entry.isOverloaded()) {
g2.drawString("OVERLOAD", x + 20, y + 80);
}
// Host has been killed manually
if (!entry.isAvailable()) {
g2.drawString("!DEAD!", x + 30, y + 70);
// Segment is overloaded
if (entry.isOverloaded()) {
g2.drawString("OVERLOAD",
VisualizationInjector.scaleValue(x + 20),
VisualizationInjector.scaleValue(y + 80));
}
// Host has been killed manually
if (!entry.isAvailable()) {
g2.drawString("!DEAD!",
VisualizationInjector.scaleValue(x + 30),
VisualizationInjector.scaleValue(y + 70));
}
}
}
} catch (ComponentNotAvailableException e) {
throw new AssertionError(
"The Topology should be Binded in the TopologyFactory.");
}
}
......@@ -325,10 +354,12 @@ public class ModelFiveGVisualization extends JComponent
@Override
public void mouseClicked(int x, int y, int modifier) {
// 17 == Shift
if (modifier == 17) {
int segID = database.getSegmentID(x, y);
int segID = database.getSegmentID(
VisualizationInjector.originalValue(x),
VisualizationInjector.originalValue(y));
Entry entry = database.getEntryFor(segID, false);
entry.setAvailability(!entry.isAvailable());
needsRedraw = true;
......@@ -336,7 +367,7 @@ public class ModelFiveGVisualization extends JComponent
// 18 == STRG || CMD
if (modifier == 18) {
showText = !showText;
needsRedraw = true;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment