Browse Source

added options to show/hide the grid beneath the statistics graph, and to change the background color

I. Dix 7 years ago
parent
commit
65781695b4
2 changed files with 1063 additions and 1054 deletions
  1. 721 725
      src/ui/view/StatisticGraph.java
  2. 342 329
      src/ui/view/StatisticGraphPanel.java

+ 721 - 725
src/ui/view/StatisticGraph.java

@@ -1,734 +1,730 @@
 package ui.view;
 
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.geom.GeneralPath;
-import java.util.ArrayList;
-
-import javax.swing.JPanel;
-
-import classes.AbstractCpsObject;
-import classes.CpsUpperNode;
-import classes.HolonElement;
-import classes.HolonObject;
-import classes.HolonSwitch;
-import classes.SubNet;
-import classes.TrackedDataSet;
+import classes.*;
 import ui.controller.Control;
 import ui.model.Model;
-import java.awt.Dimension;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.geom.GeneralPath;
+import java.util.ArrayList;
 
 public class StatisticGraph extends JPanel {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 1L;
-
-	// Maximum y Value
-	float maximum = 0;
-
-	// is the Simulation running?
-	private boolean isSimRunning;
-
-	// model and controller
-	private Model model;
-	private Control controller;
-
-	// Graphics2D
-	private Graphics2D g2;
-	GeneralPath path = new GeneralPath();
-
-	// Data
-	private ArrayList<TrackedDataSet> dataSets = new ArrayList<>();
-
-	/**
-	 * Constructor.
-	 * 
-	 * @param model
-	 *            the Model
-	 * @param control
-	 *            the Controller
-	 */
-	public StatisticGraph(final Model model, Control control) {
-		this.controller = control;
-		this.model = model;
-		this.setBackground(Color.WHITE);
-	}
-
-	/**
-	 * Paints all Components on the Canvas.
-	 * 
-	 * @param g
-	 *            Graphics
-	 * 
-	 */
-	public void paintComponent(Graphics g) {
-		super.paintComponent(g);
-
-		// Graphics2D init
-		g2 = (Graphics2D) g;
-		RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-		g2.setRenderingHints(rh);
-
-		// Paint the Grid
-		g2.setStroke(new BasicStroke(0));
-		g2.setColor(Color.BLACK);
-		for (int i = 0; i <= this.getWidth(); i += 10) {
-			g2.drawLine(i, 0, i, this.getHeight());
-		}
-		for (int i = 0; i <= this.getHeight(); i += 5) {
-			g2.drawLine(0, i, this.getWidth(), i);
-		}
-
-		g2.setStroke(new BasicStroke(3));
-
-		// Calculate the Maximum
-		// calcMaximum();
-
-		// Calculate values for each set and add them
-		// addValues();
-
-		// Create Paths and draw them
-		for (TrackedDataSet set : dataSets) {
-			path.reset();
-			switch (set.getProperty()) {
-			case TrackedDataSet.CONSUMPTION:
-			case TrackedDataSet.PRODUCTION:
-			case TrackedDataSet.ACTIVATED_ELEMENTS:
-			case TrackedDataSet.TOTAL_PRODUCTION:
-			case TrackedDataSet.TOTAL_CONSUMPTION:
-			case TrackedDataSet.AMOUNT_HOLONS:
-			case TrackedDataSet.GROUP_CONSUMPTION:
-			case TrackedDataSet.GROUP_PRODUCTION:
-			case TrackedDataSet.AMOUNT_CLOSED_SWITCHES:
-			case TrackedDataSet.AVG_AMOUNT_OBJECTS_IN_HOLONS:
-			case TrackedDataSet.AVG_AMOUNT_ELEMENTS_IN_HOLONS:
-			case TrackedDataSet.AVG_AMOUNT_PRODUCERS_IN_HOLONS:
-			case TrackedDataSet.AVG_CONSUMED_ENERGY_IN_HOLONS:
-			case TrackedDataSet.AVG_WASTED_ENERGY_IN_HOLONS:
-			case TrackedDataSet.AMOUNT_BROKEN_EDGES:
-			case TrackedDataSet.AVG_AMOUNT_CLOSED_SWITCHES_IN_HOLONS:
-			case TrackedDataSet.AVG_AMOUNT_ACTIVE_ELEMENTS_IN_HOLONS:
-			case TrackedDataSet.AVG_AMOUNT_INACTIVE_ELEMENTS_IN_HOLONS:
-			case TrackedDataSet.AVG_PRODUCED_ENERGY_IN_HOLONS:
-				createPathFloats(set);
-				break;
-			case TrackedDataSet.ON_OFF:
-				createPathBooleans(set);
-				break;
-			case TrackedDataSet.PERCENT_SUPPLIED:
-			case TrackedDataSet.PERCENT_NOT_SUPPLIED:
-			case TrackedDataSet.PERCENT_PARTIAL_SUPPLIED:
-			case TrackedDataSet.RATIO_PRODUCERS_CONSUMERS:
-				createPathPercent(set);
-				break;
-			default:
-				break;
-			}
-			g2.setColor(set.getColor());
-			g2.draw(path);
-		}
-	}
-
-	/**
-	 * Add an Object to the Graph if the maximum has not reached yet.
-	 * 
-	 * @param obj
-	 *            the Object to add
-	 */
-	public void addObject(TrackedDataSet set) {
-		dataSets.add(set);
-	}
-
-	/**
-	 * Removes an Object from the Graph.
-	 * 
-	 * @param id
-	 *            the id of the Object to remove
-	 */
-	public void removeObject(int id) {
-		dataSets.remove(id);
-	}
-
-	/**
-	 * converts the number to fit the canvas.
-	 * 
-	 * @param d
-	 *            the number to convert
-	 * @return the converted number
-	 */
-	public double convertToCanvasY(float d) {
-		return Math.abs((this.getHeight() - (d * (this.getHeight() / maximum))));
-	}
-
-	/**
-	 * Does take into account which timestep is watched, calculates the max
-	 * values.
-	 * 
-	 * @return the currentEnergy
-	 */
-	public float getEnergyAtCurrentTimeStep(HolonObject obj) {
-		float temp = 0;
-		for (HolonElement e : obj.getElements()) {
-			if (e.getActive()) {
-				temp = temp + e.getEnergyAt()[model.getCurIteration()];
-			}
-		}
-		return temp;
-	}
-
-	/**
-	 * Calculate the Max Value of the Graph
-	 */
-	public void calcMaximum() {
-		maximum = 0;
-		for (TrackedDataSet set : dataSets) {
-			float val = 0;
-			switch (set.getProperty()) {
-			case TrackedDataSet.CONSUMPTION:
-				for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
-					if (h.getEnergy() < 0) {
-						val += (h.getEnergy() + h.getFlexibility()) * h.getAmount();
-					}
-				}
-				val *= -1;
-				break;
-			case TrackedDataSet.PRODUCTION:
-				for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
-					if (h.getEnergy() > 0) {
-						val += (h.getEnergy() + h.getFlexibility()) * h.getAmount();
-					}
-				}
-				break;
-			case TrackedDataSet.ACTIVATED_ELEMENTS:
-				for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
-					val += h.getAmount();
-				}
-				break;
-			case TrackedDataSet.ON_OFF:
-				val = 1;
-				break;
-			case TrackedDataSet.TOTAL_PRODUCTION:
-				val = getMaxTotalProduction(model.getObjectsOnCanvas());
-				break;
-			case TrackedDataSet.TOTAL_CONSUMPTION:
-				val = getMaxTotalConsumption(model.getObjectsOnCanvas());
-				val *= -1;
-				break;
-			case TrackedDataSet.PERCENT_SUPPLIED:
-			case TrackedDataSet.PERCENT_NOT_SUPPLIED:
-			case TrackedDataSet.PERCENT_PARTIAL_SUPPLIED:
-				val = 1;
-				break;
-			case TrackedDataSet.GROUP_PRODUCTION:
-				val = getMaxTotalProduction(((CpsUpperNode) set.getCpsObject()).getNodes());
-				break;
-			case TrackedDataSet.GROUP_CONSUMPTION:
-				val = getMaxTotalConsumption(((CpsUpperNode) set.getCpsObject()).getNodes());
-				val *= -1;
-				break;
-			case TrackedDataSet.AMOUNT_HOLONS:
-				val = controller.getSimManager().getSubNets().size();
-				for (int i = 0; i < model.getCurIteration(); i++) {
-					if (val < set.getValues()[i]) {
-						val = set.getValues()[i];
-					}
-				}
-				break;
-			case TrackedDataSet.AMOUNT_CLOSED_SWITCHES:
-				val = model.getSwitches().size();
-				break;
-			case TrackedDataSet.AVG_AMOUNT_OBJECTS_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					if (val < sub.getObjects().size()) {
-						val = sub.getObjects().size();
-					}
-				}
-				break;
-			case TrackedDataSet.AVG_AMOUNT_ELEMENTS_IN_HOLONS:
-			case TrackedDataSet.AVG_AMOUNT_ACTIVE_ELEMENTS_IN_HOLONS:
-			case TrackedDataSet.AVG_AMOUNT_INACTIVE_ELEMENTS_IN_HOLONS:
-				float eCount = 0;
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					for (HolonObject obj : sub.getObjects()) {
-						eCount += obj.getElements().size();
-					}
-					if (val < eCount) {
-						val = eCount;
-					}
-					eCount = 0;
-				}
-				break;
-			case TrackedDataSet.AVG_AMOUNT_PRODUCERS_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					if (val < sub.getObjects().size()) {
-						val = sub.getObjects().size();
-					}
-				}
-				break;
-			case TrackedDataSet.AVG_CONSUMED_ENERGY_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					float tempVal = -getMaxTotalConsumption(new ArrayList<AbstractCpsObject>(sub.getObjects()));
-					if (val < tempVal) {
-						val = tempVal;
-					}
-				}
-				break;
-			case TrackedDataSet.AVG_WASTED_ENERGY_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					float tempVal = getMaxTotalProduction(new ArrayList<AbstractCpsObject>(sub.getObjects()));
-					if (val < tempVal) {
-						val = tempVal;
-					}
-				}
-				break;
-			case TrackedDataSet.AMOUNT_BROKEN_EDGES:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					val += sub.getSwitches().size();
-				}
-				break;
-			case TrackedDataSet.RATIO_PRODUCERS_CONSUMERS:
-				val = 1;
-				break;
-			case TrackedDataSet.AVG_AMOUNT_CLOSED_SWITCHES_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					float tempVal = sub.getSwitches().size();
-					if (val < tempVal) {
-						val = tempVal;
-					}
-				}
-				break;
-			case TrackedDataSet.AVG_PRODUCED_ENERGY_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					float tempVal = getMaxTotalProduction(new ArrayList<AbstractCpsObject>(sub.getObjects()));
-					if (val < tempVal) {
-						val = tempVal;
-					}
-				}
-				break;
-			default:
-				maximum = 0;
-				break;
-			}
-			if (val > maximum) {
-				maximum = val;
-			}
-		}
-		((StatisticGraphPanel) this.getParent().getParent()).setMaximumLabel(maximum);
-	}
-
-	/**
-	 * Add the Current Values to each set
-	 */
-	public void addValues() {
-		for (TrackedDataSet set : dataSets) {
-			float val = 0;
-			switch (set.getProperty()) {
-			case TrackedDataSet.CONSUMPTION:
-				for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
-					if (h.getTotalEnergyAtTimeStep(model.getCurIteration()) < 0 && h.getActive()) {
-						val += Math.abs(h.getTotalEnergyAtTimeStep(model.getCurIteration()));
-					}
-					set.setValAt(val, model.getCurIteration());
-				}
-				break;
-			case TrackedDataSet.PRODUCTION:
-				for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
-					if (h.getTotalEnergyAtTimeStep(model.getCurIteration()) > 0 && h.getActive()) {
-						val += Math.abs(h.getTotalEnergyAtTimeStep(model.getCurIteration()));
-					}
-					set.setValAt(val, model.getCurIteration());
-				}
-
-				break;
-			case TrackedDataSet.ACTIVATED_ELEMENTS:
-				for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
-					if (h.getActive()) {
-						val += h.getAmount();
-					}
-					set.setValAt(val, model.getCurIteration());
-				}
-				break;
-			case TrackedDataSet.ON_OFF:
-				if (((HolonSwitch) set.getCpsObject()).getManualMode()) {
-					if (((HolonSwitch) set.getCpsObject()).getActiveManual()) {
-						set.setValAt(1, model.getCurIteration());
-					} else {
-						set.setValAt(0, model.getCurIteration());
-					}
-				} else {
-					if (((HolonSwitch) set.getCpsObject()).getActiveAt()[model.getCurIteration()]) {
-						set.setValAt(1, model.getCurIteration());
-					} else {
-						set.setValAt(0, model.getCurIteration());
-					}
-				}
-				break;
-			case TrackedDataSet.TOTAL_PRODUCTION:
-				set.setValAt(getTotalProductionAt(model.getObjectsOnCanvas(), model.getCurIteration()),
-						model.getCurIteration());
-				break;
-			case TrackedDataSet.TOTAL_CONSUMPTION:
-				set.setValAt(-getTotalConsumptionAt(model.getObjectsOnCanvas(), model.getCurIteration()),
-						model.getCurIteration());
-				break;
-			case TrackedDataSet.PERCENT_SUPPLIED:
-				set.setValAt(getPercentState(model.getObjectsOnCanvas(), HolonObject.SUPPLIED),
-						model.getCurIteration());
-				break;
-			case TrackedDataSet.PERCENT_NOT_SUPPLIED:
-				set.setValAt(getPercentState(model.getObjectsOnCanvas(), HolonObject.NOT_SUPPLIED),
-						model.getCurIteration());
-				break;
-			case TrackedDataSet.PERCENT_PARTIAL_SUPPLIED:
-				set.setValAt(getPercentState(model.getObjectsOnCanvas(), HolonObject.PARTIALLY_SUPPLIED),
-						model.getCurIteration());
-				break;
-			case TrackedDataSet.GROUP_PRODUCTION:
-				set.setValAt(
-						getTotalProductionAt(((CpsUpperNode) set.getCpsObject()).getNodes(), model.getCurIteration()),
-						model.getCurIteration());
-				break;
-			case TrackedDataSet.GROUP_CONSUMPTION:
-				set.setValAt(
-						-getTotalConsumptionAt(((CpsUpperNode) set.getCpsObject()).getNodes(), model.getCurIteration()),
-						model.getCurIteration());
-				break;
-			case TrackedDataSet.AMOUNT_HOLONS:
-				set.setValAt(controller.getSimManager().getSubNets().size(), model.getCurIteration());
-				break;
-			case TrackedDataSet.AMOUNT_CLOSED_SWITCHES:
-				for (HolonSwitch s : model.getSwitches()) {
-					if (s.getState(model.getCurIteration())) {
-						val++;
-					}
-				}
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.AVG_AMOUNT_OBJECTS_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					val += sub.getObjects().size();
-				}
-				val /= controller.getSimManager().getSubNets().size();
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.AVG_AMOUNT_ELEMENTS_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					for (HolonObject obj : sub.getObjects()) {
-						val += obj.getElements().size();
-					}
-				}
-				val /= controller.getSimManager().getSubNets().size();
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.AVG_AMOUNT_PRODUCERS_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					for (HolonObject obj : sub.getObjects()) {
-						if (obj.getCurrentEnergyAtTimeStep(model.getCurIteration()) > 0) {
-							val++;
-						}
-					}
-				}
-				val /= controller.getSimManager().getSubNets().size();
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.AVG_CONSUMED_ENERGY_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					val += -getTotalConsumptionAt(new ArrayList<AbstractCpsObject>(sub.getObjects()),
-							model.getCurIteration());
-				}
-				val /= controller.getSimManager().getSubNets().size();
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.AVG_WASTED_ENERGY_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					val += (getTotalProductionAt(new ArrayList<AbstractCpsObject>(sub.getObjects()),
-							model.getCurIteration())
-							+ getTotalConsumptionAt(new ArrayList<AbstractCpsObject>(sub.getObjects()),
-									model.getCurIteration()));
-				}
-				val /= controller.getSimManager().getSubNets().size();
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.AMOUNT_BROKEN_EDGES:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					for (HolonSwitch s : sub.getSwitches()) {
-						if (s.getState()) {
-							val++;
-						}
-					}
-				}
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.RATIO_PRODUCERS_CONSUMERS:
-				float prod = 0;
-				float cons = 0;
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					for (HolonObject obj : sub.getObjects()) {
-						if (obj.getCurrentEnergyAtTimeStep(model.getCurIteration()) > 0) {
-							prod++;
-						} else if (obj.getCurrentEnergyAtTimeStep(model.getCurIteration()) < 0) {
-							cons++;
-						}
-					}
-				}
-				val = prod / (prod + cons);
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.AVG_AMOUNT_CLOSED_SWITCHES_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					val += sub.getSwitches().size();
-				}
-				val /= controller.getSimManager().getSubNets().size();
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.AVG_AMOUNT_ACTIVE_ELEMENTS_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					for (HolonObject obj : sub.getObjects()) {
-						for (HolonElement ele : obj.getElements()) {
-							if (ele.getActive()) {
-								val++;
-							}
-						}
-					}
-				}
-				val /= controller.getSimManager().getSubNets().size();
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.AVG_AMOUNT_INACTIVE_ELEMENTS_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					for (HolonObject obj : sub.getObjects()) {
-						for (HolonElement ele : obj.getElements()) {
-							if (!ele.getActive()) {
-								val++;
-							}
-						}
-					}
-				}
-				val /= controller.getSimManager().getSubNets().size();
-				set.setValAt(val, model.getCurIteration());
-				break;
-			case TrackedDataSet.AVG_PRODUCED_ENERGY_IN_HOLONS:
-				for (SubNet sub : controller.getSimManager().getSubNets()) {
-					val += getTotalProductionAt(new ArrayList<AbstractCpsObject>(sub.getObjects()),
-							model.getCurIteration());
-				}
-				val /= controller.getSimManager().getSubNets().size();
-				set.setValAt(val, model.getCurIteration());
-				break;
-			default:
-				break;
-			}
-		}
-	}
-
-	/**
-	 * create Path with floats
-	 * 
-	 * @param set
-	 */
-	private void createPathFloats(TrackedDataSet set) {
-		int range = model.getCurIteration(); //to which iteration
-		if (!model.getIsSimRunning()) {
-			range = model.getIterations()-1;
-		}
-		if (set.getValues()[0] != -1) {
-			path.moveTo(0, convertToCanvasY(set.getValues()[0]));
-		} else {
-			path.moveTo(1 * this.getWidth() / model.getIterations(), convertToCanvasY(set.getValues()[1]));
-		}
-		for (int i = 0; i < range; i++) {
-			if (set.getValues()[i + 1] != -1) {
-				path.lineTo((i + 1) * this.getWidth() / model.getIterations(),
-						convertToCanvasY(set.getValues()[i + 1]));
-			} else {
-				if (i + 2 < range) {
-					path.moveTo((i + 2) * this.getWidth() / model.getIterations(),
-							convertToCanvasY(set.getValues()[i + 2]));
-				}
-			}
-		}
-	}
-
-	/**
-	 * create Path with booleans(0 and 1)
-	 * 
-	 * @param set
-	 */
-	private void createPathBooleans(TrackedDataSet set) {
-		if (set.getValues()[0] != -1) {
-			path.moveTo(0, convertToCanvasY((float) (set.getValues()[0] * (maximum / 3 * 2)) + (maximum / 6)));
-		} else {
-			path.moveTo(1 * this.getWidth() / model.getIterations(),
-					convertToCanvasY((float) (set.getValues()[1] * (maximum / 3 * 2)) + (maximum / 6)));
-		}
-		for (int i = 0; i < model.getCurIteration(); i++) {
-			controller.addTextToConsole(set.getValues()[i] + "");
-			if (set.getValues()[i + 1] != -1) {
-				path.lineTo((i + 1) * this.getWidth() / model.getIterations(),
-						convertToCanvasY((float) (set.getValues()[i + 1] * (maximum / 3 * 2)) + (maximum / 6)));
-			} else {
-				if (i + 2 < model.getCurIteration()) {
-					path.moveTo((i + 2) * this.getWidth() / model.getIterations(),
-							convertToCanvasY((float) (set.getValues()[i + 2] * (maximum / 3 * 2)) + (maximum / 6)));
-				}
-			}
-		}
-	}
-
-	/**
-	 * create Path for percent values
-	 * 
-	 * @param set
-	 */
-	private void createPathPercent(TrackedDataSet set) {
-		if (set.getValues()[0] != -1) {
-			path.moveTo(0, convertToCanvasY(set.getValues()[0] * maximum));
-		} else {
-			path.moveTo(1 * this.getWidth() / model.getIterations(), convertToCanvasY(set.getValues()[1] * maximum));
-		}
-		for (int i = 0; i < model.getCurIteration(); i++) {
-			if (set.getValues()[i + 1] != -1) {
-				path.lineTo((i + 1) * this.getWidth() / model.getIterations(),
-						convertToCanvasY(set.getValues()[i + 1] * maximum));
-			} else {
-				if (i + 2 < model.getCurIteration()) {
-					path.moveTo((i + 2) * this.getWidth() / model.getIterations(),
-							convertToCanvasY(set.getValues()[i + 2] * maximum));
-				}
-			}
-
-		}
-	}
-
-	/**
-	 * get the max total production of the given Objects
-	 *
-	 * @param objects
-	 *            List of Objects
-	 */
-	private float getMaxTotalProduction(ArrayList<AbstractCpsObject> objects) {
-		float val = 0;
-
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getEnergy() > 0) {
-						val += (ele.getEnergy() + ele.getFlexibility()) * ele.getAmount();
-					}
-				}
-			} else if (obj instanceof CpsUpperNode) {
-				val += getMaxTotalProduction(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return val;
-	}
-
-	/**
-	 * get the max total consumption of the given Objects
-	 *
-	 * @param objects
-	 *            List of Objects
-	 */
-	private float getMaxTotalConsumption(ArrayList<AbstractCpsObject> objects) {
-		float val = 0;
-
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getEnergy() < 0) {
-						val += (ele.getEnergy() + ele.getFlexibility()) * ele.getAmount();
-					}
-				}
-			} else if (obj instanceof CpsUpperNode) {
-				val += getMaxTotalConsumption(((CpsUpperNode) obj).getNodes());
-			}
-		}
-		return val;
-	}
-
-	/**
-	 * get the max total production of the given Objects
-	 *
-	 * @param objects
-	 *            List of Objects
-	 * @param tStep
-	 */
-	private float getTotalProductionAt(ArrayList<AbstractCpsObject> objects, int tStep) {
-		float val = 0;
-
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getTotalEnergyAtTimeStep(tStep) > 0 && ele.getActive()) {
-						val += ele.getTotalEnergyAtTimeStep(tStep);
-					}
-				}
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalProductionAt(((CpsUpperNode) obj).getNodes(), tStep);
-			}
-		}
-		return val;
-	}
-
-	/**
-	 * get the total consumption of the given Objects at the given timestep
-	 *
-	 * @param objects
-	 *            List of Objects
-	 * @param tStep
-	 */
-	private float getTotalConsumptionAt(ArrayList<AbstractCpsObject> objects, int tStep) {
-		float val = 0;
-
-		for (AbstractCpsObject obj : objects) {
-			if (obj instanceof HolonObject) {
-				for (HolonElement ele : ((HolonObject) obj).getElements()) {
-					if (ele.getEnergyAt()[tStep] < 0 && ele.getActive()) {
-						val += ele.getTotalEnergyAtTimeStep(tStep);
-					}
-				}
-			} else if (obj instanceof CpsUpperNode) {
-				val += getTotalConsumptionAt(((CpsUpperNode) obj).getNodes(), tStep);
-			}
-		}
-		return val;
-	}
-
-	/**
-	 * get the Percentage of how many objects with the given state are in the
-	 * given List
-	 *
-	 * @param objects
-	 *            List of Objects
-	 */
-	private float getPercentState(ArrayList<AbstractCpsObject> objects, int state) {
-		float count = controller.getNumberHolonObjects(objects);
-		float stateObjectss = controller.getNumberStateObjects(objects, state);
-
-		return stateObjectss / count;
-	}
-
-	/**
-	 * Return all TrackedDataSets
-	 * 
-	 * @return ArrayList of TrackedDataSet
-	 */
-	public ArrayList<TrackedDataSet> getDataSets() {
-		return dataSets;
-	}
-
-	/**
-	 * Reset the Graph. Delete all calculated values.
-	 */
-	public void resetGraph() {
-		for (TrackedDataSet s : dataSets) {
-			s.resetValues();
-		}
-	}
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    // Maximum y Value
+    float maximum = 0;
+
+    // is the Simulation running?
+//	private boolean isSimRunning;
+    GeneralPath path = new GeneralPath();
+    // model and controller
+    private Model model;
+    private Control controller;
+    // Graphics2D
+    private Graphics2D g2;
+    // Data
+    private ArrayList<TrackedDataSet> dataSets = new ArrayList<>();
+
+    private boolean showGrid = true;
+
+//	private JTable table = new JTable();
+//	private ArrayList<Line2D> gridLines = new ArrayList<>();
+
+    /**
+     * Constructor.
+     *
+     * @param model   the Model
+     * @param control the Controller
+     */
+    public StatisticGraph(final Model model, Control control) {
+        this.controller = control;
+        this.model = model;
+        this.setBackground(Color.WHITE);
+    }
+
+    /**
+     * Paints all Components on the Canvas.
+     *
+     * @param g Graphics
+     */
+    public void paintComponent(Graphics g) {
+        super.paintComponent(g);
+
+        // Graphics2D init
+        g2 = (Graphics2D) g;
+        RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        g2.setRenderingHints(rh);
+
+        // Paint the Grid if it should currently be shown
+        if (showGrid) {
+            g2.setStroke(new BasicStroke(0));
+
+            g2.setColor(Color.BLACK);
+            for (int i = 0; i <= this.getWidth(); i += 10) {
+                g2.drawLine(i, 0, i, this.getHeight());
+            }
+            for (int i = 0; i <= this.getHeight(); i += 5) {
+                g2.drawLine(0, i, this.getWidth(), i);
+            }
+        }
+
+        g2.setStroke(new BasicStroke(3));
+
+        // Calculate the Maximum
+        // calcMaximum();
+
+        // Calculate values for each set and add them
+        // addValues();
+
+        // Create Paths and draw them
+        for (TrackedDataSet set : dataSets) {
+            path.reset();
+            switch (set.getProperty()) {
+                case TrackedDataSet.CONSUMPTION:
+                case TrackedDataSet.PRODUCTION:
+                case TrackedDataSet.ACTIVATED_ELEMENTS:
+                case TrackedDataSet.TOTAL_PRODUCTION:
+                case TrackedDataSet.TOTAL_CONSUMPTION:
+                case TrackedDataSet.AMOUNT_HOLONS:
+                case TrackedDataSet.GROUP_CONSUMPTION:
+                case TrackedDataSet.GROUP_PRODUCTION:
+                case TrackedDataSet.AMOUNT_CLOSED_SWITCHES:
+                case TrackedDataSet.AVG_AMOUNT_OBJECTS_IN_HOLONS:
+                case TrackedDataSet.AVG_AMOUNT_ELEMENTS_IN_HOLONS:
+                case TrackedDataSet.AVG_AMOUNT_PRODUCERS_IN_HOLONS:
+                case TrackedDataSet.AVG_CONSUMED_ENERGY_IN_HOLONS:
+                case TrackedDataSet.AVG_WASTED_ENERGY_IN_HOLONS:
+                case TrackedDataSet.AMOUNT_BROKEN_EDGES:
+                case TrackedDataSet.AVG_AMOUNT_CLOSED_SWITCHES_IN_HOLONS:
+                case TrackedDataSet.AVG_AMOUNT_ACTIVE_ELEMENTS_IN_HOLONS:
+                case TrackedDataSet.AVG_AMOUNT_INACTIVE_ELEMENTS_IN_HOLONS:
+                case TrackedDataSet.AVG_PRODUCED_ENERGY_IN_HOLONS:
+                    createPathFloats(set);
+                    break;
+                case TrackedDataSet.ON_OFF:
+                    createPathBooleans(set);
+                    break;
+                case TrackedDataSet.PERCENT_SUPPLIED:
+                case TrackedDataSet.PERCENT_NOT_SUPPLIED:
+                case TrackedDataSet.PERCENT_PARTIAL_SUPPLIED:
+                case TrackedDataSet.RATIO_PRODUCERS_CONSUMERS:
+                    createPathPercent(set);
+                    break;
+                default:
+                    break;
+            }
+            g2.setColor(set.getColor());
+            g2.draw(path);
+        }
+    }
+
+    /**
+     * Add an Object to the Graph if the maximum has not reached yet.
+     *
+     * @param set the Object to add
+     */
+    public void addObject(TrackedDataSet set) {
+        dataSets.add(set);
+    }
+
+    /**
+     * Removes an Object from the Graph.
+     *
+     * @param id the id of the Object to remove
+     */
+    public void removeObject(int id) {
+        dataSets.remove(id);
+    }
+
+    /**
+     * converts the number to fit the canvas.
+     *
+     * @param d the number to convert
+     * @return the converted number
+     */
+    public double convertToCanvasY(float d) {
+        return Math.abs((this.getHeight() - (d * (this.getHeight() / maximum))));
+    }
+
+    /**
+     * Does take into account which timestep is watched, calculates the max
+     * values.
+     *
+     * @return the currentEnergy
+     */
+    public float getEnergyAtCurrentTimeStep(HolonObject obj) {
+        float temp = 0;
+        for (HolonElement e : obj.getElements()) {
+            if (e.getActive()) {
+                temp = temp + e.getEnergyAt()[model.getCurIteration()];
+            }
+        }
+        return temp;
+    }
+
+    /**
+     * Calculate the Max Value of the Graph
+     */
+    public void calcMaximum() {
+        maximum = 0;
+        for (TrackedDataSet set : dataSets) {
+            float val = 0;
+            switch (set.getProperty()) {
+                case TrackedDataSet.CONSUMPTION:
+                    for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
+                        if (h.getEnergy() < 0) {
+                            val += (h.getEnergy() + h.getFlexibility()) * h.getAmount();
+                        }
+                    }
+                    val *= -1;
+                    break;
+                case TrackedDataSet.PRODUCTION:
+                    for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
+                        if (h.getEnergy() > 0) {
+                            val += (h.getEnergy() + h.getFlexibility()) * h.getAmount();
+                        }
+                    }
+                    break;
+                case TrackedDataSet.ACTIVATED_ELEMENTS:
+                    for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
+                        val += h.getAmount();
+                    }
+                    break;
+                case TrackedDataSet.ON_OFF:
+                    val = 1;
+                    break;
+                case TrackedDataSet.TOTAL_PRODUCTION:
+                    val = getMaxTotalProduction(model.getObjectsOnCanvas());
+                    break;
+                case TrackedDataSet.TOTAL_CONSUMPTION:
+                    val = getMaxTotalConsumption(model.getObjectsOnCanvas());
+                    val *= -1;
+                    break;
+                case TrackedDataSet.PERCENT_SUPPLIED:
+                case TrackedDataSet.PERCENT_NOT_SUPPLIED:
+                case TrackedDataSet.PERCENT_PARTIAL_SUPPLIED:
+                    val = 1;
+                    break;
+                case TrackedDataSet.GROUP_PRODUCTION:
+                    val = getMaxTotalProduction(((CpsUpperNode) set.getCpsObject()).getNodes());
+                    break;
+                case TrackedDataSet.GROUP_CONSUMPTION:
+                    val = getMaxTotalConsumption(((CpsUpperNode) set.getCpsObject()).getNodes());
+                    val *= -1;
+                    break;
+                case TrackedDataSet.AMOUNT_HOLONS:
+                    val = controller.getSimManager().getSubNets().size();
+                    for (int i = 0; i < model.getCurIteration(); i++) {
+                        if (val < set.getValues()[i]) {
+                            val = set.getValues()[i];
+                        }
+                    }
+                    break;
+                case TrackedDataSet.AMOUNT_CLOSED_SWITCHES:
+                    val = model.getSwitches().size();
+                    break;
+                case TrackedDataSet.AVG_AMOUNT_OBJECTS_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        if (val < sub.getObjects().size()) {
+                            val = sub.getObjects().size();
+                        }
+                    }
+                    break;
+                case TrackedDataSet.AVG_AMOUNT_ELEMENTS_IN_HOLONS:
+                case TrackedDataSet.AVG_AMOUNT_ACTIVE_ELEMENTS_IN_HOLONS:
+                case TrackedDataSet.AVG_AMOUNT_INACTIVE_ELEMENTS_IN_HOLONS:
+                    float eCount = 0;
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        for (HolonObject obj : sub.getObjects()) {
+                            eCount += obj.getElements().size();
+                        }
+                        if (val < eCount) {
+                            val = eCount;
+                        }
+                        eCount = 0;
+                    }
+                    break;
+                case TrackedDataSet.AVG_AMOUNT_PRODUCERS_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        if (val < sub.getObjects().size()) {
+                            val = sub.getObjects().size();
+                        }
+                    }
+                    break;
+                case TrackedDataSet.AVG_CONSUMED_ENERGY_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        float tempVal = -getMaxTotalConsumption(new ArrayList<AbstractCpsObject>(sub.getObjects()));
+                        if (val < tempVal) {
+                            val = tempVal;
+                        }
+                    }
+                    break;
+                case TrackedDataSet.AVG_WASTED_ENERGY_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        float tempVal = getMaxTotalProduction(new ArrayList<AbstractCpsObject>(sub.getObjects()));
+                        if (val < tempVal) {
+                            val = tempVal;
+                        }
+                    }
+                    break;
+                case TrackedDataSet.AMOUNT_BROKEN_EDGES:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        val += sub.getSwitches().size();
+                    }
+                    break;
+                case TrackedDataSet.RATIO_PRODUCERS_CONSUMERS:
+                    val = 1;
+                    break;
+                case TrackedDataSet.AVG_AMOUNT_CLOSED_SWITCHES_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        float tempVal = sub.getSwitches().size();
+                        if (val < tempVal) {
+                            val = tempVal;
+                        }
+                    }
+                    break;
+                case TrackedDataSet.AVG_PRODUCED_ENERGY_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        float tempVal = getMaxTotalProduction(new ArrayList<AbstractCpsObject>(sub.getObjects()));
+                        if (val < tempVal) {
+                            val = tempVal;
+                        }
+                    }
+                    break;
+                default:
+                    maximum = 0;
+                    break;
+            }
+            if (val > maximum) {
+                maximum = val;
+            }
+        }
+        ((StatisticGraphPanel) this.getParent().getParent()).setMaximumLabel(maximum);
+    }
+
+    /**
+     * Add the Current Values to each set
+     */
+    public void addValues() {
+        for (TrackedDataSet set : dataSets) {
+            float val = 0;
+            switch (set.getProperty()) {
+                case TrackedDataSet.CONSUMPTION:
+                    for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
+                        if (h.getTotalEnergyAtTimeStep(model.getCurIteration()) < 0 && h.getActive()) {
+                            val += Math.abs(h.getTotalEnergyAtTimeStep(model.getCurIteration()));
+                        }
+                        set.setValAt(val, model.getCurIteration());
+                    }
+                    break;
+                case TrackedDataSet.PRODUCTION:
+                    for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
+                        if (h.getTotalEnergyAtTimeStep(model.getCurIteration()) > 0 && h.getActive()) {
+                            val += Math.abs(h.getTotalEnergyAtTimeStep(model.getCurIteration()));
+                        }
+                        set.setValAt(val, model.getCurIteration());
+                    }
+
+                    break;
+                case TrackedDataSet.ACTIVATED_ELEMENTS:
+                    for (HolonElement h : ((HolonObject) set.getCpsObject()).getElements()) {
+                        if (h.getActive()) {
+                            val += h.getAmount();
+                        }
+                        set.setValAt(val, model.getCurIteration());
+                    }
+                    break;
+                case TrackedDataSet.ON_OFF:
+                    if (((HolonSwitch) set.getCpsObject()).getManualMode()) {
+                        if (((HolonSwitch) set.getCpsObject()).getActiveManual()) {
+                            set.setValAt(1, model.getCurIteration());
+                        } else {
+                            set.setValAt(0, model.getCurIteration());
+                        }
+                    } else {
+                        if (((HolonSwitch) set.getCpsObject()).getActiveAt()[model.getCurIteration()]) {
+                            set.setValAt(1, model.getCurIteration());
+                        } else {
+                            set.setValAt(0, model.getCurIteration());
+                        }
+                    }
+                    break;
+                case TrackedDataSet.TOTAL_PRODUCTION:
+                    set.setValAt(getTotalProductionAt(model.getObjectsOnCanvas(), model.getCurIteration()),
+                            model.getCurIteration());
+                    break;
+                case TrackedDataSet.TOTAL_CONSUMPTION:
+                    set.setValAt(-getTotalConsumptionAt(model.getObjectsOnCanvas(), model.getCurIteration()),
+                            model.getCurIteration());
+                    break;
+                case TrackedDataSet.PERCENT_SUPPLIED:
+                    set.setValAt(getPercentState(model.getObjectsOnCanvas(), HolonObject.SUPPLIED),
+                            model.getCurIteration());
+                    break;
+                case TrackedDataSet.PERCENT_NOT_SUPPLIED:
+                    set.setValAt(getPercentState(model.getObjectsOnCanvas(), HolonObject.NOT_SUPPLIED),
+                            model.getCurIteration());
+                    break;
+                case TrackedDataSet.PERCENT_PARTIAL_SUPPLIED:
+                    set.setValAt(getPercentState(model.getObjectsOnCanvas(), HolonObject.PARTIALLY_SUPPLIED),
+                            model.getCurIteration());
+                    break;
+                case TrackedDataSet.GROUP_PRODUCTION:
+                    set.setValAt(
+                            getTotalProductionAt(((CpsUpperNode) set.getCpsObject()).getNodes(), model.getCurIteration()),
+                            model.getCurIteration());
+                    break;
+                case TrackedDataSet.GROUP_CONSUMPTION:
+                    set.setValAt(
+                            -getTotalConsumptionAt(((CpsUpperNode) set.getCpsObject()).getNodes(), model.getCurIteration()),
+                            model.getCurIteration());
+                    break;
+                case TrackedDataSet.AMOUNT_HOLONS:
+                    set.setValAt(controller.getSimManager().getSubNets().size(), model.getCurIteration());
+                    break;
+                case TrackedDataSet.AMOUNT_CLOSED_SWITCHES:
+                    for (HolonSwitch s : model.getSwitches()) {
+                        if (s.getState(model.getCurIteration())) {
+                            val++;
+                        }
+                    }
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.AVG_AMOUNT_OBJECTS_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        val += sub.getObjects().size();
+                    }
+                    val /= controller.getSimManager().getSubNets().size();
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.AVG_AMOUNT_ELEMENTS_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        for (HolonObject obj : sub.getObjects()) {
+                            val += obj.getElements().size();
+                        }
+                    }
+                    val /= controller.getSimManager().getSubNets().size();
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.AVG_AMOUNT_PRODUCERS_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        for (HolonObject obj : sub.getObjects()) {
+                            if (obj.getCurrentEnergyAtTimeStep(model.getCurIteration()) > 0) {
+                                val++;
+                            }
+                        }
+                    }
+                    val /= controller.getSimManager().getSubNets().size();
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.AVG_CONSUMED_ENERGY_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        val += -getTotalConsumptionAt(new ArrayList<AbstractCpsObject>(sub.getObjects()),
+                                model.getCurIteration());
+                    }
+                    val /= controller.getSimManager().getSubNets().size();
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.AVG_WASTED_ENERGY_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        val += (getTotalProductionAt(new ArrayList<AbstractCpsObject>(sub.getObjects()),
+                                model.getCurIteration())
+                                + getTotalConsumptionAt(new ArrayList<AbstractCpsObject>(sub.getObjects()),
+                                model.getCurIteration()));
+                    }
+                    val /= controller.getSimManager().getSubNets().size();
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.AMOUNT_BROKEN_EDGES:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        for (HolonSwitch s : sub.getSwitches()) {
+                            if (s.getState()) {
+                                val++;
+                            }
+                        }
+                    }
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.RATIO_PRODUCERS_CONSUMERS:
+                    float prod = 0;
+                    float cons = 0;
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        for (HolonObject obj : sub.getObjects()) {
+                            if (obj.getCurrentEnergyAtTimeStep(model.getCurIteration()) > 0) {
+                                prod++;
+                            } else if (obj.getCurrentEnergyAtTimeStep(model.getCurIteration()) < 0) {
+                                cons++;
+                            }
+                        }
+                    }
+                    val = prod / (prod + cons);
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.AVG_AMOUNT_CLOSED_SWITCHES_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        val += sub.getSwitches().size();
+                    }
+                    val /= controller.getSimManager().getSubNets().size();
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.AVG_AMOUNT_ACTIVE_ELEMENTS_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        for (HolonObject obj : sub.getObjects()) {
+                            for (HolonElement ele : obj.getElements()) {
+                                if (ele.getActive()) {
+                                    val++;
+                                }
+                            }
+                        }
+                    }
+                    val /= controller.getSimManager().getSubNets().size();
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.AVG_AMOUNT_INACTIVE_ELEMENTS_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        for (HolonObject obj : sub.getObjects()) {
+                            for (HolonElement ele : obj.getElements()) {
+                                if (!ele.getActive()) {
+                                    val++;
+                                }
+                            }
+                        }
+                    }
+                    val /= controller.getSimManager().getSubNets().size();
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                case TrackedDataSet.AVG_PRODUCED_ENERGY_IN_HOLONS:
+                    for (SubNet sub : controller.getSimManager().getSubNets()) {
+                        val += getTotalProductionAt(new ArrayList<AbstractCpsObject>(sub.getObjects()),
+                                model.getCurIteration());
+                    }
+                    val /= controller.getSimManager().getSubNets().size();
+                    set.setValAt(val, model.getCurIteration());
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * create Path with floats
+     *
+     * @param set
+     */
+    private void createPathFloats(TrackedDataSet set) {
+        int range = model.getCurIteration(); //to which iteration
+        if (!model.getIsSimRunning()) {
+            range = model.getIterations() - 1;
+        }
+        if (set.getValues()[0] != -1) {
+            path.moveTo(0, convertToCanvasY(set.getValues()[0]));
+        } else {
+            path.moveTo(1 * this.getWidth() / model.getIterations(), convertToCanvasY(set.getValues()[1]));
+        }
+        for (int i = 0; i < range; i++) {
+            if (set.getValues()[i + 1] != -1) {
+                path.lineTo((i + 1) * this.getWidth() / model.getIterations(),
+                        convertToCanvasY(set.getValues()[i + 1]));
+            } else {
+                if (i + 2 < range) {
+                    path.moveTo((i + 2) * this.getWidth() / model.getIterations(),
+                            convertToCanvasY(set.getValues()[i + 2]));
+                }
+            }
+        }
+    }
+
+    /**
+     * create Path with booleans(0 and 1)
+     *
+     * @param set
+     */
+    private void createPathBooleans(TrackedDataSet set) {
+        if (set.getValues()[0] != -1) {
+            path.moveTo(0, convertToCanvasY((float) (set.getValues()[0] * (maximum / 3 * 2)) + (maximum / 6)));
+        } else {
+            path.moveTo(1 * this.getWidth() / model.getIterations(),
+                    convertToCanvasY((float) (set.getValues()[1] * (maximum / 3 * 2)) + (maximum / 6)));
+        }
+        for (int i = 0; i < model.getCurIteration(); i++) {
+            controller.addTextToConsole(set.getValues()[i] + "");
+            if (set.getValues()[i + 1] != -1) {
+                path.lineTo((i + 1) * this.getWidth() / model.getIterations(),
+                        convertToCanvasY((float) (set.getValues()[i + 1] * (maximum / 3 * 2)) + (maximum / 6)));
+            } else {
+                if (i + 2 < model.getCurIteration()) {
+                    path.moveTo((i + 2) * this.getWidth() / model.getIterations(),
+                            convertToCanvasY((float) (set.getValues()[i + 2] * (maximum / 3 * 2)) + (maximum / 6)));
+                }
+            }
+        }
+    }
+
+    /**
+     * create Path for percent values
+     *
+     * @param set
+     */
+    private void createPathPercent(TrackedDataSet set) {
+        if (set.getValues()[0] != -1) {
+            path.moveTo(0, convertToCanvasY(set.getValues()[0] * maximum));
+        } else {
+            path.moveTo(1 * this.getWidth() / model.getIterations(), convertToCanvasY(set.getValues()[1] * maximum));
+        }
+        for (int i = 0; i < model.getCurIteration(); i++) {
+            if (set.getValues()[i + 1] != -1) {
+                path.lineTo((i + 1) * this.getWidth() / model.getIterations(),
+                        convertToCanvasY(set.getValues()[i + 1] * maximum));
+            } else {
+                if (i + 2 < model.getCurIteration()) {
+                    path.moveTo((i + 2) * this.getWidth() / model.getIterations(),
+                            convertToCanvasY(set.getValues()[i + 2] * maximum));
+                }
+            }
+
+        }
+    }
+
+    /**
+     * get the max total production of the given Objects
+     *
+     * @param objects List of Objects
+     */
+    private float getMaxTotalProduction(ArrayList<AbstractCpsObject> objects) {
+        float val = 0;
+
+        for (AbstractCpsObject obj : objects) {
+            if (obj instanceof HolonObject) {
+                for (HolonElement ele : ((HolonObject) obj).getElements()) {
+                    if (ele.getEnergy() > 0) {
+                        val += (ele.getEnergy() + ele.getFlexibility()) * ele.getAmount();
+                    }
+                }
+            } else if (obj instanceof CpsUpperNode) {
+                val += getMaxTotalProduction(((CpsUpperNode) obj).getNodes());
+            }
+        }
+        return val;
+    }
+
+    /**
+     * get the max total consumption of the given Objects
+     *
+     * @param objects List of Objects
+     */
+    private float getMaxTotalConsumption(ArrayList<AbstractCpsObject> objects) {
+        float val = 0;
+
+        for (AbstractCpsObject obj : objects) {
+            if (obj instanceof HolonObject) {
+                for (HolonElement ele : ((HolonObject) obj).getElements()) {
+                    if (ele.getEnergy() < 0) {
+                        val += (ele.getEnergy() + ele.getFlexibility()) * ele.getAmount();
+                    }
+                }
+            } else if (obj instanceof CpsUpperNode) {
+                val += getMaxTotalConsumption(((CpsUpperNode) obj).getNodes());
+            }
+        }
+        return val;
+    }
+
+    /**
+     * get the max total production of the given Objects
+     *
+     * @param objects List of Objects
+     * @param tStep
+     */
+    private float getTotalProductionAt(ArrayList<AbstractCpsObject> objects, int tStep) {
+        float val = 0;
+
+        for (AbstractCpsObject obj : objects) {
+            if (obj instanceof HolonObject) {
+                for (HolonElement ele : ((HolonObject) obj).getElements()) {
+                    if (ele.getTotalEnergyAtTimeStep(tStep) > 0 && ele.getActive()) {
+                        val += ele.getTotalEnergyAtTimeStep(tStep);
+                    }
+                }
+            } else if (obj instanceof CpsUpperNode) {
+                val += getTotalProductionAt(((CpsUpperNode) obj).getNodes(), tStep);
+            }
+        }
+        return val;
+    }
+
+    /**
+     * get the total consumption of the given Objects at the given timestep
+     *
+     * @param objects List of Objects
+     * @param tStep
+     */
+    private float getTotalConsumptionAt(ArrayList<AbstractCpsObject> objects, int tStep) {
+        float val = 0;
+
+        for (AbstractCpsObject obj : objects) {
+            if (obj instanceof HolonObject) {
+                for (HolonElement ele : ((HolonObject) obj).getElements()) {
+                    if (ele.getEnergyAt()[tStep] < 0 && ele.getActive()) {
+                        val += ele.getTotalEnergyAtTimeStep(tStep);
+                    }
+                }
+            } else if (obj instanceof CpsUpperNode) {
+                val += getTotalConsumptionAt(((CpsUpperNode) obj).getNodes(), tStep);
+            }
+        }
+        return val;
+    }
+
+    /**
+     * get the Percentage of how many objects with the given state are in the
+     * given List
+     *
+     * @param objects List of Objects
+     */
+    private float getPercentState(ArrayList<AbstractCpsObject> objects, int state) {
+        float count = controller.getNumberHolonObjects(objects);
+        float stateObjectss = controller.getNumberStateObjects(objects, state);
+
+        return stateObjectss / count;
+    }
+
+    /**
+     * Return all TrackedDataSets
+     *
+     * @return ArrayList of TrackedDataSet
+     */
+    public ArrayList<TrackedDataSet> getDataSets() {
+        return dataSets;
+    }
+
+    /**
+     * Reset the Graph. Delete all calculated values.
+     */
+    public void resetGraph() {
+        for (TrackedDataSet s : dataSets) {
+            s.resetValues();
+        }
+    }
+
+    protected void hideGrid() {
+        Graphics g = this.getGraphics();
+        showGrid = false;
+        // clear the area
+        g.clearRect(0, 0, this.getWidth(), this.getHeight());
+        paintComponent(g);
+    }
+
+    protected void showGrid() {
+        Graphics g = this.getGraphics();
+        showGrid = true;
+        paintComponent(g);
+    }
+
 
 }

+ 342 - 329
src/ui/view/StatisticGraphPanel.java

@@ -1,342 +1,355 @@
 package ui.view;
 
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import classes.TrackedDataSet;
+import ui.controller.Control;
+import ui.model.Model;
+
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Hashtable;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import javax.imageio.ImageIO;
-import javax.swing.BorderFactory;
-import javax.swing.JButton;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JSplitPane;
-import javax.swing.SwingConstants;
-import javax.swing.border.EmptyBorder;
-
-import com.google.gson.JsonObject;
-
-import classes.TrackedDataSet;
-import ui.controller.Control;
-import ui.model.Model;
 
 public class StatisticGraphPanel extends JSplitPane {
 
-	private static final long serialVersionUID = 1L;
-
-	// Model/Controller
-	private Model model;
-	private Control controller;
-
-	// Components
-	private StatisticGraph sGraph;
-	private final JLabel graphNameLabel;
-	private final JLabel maximumLabel = new JLabel("0");
-	private JPanel topPanel = new JPanel();
-	private JButton closeButton = new JButton("X");
-	private JButton savImgButton = new JButton("Save as Image");
-	private JPanel topContainer = new JPanel();
-	private JPanel buttomContainer = new JPanel();
-
-	// Variables
-	String graphName;
-	private final JPanel legendPanel = new JPanel();
-	private JSplitPane that;
-	private Hashtable<String, StatisticGraphPanel> graphHashtable;
-
-	/**
-	 * Constructor.
-	 * 
-	 * @param mod
-	 *            the Model
-	 * @param cont
-	 *            the Controller
-	 */
-	public StatisticGraphPanel(Model mod, Control cont, String name, Hashtable<String, StatisticGraphPanel> gHt) {
-		super();
-		setDividerSize(0);
-		setPreferredSize(new Dimension(600, 300));
-		setContinuousLayout(true);
-		setMinimumSize(new Dimension(600, 300));
-		setOrientation(JSplitPane.VERTICAL_SPLIT);
-		setBorder(new EmptyBorder(0, 0, 0, 0));
-		this.model = mod;
-		this.controller = cont;
-		this.sGraph = new StatisticGraph(mod, cont);
-		this.graphName = name;
-		this.graphHashtable = gHt;
-		topContainer.setLayout(new BorderLayout(0,0));
-		buttomContainer.setPreferredSize(new Dimension(0, 0));
-		buttomContainer.setMinimumSize(new Dimension(0, 0));
-		buttomContainer.setAlignmentX(Component.LEFT_ALIGNMENT);
-		buttomContainer.setAlignmentY(Component.TOP_ALIGNMENT);
-		buttomContainer.setLayout(new BorderLayout(0,0));
-		this.setTopComponent(topContainer);
-		this.setBottomComponent(buttomContainer);
-		//setLayout(new BorderLayout(0, 0));
-
-		// ******************** Component Propertys ***************//
-		// Graph
-		// this.setPreferredSize(new Dimension(300, 200));
-		sGraph.setPreferredSize(new Dimension(200, 200));
-		sGraph.setMinimumSize(new Dimension(100, 150));
-		// this.setMaximumSize(new Dimension(700, 200));
-		// this.setMinimumSize(new Dimension(300, 200));
-
-		// Graph Name
-		graphNameLabel = new JLabel(graphName);
-		graphNameLabel.setHorizontalTextPosition(JLabel.CENTER);
-
-		// Panel on top (Name and Close Button)
-		topPanel.setLayout(new BorderLayout(0, 0));
-		JPanel topPanelHelp = new JPanel(new BorderLayout(0, 0));
-		topPanelHelp.add(graphNameLabel, BorderLayout.CENTER);
-		topPanelHelp.add(savImgButton, BorderLayout.EAST);
-		topPanel.add(topPanelHelp, BorderLayout.CENTER);
-		topPanel.add(closeButton, BorderLayout.EAST);
-		savImgButton.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				BufferedImage img = new BufferedImage(that.getWidth(), that.getHeight(), BufferedImage.TYPE_INT_RGB);
-				that.print(img.getGraphics());
-				try {
-					JFileChooser fileChooser = new JFileChooser();
-					if (fileChooser.showSaveDialog(new JFrame()) == JFileChooser.APPROVE_OPTION) {
-						String file = fileChooser.getSelectedFile().getPath();
-						ImageIO.write(img, "jpg", new File(file + ".jpg"));
-					}
-				} catch (IOException e1) {
-					// TODO Auto-generated catch block
-					e1.printStackTrace();
-				}
-
-			}
-		});
-		topPanel.setBorder(null);
-
-		// Maximum Label
-		maximumLabel.setVerticalAlignment(SwingConstants.TOP);
-		maximumLabel.setMinimumSize(new Dimension(30, 10));
-		legendPanel.setAlignmentY(Component.BOTTOM_ALIGNMENT);
-
-		// Legend Panel
-		legendPanel.setLayout(new GridLayout(0, 5, 0, 0));
-
-		// ******************** Component Listener ****************//
-
-		that = this;
-		closeButton.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				JPanel parent = (JPanel) that.getParent();
-				for (int i = 0; i < parent.getComponentCount(); i++) {
-					if (parent.getComponent(i).equals(that)) {
-						if(parent.getComponentCount() > i + 1){
-							parent.remove(parent.getComponent(i+1));
-						}
-						break;
-					}
-				}
-				graphHashtable.remove(graphName);
-				parent.remove(that);
-				parent.updateUI();
-			}
-		});
-
-		// ******************** add everything ********************//
-		topContainer.add(sGraph);
-		topContainer.add(topPanel, BorderLayout.NORTH);
-		topContainer.add(maximumLabel, BorderLayout.WEST);
-		buttomContainer.add(legendPanel, BorderLayout.NORTH);
-		this.setEnabled(false);
-
-	}
-
-	/**
-	 * Adds the Set to the Graph.
-	 * 
-	 * @param set
-	 */
-	public void addObject(TrackedDataSet set) {
-		if(legendPanel.getComponentCount() >= 20){
-			JOptionPane.showMessageDialog(null, "You can not add more than 20 Properties to a Graph");
-			return;
-		}
-		sGraph.addObject(set);
-		String property = "";
-		switch (set.getProperty()) {
-		case TrackedDataSet.CONSUMPTION:
-		case TrackedDataSet.GROUP_CONSUMPTION:
-			property = "consumption";
-			break;
-		case TrackedDataSet.PRODUCTION:
-		case TrackedDataSet.GROUP_PRODUCTION:
-			property = "production";
-			break;
-		case TrackedDataSet.ACTIVATED_ELEMENTS:
-			property = "active elements";
-			break;
-		case TrackedDataSet.ON_OFF:
-			property = "on//off";
-			break;
-		case TrackedDataSet.TOTAL_PRODUCTION:
-			property = "total production";
-			break;
-		case TrackedDataSet.TOTAL_CONSUMPTION:
-			property = "total consumption";
-			break;
-		case TrackedDataSet.PERCENT_SUPPLIED:
-			property = "Percentage of supplied";
-			break;
-		case TrackedDataSet.PERCENT_NOT_SUPPLIED:
-			property = "Percentage of not supplied";
-			break;
-		case TrackedDataSet.PERCENT_PARTIAL_SUPPLIED:
-			property = "Percentage of partial supplied";
-			break;
-		case TrackedDataSet.AMOUNT_HOLONS:
-			property = "Amount of holons";
-			break;
-		case TrackedDataSet.AMOUNT_CLOSED_SWITCHES:
-			property = "Amount of Closed Switches";
-			break;
-		case TrackedDataSet.AVG_AMOUNT_OBJECTS_IN_HOLONS:
-			property = "Avg. Amount of Objects in Holons";
-			break;
-		case TrackedDataSet.AVG_AMOUNT_ELEMENTS_IN_HOLONS:
-			property = "Avg. Amount of Elements in Holons";
-			break;
-		case TrackedDataSet.AVG_AMOUNT_PRODUCERS_IN_HOLONS:
-			property = "Avg. Amount Producers in Holons";
-			break;
-		case TrackedDataSet.AVG_CONSUMED_ENERGY_IN_HOLONS:
-			property = "Avg. Consumed Energy in Holons";
-			break;
-		case TrackedDataSet.AVG_WASTED_ENERGY_IN_HOLONS:
-			property = "Avg. Wasted Energy in Holons";
-			break;
-		case TrackedDataSet.AMOUNT_BROKEN_EDGES:
-			property = "Amount of Broken Edged";
-			break;
-		case TrackedDataSet.RATIO_PRODUCERS_CONSUMERS:
-			property = "Ratio Producers:Consumers";
-			break;
-		case TrackedDataSet.AVG_AMOUNT_CLOSED_SWITCHES_IN_HOLONS:
-			property = "Avg. Amount of Closed Switches in Holons";
-			break;
-		case TrackedDataSet.AVG_AMOUNT_ACTIVE_ELEMENTS_IN_HOLONS:
-			property = "Avg. Amount of Active Elements in Holons";
-			break;
-		case TrackedDataSet.AVG_AMOUNT_INACTIVE_ELEMENTS_IN_HOLONS:
-			property = "Avg. Amount of Inactive Elements in Holons";
-			break;
-		case TrackedDataSet.AVG_PRODUCED_ENERGY_IN_HOLONS:
-			property = "Avg. Produced Energy in Holons";
-			break;
-		default:
-			property = "null";
-			break;
-		}
-		JLabel b;
-		if (set.getCpsObject() != null) {
-			b = new JLabel(set.getCpsObject().getId() + ", " + set.getCpsObject().getName() + ": " + property);
-		} else {
-			b = new JLabel(property);
-		}
-		// b.setBackground(set.getColor());
-		b.setBorder(BorderFactory.createLineBorder(set.getColor(), 2));
-		b.setHorizontalAlignment(SwingConstants.CENTER);
-		int color = Math.max(Math.max(set.getColor().getRed(), set.getColor().getGreen()), set.getColor().getBlue());
-
-		b.setOpaque(true);
-		b.addMouseListener(new MouseAdapter() {
-
-			@Override
-			public void mousePressed(MouseEvent e) {
-				if (MouseEvent.BUTTON3 == e.getButton()) {
-					for (int i = 0; i < legendPanel.getComponentCount(); i++) {
-						if (legendPanel.getComponent(i).equals(e.getComponent())) {
-							legendPanel.remove(i);
-							sGraph.removeObject(i);
-							that.updateUI();
-						}
-					}
-				}
-			}
-		});
-		legendPanel.add(b);
-		sGraph.calcMaximum();
-		that.updateUI();
-	}
-
-	/**
-	 * Set the Maximum Label
-	 *
-	 * @param max
-	 */
-	public void setMaximumLabel(double max) {
-		maximumLabel.setText(Double.toString(max));
-	}
-
-	/**
-	 * Get the name of the Graph.
-	 * 
-	 * @return the name of the Graph
-	 */
-	public String getGraphName() {
-		return this.graphName;
-	}
-
-	/**
-	 * Calls the addValue function of the sGraph
-	 */
-	public void addValues() {
-		sGraph.addValues();
-	}
-
-	/**
-	 * Calls the calcMaximum function of the sGraph
-	 */
-	public void calcMaximum() {
-		sGraph.calcMaximum();
-	}
-
-	public StatisticGraph getStatGraph() {
-		return sGraph;
-	}
-
-	public void setStatisticGraph(StatisticGraph sG) {
-		this.sGraph = sG;
-	}
-
-	/**
-	 * Reset the Graph. Delete all calculated values.
-	 */
-	public void resetGraph() {
-		sGraph.resetGraph();
-	}
-
-	/**
-	 * Returns the Legend Panel.
-	 * @return legendPanel
-	 */
-	public JPanel getLegendPanel(){
-		return legendPanel;
-	}
+    private static final long serialVersionUID = 1L;
+
+    // Model/Controller
+//    private Model model;
+//    private Control controller;
+    private final JLabel graphNameLabel;
+    private final JLabel maximumLabel = new JLabel("0");
+    private final JPanel legendPanel = new JPanel();
+    String[] backgroundColors = {"White", "Dark", "Red", "Blue"};
+    // Variables
+    String graphName;
+    // Components
+    private StatisticGraph sGraph;
+    private JPanel topPanel = new JPanel();
+    private JButton closeButton = new JButton("X");
+    private JPanel graphOptionsContainer = new JPanel();
+    private JToggleButton toggleGridButton = new JToggleButton("Hide Grid");
+    private JLabel backgroundColorLabel = new JLabel("Background: ");
+    private JComboBox backgroundColorSelector = new JComboBox(backgroundColors);
+    private JButton savImgButton = new JButton("Save as Image");
+    private JPanel topContainer = new JPanel();
+    private JPanel buttomContainer = new JPanel();
+    private JSplitPane that;
+    private Hashtable<String, StatisticGraphPanel> graphHashtable;
+
+    /**
+     * Constructor.
+     *
+     * @param mod  the Model
+     * @param cont the Controller
+     */
+    public StatisticGraphPanel(Model mod, Control cont, String name, Hashtable<String, StatisticGraphPanel> gHt) {
+        super();
+        setDividerSize(0);
+        setPreferredSize(new Dimension(600, 300));
+        setContinuousLayout(true);
+        setMinimumSize(new Dimension(600, 300));
+        setOrientation(JSplitPane.VERTICAL_SPLIT);
+        setBorder(new EmptyBorder(0, 0, 0, 0));
+//        this.model = mod;
+//        this.controller = cont;
+        this.sGraph = new StatisticGraph(mod, cont);
+        this.graphName = name;
+        this.graphHashtable = gHt;
+        topContainer.setLayout(new BorderLayout(0, 0));
+        buttomContainer.setPreferredSize(new Dimension(0, 0));
+        buttomContainer.setMinimumSize(new Dimension(0, 0));
+        buttomContainer.setAlignmentX(Component.LEFT_ALIGNMENT);
+        buttomContainer.setAlignmentY(Component.TOP_ALIGNMENT);
+        buttomContainer.setLayout(new BorderLayout(0, 0));
+        this.setTopComponent(topContainer);
+        this.setBottomComponent(buttomContainer);
+
+        // ******************** Component Propertys ***************//
+        // Graph
+        sGraph.setPreferredSize(new Dimension(200, 200));
+        sGraph.setMinimumSize(new Dimension(100, 150));
+
+        // Graph Name
+        graphNameLabel = new JLabel(graphName);
+        graphNameLabel.setHorizontalTextPosition(JLabel.CENTER);
+        // set font bold and font size slightly bigger than the rest
+        graphNameLabel.setFont(new Font(graphNameLabel.getFont().getName(), Font.BOLD, 14));
+
+        toggleGridButton.addActionListener(actionEvent -> {
+            boolean currentState = toggleGridButton.isSelected();
+            if (currentState) {
+                sGraph.hideGrid();
+                toggleGridButton.setText("Show Grid");
+            } else {
+                sGraph.showGrid();
+                toggleGridButton.setText("Hide Grid");
+            }
+        });
+
+        // Panel on top (Name and Close Button)
+        topPanel.setLayout(new BorderLayout(0, 0));
+        JPanel topPanelHelp = new JPanel(new BorderLayout(0, 0));
+        topPanelHelp.add(graphNameLabel, BorderLayout.CENTER);
+        // graph options
+        graphOptionsContainer.add(toggleGridButton);
+        graphOptionsContainer.add(new JLabel("  "));    // spacer
+        graphOptionsContainer.add(backgroundColorLabel);
+        graphOptionsContainer.add(backgroundColorSelector);
+        graphOptionsContainer.add(new JLabel("  "));    // spacer
+        graphOptionsContainer.add(savImgButton);
+        topPanelHelp.add(graphOptionsContainer, BorderLayout.EAST);
+        //
+        topPanel.add(topPanelHelp, BorderLayout.CENTER);
+        topPanel.add(closeButton, BorderLayout.EAST);
+        savImgButton.addActionListener(actionEvent -> {
+            BufferedImage img = new BufferedImage(that.getWidth(), that.getHeight(), BufferedImage.TYPE_INT_RGB);
+            that.print(img.getGraphics());
+            try {
+                JFileChooser fileChooser = new JFileChooser();
+                if (fileChooser.showSaveDialog(new JFrame()) == JFileChooser.APPROVE_OPTION) {
+                    String file = fileChooser.getSelectedFile().getPath();
+                    ImageIO.write(img, "jpg", new File(file + ".jpg"));
+                }
+            } catch (IOException e1) {
+                // TODO Auto-generated catch block
+                e1.printStackTrace();
+            }
+
+        });
+        topPanel.setBorder(null);
+
+        // background-color selector
+        backgroundColorSelector.addActionListener(actionEvent -> {
+            String selectedBackgroundString = (String) backgroundColorSelector.getSelectedItem();
+            switch (selectedBackgroundString) {
+                case "White":
+                    sGraph.setBackground(Color.WHITE);
+                    break;
+                case "Dark":
+                    sGraph.setBackground(Color.DARK_GRAY);
+                    break;
+                case "Red":
+                    sGraph.setBackground(Color.RED);
+                    break;
+                case "Blue":
+                    sGraph.setBackground(Color.BLUE);
+                    break;
+            }
+        });
+
+        // Maximum Label
+        maximumLabel.setVerticalAlignment(SwingConstants.TOP);
+        maximumLabel.setMinimumSize(new Dimension(30, 10));
+        legendPanel.setAlignmentY(Component.BOTTOM_ALIGNMENT);
+
+        // Legend Panel
+        legendPanel.setLayout(new GridLayout(0, 5, 0, 0));
+
+        // ******************** Component Listener ****************//
+
+        that = this;
+        closeButton.addActionListener(actionEvent -> {
+            JPanel parent = (JPanel) that.getParent();
+            for (int i = 0; i < parent.getComponentCount(); i++) {
+                if (parent.getComponent(i).equals(that)) {
+                    if (parent.getComponentCount() > i + 1) {
+                        parent.remove(parent.getComponent(i + 1));
+                    }
+                    break;
+                }
+            }
+            graphHashtable.remove(graphName);
+            parent.remove(that);
+            parent.updateUI();
+        });
+
+        // ******************** add everything ********************//
+        topContainer.add(sGraph);
+        topContainer.add(topPanel, BorderLayout.NORTH);
+        topContainer.add(maximumLabel, BorderLayout.WEST);
+        buttomContainer.add(legendPanel, BorderLayout.NORTH);
+        this.setEnabled(false);
+
+    }
+
+    /**
+     * Adds the Set to the Graph.
+     *
+     * @param set
+     */
+
+    public void addObject(TrackedDataSet set) {
+        if (legendPanel.getComponentCount() >= 20) {
+            JOptionPane.showMessageDialog(null, "You can not add more than 20 Properties to a Graph");
+            return;
+        }
+        sGraph.addObject(set);
+        String property;
+        switch (set.getProperty()) {
+            case TrackedDataSet.CONSUMPTION:
+            case TrackedDataSet.GROUP_CONSUMPTION:
+                property = "consumption";
+                break;
+            case TrackedDataSet.PRODUCTION:
+            case TrackedDataSet.GROUP_PRODUCTION:
+                property = "production";
+                break;
+            case TrackedDataSet.ACTIVATED_ELEMENTS:
+                property = "active elements";
+                break;
+            case TrackedDataSet.ON_OFF:
+                property = "on//off";
+                break;
+            case TrackedDataSet.TOTAL_PRODUCTION:
+                property = "total production";
+                break;
+            case TrackedDataSet.TOTAL_CONSUMPTION:
+                property = "total consumption";
+                break;
+            case TrackedDataSet.PERCENT_SUPPLIED:
+                property = "Percentage of supplied";
+                break;
+            case TrackedDataSet.PERCENT_NOT_SUPPLIED:
+                property = "Percentage of not supplied";
+                break;
+            case TrackedDataSet.PERCENT_PARTIAL_SUPPLIED:
+                property = "Percentage of partial supplied";
+                break;
+            case TrackedDataSet.AMOUNT_HOLONS:
+                property = "Amount of holons";
+                break;
+            case TrackedDataSet.AMOUNT_CLOSED_SWITCHES:
+                property = "Amount of Closed Switches";
+                break;
+            case TrackedDataSet.AVG_AMOUNT_OBJECTS_IN_HOLONS:
+                property = "Avg. Amount of Objects in Holons";
+                break;
+            case TrackedDataSet.AVG_AMOUNT_ELEMENTS_IN_HOLONS:
+                property = "Avg. Amount of Elements in Holons";
+                break;
+            case TrackedDataSet.AVG_AMOUNT_PRODUCERS_IN_HOLONS:
+                property = "Avg. Amount Producers in Holons";
+                break;
+            case TrackedDataSet.AVG_CONSUMED_ENERGY_IN_HOLONS:
+                property = "Avg. Consumed Energy in Holons";
+                break;
+            case TrackedDataSet.AVG_WASTED_ENERGY_IN_HOLONS:
+                property = "Avg. Wasted Energy in Holons";
+                break;
+            case TrackedDataSet.AMOUNT_BROKEN_EDGES:
+                property = "Amount of Broken Edged";
+                break;
+            case TrackedDataSet.RATIO_PRODUCERS_CONSUMERS:
+                property = "Ratio Producers:Consumers";
+                break;
+            case TrackedDataSet.AVG_AMOUNT_CLOSED_SWITCHES_IN_HOLONS:
+                property = "Avg. Amount of Closed Switches in Holons";
+                break;
+            case TrackedDataSet.AVG_AMOUNT_ACTIVE_ELEMENTS_IN_HOLONS:
+                property = "Avg. Amount of Active Elements in Holons";
+                break;
+            case TrackedDataSet.AVG_AMOUNT_INACTIVE_ELEMENTS_IN_HOLONS:
+                property = "Avg. Amount of Inactive Elements in Holons";
+                break;
+            case TrackedDataSet.AVG_PRODUCED_ENERGY_IN_HOLONS:
+                property = "Avg. Produced Energy in Holons";
+                break;
+            default:
+                property = "null";
+                break;
+        }
+        JLabel b;
+        if (set.getCpsObject() != null) {
+            b = new JLabel(set.getCpsObject().getId() + ", " + set.getCpsObject().getName() + ": " + property);
+        } else {
+            b = new JLabel(property);
+        }
+        // b.setBackground(set.getColor());
+        b.setBorder(BorderFactory.createLineBorder(set.getColor(), 2));
+        b.setHorizontalAlignment(SwingConstants.CENTER);
+//        int color = Math.max(Math.max(set.getColor().getRed(), set.getColor().getGreen()), set.getColor().getBlue());
+
+        b.setOpaque(true);
+        b.addMouseListener(new MouseAdapter() {
+
+            @Override
+            public void mousePressed(MouseEvent e) {
+                if (MouseEvent.BUTTON3 == e.getButton()) {
+                    for (int i = 0; i < legendPanel.getComponentCount(); i++) {
+                        if (legendPanel.getComponent(i).equals(e.getComponent())) {
+                            legendPanel.remove(i);
+                            sGraph.removeObject(i);
+                            that.updateUI();
+                        }
+                    }
+                }
+            }
+        });
+        legendPanel.add(b);
+        sGraph.calcMaximum();
+        that.updateUI();
+    }
+
+    /**
+     * Set the Maximum Label
+     *
+     * @param max
+     */
+    public void setMaximumLabel(double max) {
+        maximumLabel.setText(Double.toString(max));
+    }
+
+    /**
+     * Get the name of the Graph.
+     *
+     * @return the name of the Graph
+     */
+    public String getGraphName() {
+        return this.graphName;
+    }
+
+    /**
+     * Calls the addValue function of the sGraph
+     */
+    public void addValues() {
+        sGraph.addValues();
+    }
+
+    /**
+     * Calls the calcMaximum function of the sGraph
+     */
+    public void calcMaximum() {
+        sGraph.calcMaximum();
+    }
+
+    public StatisticGraph getStatGraph() {
+        return sGraph;
+    }
+
+    public void setStatisticGraph(StatisticGraph sG) {
+        this.sGraph = sG;
+    }
+
+    /**
+     * Reset the Graph. Delete all calculated values.
+     */
+    public void resetGraph() {
+        sGraph.resetGraph();
+    }
+
+    /**
+     * Returns the Legend Panel.
+     *
+     * @return legendPanel
+     */
+    public JPanel getLegendPanel() {
+        return legendPanel;
+    }
 
 }