Commit 2e28bc46 authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

Merge branch 'master' into tm/sumo-integration

Conflicts:
	src/de/tud/kom/p2psim/impl/topology/DefaultTopologyComponent.java
parents 8aeec4ee 686eca40
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.views.fiveg.models;
/**
* Logarithmic model
* log(u) = a * ln(c * (u - d)) + b
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public class LogarithmicModel extends AbstractModel {
private double a = 1;
private double b = 0;
private double c = 1;
private double d = 0;
public void setA(double a) {
this.a = a;
}
public void setB(double b) {
this.b = b;
}
public void setC(double c) {
this.c = c;
}
public void setD(double d) {
this.d = d;
}
@Override
public long getLong(int users) {
return (long) getDouble(users);
}
@Override
public double getDouble(int users) {
double tmp = this.a * Math.log(this.c * (users - this.d)) + this.b;
if(tmp < 0) {
return 0;
} else {
return tmp;
}
}
@Override
public String toString() {
return "Logarithmic Model: log(u) = " + this.a + " * ln(" + this.c + " * (u - " + this.d + ")) + " + this.b;
}
}
# 5G Models
> **IMPORTANT!** The colors of each segment reflect the status *per* characteristic not the global status of this segment. If a segment is overloaded the text "overload" is shown.
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**.
Whenever one of the characteristic for a client is requested every other characteristic is evaluated to check if one of them is overloaded such that no connection is possible. The thresholds for the overload are defined in [`FiveGTopologyDatabase.Entry`](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/blob/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/ModelBasedSegmentDatabase.java#L182)
## Configuration / Setup
The models are enabled by changing the `Database` of the `FiveGTopologyView` to `ModelBasedSegmentDatabase`. For a minimal config the `ModelBasedSegmentDatabase` needs at least a model for each characteristic. Therefore, the models are passed to the database. Each model has its specific defaults described [here](#models). In addition to that every model has parameters for `direction` (*UPLOAD*, *DOWNLOAD* or **BOTH**), `parameterType` (*BANDWIDTH*, *LATENCY* and *DROPRATE*), `segmentID` (to which segmentID this model is applied - **-1** means that it is applied to every segment) and debug (TRUE or **FALSE**). **Bold** values mark the defaults.
## Examples
> **IMPORTANT!** For every characteristic there needs to be one and *only one* default model.
### General Setup
Here the general setup for the model based segments is shown. The models are placed inside the database element.
```xml
<View class="de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView" phy="UMTS" cloudGroups="Cloud">
<Database class="de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase" enableVis="$ENABLE_VIS" gridSize="$CELL_GRID_SIZE">
<!-- Place model definitions here -->
</Database>
</View>
```
### A default constant model for every characteristic
```xml
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ConstantModel" c="300" parameterType="BANDWIDTH" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ConstantModel" c="5" parameterType="LATENCY" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ConstantModel" c="0.1" parameterType="DROPRATE" />
```
For every segment the bandwidth is 300 kBit/s, the latency 5 ms and drop rate is 1% (0.1) in both directions.
### Advanced setup
```xml
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ConstantModel" c="300" parameterType="BANDWIDTH" direction="UPLOAD" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ConstantModel" c="10" parameterType="BANDWIDTH" direction="DOWNLOAD" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.LogarithmicModel" a="3" b="10" c="-5" d="-10" parameterType="LATENCY" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.ExponentialModel" parameterType="DROPRATE" />
<Model class="de.tud.kom.p2psim.impl.topology.views.fiveg.models.CutoffModel" parameterType="BANDWIDTH" segmentID="123" debug="TRUE" />
```
Every segment has 300 kBit/s upload bandwidth and 10 kBit/s download bandwidth with a constant model. The latency of every segment is equal for up- and download and is based on a logarithmic model with $`a=3`$, $`b=10`$, $`c=-5`$ and $`d=-10`$. A default exponential model is applied on the latency. At last there is a cut-off model for the bandwidth for the segment with the ID `123`. It also shows the debug graph.
## Models
* [Constant](#constant)
* [Linear](#linear)
* [Exponential](#exponential)
* [Logarithmic](#logarithmic)
* [Cut-Off](#cut-off)
### Constant
![](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/raw/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/models/img/constant.png)
$`c(u)=C`$
> The constant model applies the the same constant value `c` to the selected characteristic regardless of the number of hosts in the segment.
*Model-specific Parameters*:
`c` the constant value (*default* `0`)
### Linear
![](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/raw/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/models/img/linear.png)
$`lin(u)=a*u+b`$
*Model-specific Parameters*:
`a` the slope (*default* `1`)
`b` y-axis intersection (*default* `0`)
### Exponential
![](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/raw/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/models/img/exponential.png)
$`exp(u)=a*e^{c(u-d)}+b`$
*Model-specific Parameters*:
`a` scaling factor (*default* `1`)
`b` y-axis offset (*default* `0`)
`c` exponent scaling (*default* `1`)
`d` x-axis offset (*default* `0`)
### Logarithmic
![](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/raw/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/models/img/logarithmic.png)
$`log(u)=a*ln(c(u-d))+b`$
*Model-specific Parameters*:
`a` scaling factor (*default* `1`)
`b` y-axis offset (*default* `0`)
`c` logarithm scaling (*default* `1`)
`d` x-axis offset (*default* `0`)
### Cut-Off
![](https://dev.kom.e-technik.tu-darmstadt.de/gitlab/simonstrator/simonstrator-peerfactsim/raw/nr/monitoring-model/src/de/tud/kom/p2psim/impl/topology/views/fiveg/models/img/cutoff.png)
$`cut(u)=a*\theta(c(u-d))+b`$
> The cut-off model is based on the [Heaviside step function](https://en.wikipedia.org/wiki/Heaviside_step_function).
*Model-specific Parameters*:
`a` scaling factor (*default* `1`)
`b` y-axis offset (*default* `0`)
`c` scaling (*default* `1`)
`d` x-axis offset (*default* `0`)
\ No newline at end of file
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.views.fiveg.utils;
/**
* Enumeration for defining the direction (Up,Down or Both) for a model.
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public enum Direction {
BOTH(),
UPLOAD(),
DOWNLOAD();
public static String printTypes() {
Direction[] types = values();
String out = "";
for (int i = 0; i < types.length; i++) {
if (i > 0) {
out += ", ";
}
out += types[i].name();
}
return out;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.views.fiveg.utils;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import de.tud.kom.p2psim.impl.topology.views.FiveGTopologyView;
import de.tud.kom.p2psim.impl.topology.views.fiveg.ModelBasedSegmentDatabase;
import de.tud.kom.p2psim.impl.topology.views.fiveg.models.AbstractModel;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Oracle;
/**
* A simple graph for debugging the models of the
* {@link ModelBasedSegmentDatabase} used by the {@link FiveGTopologyView}.
*
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public class Graph extends JFrame implements EventHandler {
AbstractModel model = null;
public Graph() {
super("FiveGTopology - Cell Model Debug Graph");
Event.scheduleImmediately(this, null, 0);
}
public void setModel(AbstractModel model) {
this.model = model;
}
@Override
public void eventOccurred(Object content, int type) {
if (model.getDebug()) {
XYSeries data = new XYSeries("ModelData");
for (int i = 0; i < Oracle.getAllHosts().size(); i += 1) {
data.add(i, model.getDouble(i));
}
JFreeChart xyChart = ChartFactory.createXYLineChart(
model.getParameterType().toString() + " -- " + model.toString(), "Users", "Value",
new XYSeriesCollection(data), PlotOrientation.VERTICAL,
false, true, false);
// X-Axis Ticks every 5%
((NumberAxis) xyChart.getXYPlot().getDomainAxis())
.setTickUnit(new NumberTickUnit(Oracle.getAllHosts().size() / 20));
ChartPanel chartPanel = new ChartPanel(xyChart);
setContentPane(chartPanel);
pack();
setVisible(true);
}
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.views.fiveg.utils;
/**
* Enumeration for defining the type (Bandwidth, Drop Rate, Latency) for a model.
* @author Marc Schiller
* @version 1.0, 15 Dec 2016
*/
public enum ParameterType {
BANDWIDTH(),
DROPRATE(),
LATENCY();
public static String printTypes() {
ParameterType[] types = values();
String out = "";
for (int i = 0; i < types.length; i++) {
if (i > 0) {
out += ", ";
}
out += types[i].name();
}
return out;
}
}
package de.tud.kom.p2psim.impl.topology.views.visualization.ui;
import de.tudarmstadt.maki.simonstrator.api.NodeDebugMonitor;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Vector;
/**
* The actual frame/view displaying the node data. Simply a frame that holds a table
* displaying the info.
*/
public class DebugNodeView extends JFrame
{
private JPanel panel;
private JTable table;
private DefaultTableModel model;
private long hostId;
public DebugNodeView(long hostId)
{
this.hostId = hostId;
setTitle("Host: " + hostId);
SwingUtilities.invokeLater(this::createGUI);
}
/**
* Initialise the UI
*/
private void createGUI()
{
panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setPreferredSize(new Dimension(300,300));
Map<Class, HashMap<String, Object>> nodeData = NodeDebugMonitor.getNodeData(INodeID.get(hostId));
Vector tableData = convertToTableVector(nodeData);
Vector<String> columns = new Vector<>();
columns.add("Klasse");
columns.add("Beschreibung");
columns.add("Wert");
model = new DefaultTableModel(tableData, columns);
table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
table.setFillsViewportHeight(true);
panel.add(scrollPane, BorderLayout.NORTH);
getContentPane().add(panel);
pack();
setVisible(true);
}
/**
* Updates an entry for a node
* @param subject The class which provided the info
* @param entry the entry/key
* @param value the value
*/
public void update(Class subject, String entry, String value)
{
int rowIndex = findEntry(subject.getSimpleName(), entry);
//If the entry already existed it needs to be updates.
if(rowIndex >= 0)
{
//2 is the position of the value in the vector.
((Vector) model.getDataVector().get(rowIndex)).set(2, value);
model.fireTableDataChanged();
}
//If the entry didn't exist, a new row is inserted.
else
{
String[] data = {subject.getSimpleName(), entry, value};
model.addRow(data);
}
}
/**
* Finds the row in the data vector which holds the specified entry
* @param subject the providing class
* @param entry the entry
* @return the index of the row holding the entry
*/
private int findEntry(String subject, String entry)
{
Vector data = model.getDataVector();
for(int i = 0; i < data.size(); i++)
{
Vector v = (Vector) data.get(i);
if(v.get(0).equals(subject) && v.get(1).equals(entry))
{
return i;
}
}
return -1;
}
/**
* Converts a hashmap with the per node information as provided by the {@link NodeDebugMonitor}
* to a data vector which can be used in a table model.
* @param nodeData the data which should be converted.
* @return a vector holding all the data which can be used for table models.
*/
private Vector<Vector<String>> convertToTableVector(Map<Class, HashMap<String, Object>> nodeData)
{
Vector<Vector<String>> tableData = new Vector<>();
for (Map.Entry<Class, HashMap<String, Object>> classData : nodeData.entrySet())
{
String classname = classData.getKey().getSimpleName();
for(Map.Entry<String, Object> entry : classData.getValue().entrySet())
{
String value;
if (entry.getValue() == null) value = "NULL";
else value = entry.getValue().toString();
Vector<String> entryVector = new Vector<>();
entryVector.add(classname);
entryVector.add(entry.getKey());
entryVector.add(value);
tableData.add(entryVector);
}
}
return tableData;
}
}
......@@ -104,6 +104,12 @@ public class MetricCDFAdapter implements MetricPlotAdapter {
series.add(entry.getValue(), entry.getKey(), entry.getKey(),
entry.getKey());
}
// ValueAxis has errors if maxX is close to 0
if(maxX <= Double.MIN_VALUE){
maxX = 1d;
}
chart.getDomainAxis().setRange(0, maxX);
}
......
package de.tud.kom.p2psim.impl.topology.views.visualization.ui;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView;
import de.tud.kom.p2psim.impl.topology.views.visualization.world.NodeVisInteractionListener;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.NodeDebugMonitor;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
import de.tudarmstadt.maki.simonstrator.api.component.core.NodeDebugMonitorComponent;
import java.util.HashMap;
/**
* Managing class for the presentation of the per node data. All the little "per-node-frames" are handled here.
*/
public class NodeDebugVisualisation implements NodeVisInteractionListener, NodeDebugMonitorComponent.NodeDebugUpdateListener
{
/**
* The info frames that currently exist.
*/
private HashMap<Long, DebugNodeView> frames = new HashMap<>();
public NodeDebugVisualisation()
{
Event.scheduleImmediately((content, type) -> {
NodeDebugMonitor.addUpdateListener(NodeDebugVisualisation.this);
VisualizationTopologyView.VisualizationInjector.addInteractionListener(NodeDebugVisualisation.this);
}, null, 0);
}
@Override
public void onHostClick(long hostID, boolean isActive)
{
if(isActive)
{
frames.put(hostID, new DebugNodeView(hostID));
}
else
{
DebugNodeView view = frames.remove(hostID);
view.dispose();
}
}
@Override
public void onNodeDebugUpdate(Class subject, INodeID nodeId, String entry, Object value)
{
String string;
if(value == null) string = "NULL";
else string = value.toString();
if(frames.containsKey(nodeId.value()))
{
frames.get(nodeId.value()).update(subject, entry, string);
}
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.views.visualization.ui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;
import com.google.common.collect.Maps;
public class PlottingView extends JFrame {
private static final int VIEW_WIDTH = 900;
private static final int VIEW_HEIGHT = 800;
private static final int PLOT_HEIGHT = 120;
private static final Color PLOT_BACKGROUND_COLOR = Color.WHITE;
private String name;
private Map<String, XYChart> nameToPlotMap = Maps.newLinkedHashMap();
private JPanel content;
private JPanel selectorPanel;
private Box plotBox;
private GridBagConstraints layoutConstraints;
public PlottingView(String name) {
this.name = name;
setTitle(name);
setVisible(true);
buildUI();
}
private void buildUI() {
content = new JPanel();
content.setLayout(new BorderLayout());
selectorPanel = new JPanel();
selectorPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
layoutConstraints = new GridBagConstraints();
layoutConstraints.anchor = GridBagConstraints.NORTH;
layoutConstraints.weighty = 1;
plotBox = Box.createVerticalBox();
plotBox.setBackground(PLOT_BACKGROUND_COLOR);
plotBox.setBorder(BorderFactory.createEtchedBorder());
content.add(selectorPanel, BorderLayout.NORTH);
content.add(plotBox, BorderLayout.CENTER);
add(content, BorderLayout.CENTER);
setSize(VIEW_WIDTH, VIEW_HEIGHT);
}
public XYChart createPlot(String name, String seriesName) {
XYChart plot = new XYChart(PLOT_BACKGROUND_COLOR, name, seriesName);
JPanel chartPanel = plot.getChartPanel();
chartPanel = wrapInCollabsable(chartPanel, name);
plotBox.add(chartPanel);
plotBox.validate();
nameToPlotMap.put(name, plot);
return plot;
}
public XYChart createPlot(String name) {
return createPlot(name, name);
}
private JPanel wrapInCollabsable(JPanel chartPanel, String title) {
final JPanel innerPanel = new JPanel();
innerPanel.setLayout(new BorderLayout());
innerPanel.add(new JLabel(" "), BorderLayout.WEST);
innerPanel.add(chartPanel, BorderLayout.CENTER);
innerPanel.setBackground(PLOT_BACKGROUND_COLOR);
final JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setBackground(PLOT_BACKGROUND_COLOR);
Box header = Box.createHorizontalBox();
header.setBackground(PLOT_BACKGROUND_COLOR);
final JLabel collapseButton = new JLabel("-");
Dimension buttonSize = new Dimension(11, 11);
collapseButton.setBackground(PLOT_BACKGROUND_COLOR);
collapseButton.setPreferredSize(buttonSize);
collapseButton.setMaximumSize(buttonSize);
collapseButton.setMinimumSize(buttonSize);
collapseButton.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
collapseButton.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent arg0) {
collapseButton.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
}
@Override
public void mouseReleased(MouseEvent arg0) {
collapseButton.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
if (collapseButton.getText().equals("-")) {
collapseButton.setText("+");
panel.remove(innerPanel);
} else {
collapseButton.setText("-");
panel.add(innerPanel, BorderLayout.CENTER);
}
}
});
JLabel titleLabel = new JLabel(" " + title);
Font font = titleLabel.getFont();
titleLabel.setFont(font.deriveFont(5));
titleLabel.setBackground(PLOT_BACKGROUND_COLOR);
header.add(new JLabel(" "));
header.add(collapseButton);
header.add(titleLabel);
panel.add(header, BorderLayout.NORTH);
panel.add(innerPanel, BorderLayout.CENTER);
return panel;
}
public void removeAllPlots() {
nameToPlotMap.clear();
plotBox.removeAll();
content.doLayout();
content.validate();
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.views.visualization.ui;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Map;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import com.google.common.collect.Maps;
/**
* JFrame which holds all the live plots.
*
* @author Unknown
*
* 21.03.2017 Clemens Krug:
* Changed this class up quite a bit because when one would
* add more and more metrics to the visualisation, they would get unreadable small. Reworked this
* class so the charts will allways fill the view if theres is space, but if you add do many plots
* they will stay add a minimum height of 250 px and a scrollbar will be added instead.
*/
public class PlottingView extends JFrame {
private static final int VIEW_WIDTH = 900;
private static final int VIEW_HEIGHT = 800;
private static final int PLOT_HEIGHT_MIN = 250;
private static final Color PLOT_BACKGROUND_COLOR = Color.WHITE;
private Map<String, XYChart> nameToPlotMap = Maps.newLinkedHashMap();
private JPanel plotBox;
private JScrollPane spane;
public PlottingView(String name) {
setTitle(name);
setVisible(true);
buildUI();
}
private void buildUI() {
plotBox = new PlotBox();
plotBox.setLayout(new BoxLayout(plotBox, BoxLayout.Y_AXIS));
plotBox.setBackground(PLOT_BACKGROUND_COLOR);
plotBox.setBorder(BorderFactory.createEtchedBorder());
spane = new JScrollPane(plotBox);
add(spane);
setSize(VIEW_WIDTH, VIEW_HEIGHT);
setPreferredSize(new Dimension(VIEW_WIDTH, VIEW_HEIGHT));
}
public XYChart createPlot(String name, String seriesName) {
XYChart plot = new XYChart(PLOT_BACKGROUND_COLOR, name, seriesName);
JPanel chartPanel = plot.getChartPanel();
chartPanel = wrapInCollabsable(chartPanel, name);
plotBox.add(chartPanel);
plotBox.repaint();
spane.validate();
nameToPlotMap.put(name, plot);
return plot;
}
public XYChart createPlot(String name) {
return createPlot(name, name);
}
private JPanel wrapInCollabsable(JPanel chartPanel, String title) {
final JPanel innerPanel = new JPanel();
innerPanel.setLayout(new BorderLayout());
innerPanel.add(new JLabel(" "), BorderLayout.WEST);
innerPanel.add(chartPanel, BorderLayout.CENTER);
innerPanel.setBackground(PLOT_BACKGROUND_COLOR);
final JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setBackground(PLOT_BACKGROUND_COLOR);
Box header = Box.createHorizontalBox();
header.setBackground(PLOT_BACKGROUND_COLOR);
final JLabel collapseButton = new JLabel("-");
Dimension buttonSize = new Dimension(11, 11);
collapseButton.setBackground(PLOT_BACKGROUND_COLOR);
collapseButton.setPreferredSize(buttonSize);
collapseButton.setMaximumSize(buttonSize);
collapseButton.setMinimumSize(buttonSize);
collapseButton.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
collapseButton.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent arg0) {
collapseButton.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
}
@Override
public void mouseReleased(MouseEvent arg0) {
collapseButton.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
if (collapseButton.getText().equals("-")) {
collapseButton.setText("+");
panel.remove(innerPanel);
panel.setMinimumSize(header.getPreferredSize());
panel.repaint();
} else {
collapseButton.setText("-");
panel.add(innerPanel, BorderLayout.CENTER);
panel.setMinimumSize(new Dimension(850,PLOT_HEIGHT_MIN));
}
}
});
JLabel titleLabel = new JLabel(" " + title);
Font font = titleLabel.getFont();
titleLabel.setFont(font.deriveFont(5));
titleLabel.setBackground(PLOT_BACKGROUND_COLOR);
header.add(new JLabel(" "));
header.add(collapseButton);
header.add(titleLabel);
panel.add(header, BorderLayout.NORTH);
panel.add(innerPanel, BorderLayout.CENTER);
panel.setMinimumSize(new Dimension(850,PLOT_HEIGHT_MIN));
return panel;
}
public void removeAllPlots() {
nameToPlotMap.clear();
plotBox.removeAll();
plotBox.validate();
}
/**
* Custom JPanel to implement the desired scrolling policy. Basically
* there won't be a scrollbar if all of the components have a greater height than
* {@link #PLOT_HEIGHT_MIN}. However, if you add so many components that they can't
* fit in while maintaining that minimum height, a scrollbar will be added.
*
* @author Clemens Krug
*/
private class PlotBox extends JPanel implements Scrollable
{
private boolean enableScroll = false;
private Dimension preferredSize = new Dimension(VIEW_WIDTH, 800);
@Override
public Component add(Component comp)
{
Component retComp = super.add(comp);
preferredSize.height = getComponentCount() * PLOT_HEIGHT_MIN;
checkScrollNeeded();
return retComp;
}
/**
* Check if scrolling should be enabled and to so if it should.
*/
private void checkScrollNeeded()
{
enableScroll = getComponentCount() * PLOT_HEIGHT_MIN > getParent().getHeight();
}
@Override
public Dimension getPreferredSize() {
return preferredSize;
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 50;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return PLOT_HEIGHT_MIN;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return !enableScroll;
}
}
}
\ No newline at end of file
......@@ -263,7 +263,7 @@ public class NodeInfoComponentVis extends JComponent
// Draw active (green) over underlay vis.
g2.setColor(nodeInfo.isActive() ? activeGreen : Color.LIGHT_GRAY);
int radius = 3;
g2.drawOval(center.x - radius, center.y - radius, radius * 2,
g2.drawOval(VisualizationInjector.scaleValue(center.x) - radius, VisualizationInjector.scaleValue(center.y) - radius, radius * 2,
radius * 2);
if (!nodeInfo.isActive()) {
......@@ -285,7 +285,7 @@ public class NodeInfoComponentVis extends JComponent
continue;
}
g2.setColor(colors[dim][value]);
g2.drawArc(center.x-arcSize, center.y-arcSize, 2*arcSize, 2*arcSize, dim*segmentDegrees, segmentDegrees);
g2.drawArc(VisualizationInjector.scaleValue(center.x)-arcSize, VisualizationInjector.scaleValue(center.y)-arcSize, 2*arcSize, 2*arcSize, dim*segmentDegrees, segmentDegrees);
}
g2.setStroke(new BasicStroke(1));
......
......@@ -21,6 +21,7 @@
package de.tud.kom.p2psim.impl.transport.modular;
import de.tud.kom.p2psim.api.transport.TransMessage;
import de.tud.kom.p2psim.api.transport.TransProtocol;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
import de.tudarmstadt.maki.simonstrator.api.component.transport.TransInfo;
......@@ -63,5 +64,11 @@ public interface ITransProtocol {
* @return
*/
public int getHeaderSize();
/**
* Protocol type of this instance.
* @return
*/
public TransProtocol getProtocol();
}
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