瀏覽代碼

Merge branch 'master' of https://git.tk.informatik.tu-darmstadt.de/scm-ssi-student-hostagev2

Alexander Brakowski 10 年之前
父節點
當前提交
7f0fc35177

+ 10 - 0
res/layout/fragment_record_detail.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:color/transparent"
+    >
+
+
+</RelativeLayout>

+ 2 - 2
res/layout/fragment_statistics.xml

@@ -86,9 +86,9 @@
             android:layout_height="wrap_content"
             android:id="@+id/FilterButton"
             android:src="@drawable/ic_filter"
-            android:layout_alignParentTop="true"
             android:visibility="invisible"
-            />
+            android:layout_alignParentTop="true"
+            android:layout_toLeftOf="@+id/plot_data_button" />
 
         <ImageButton
             style="@android:style/Widget.DeviceDefault.ActionButton.Overflow"

+ 1 - 1
src/com/echo/holographlibrary/BarGraph.java

@@ -43,7 +43,7 @@ import java.util.ArrayList;
 
 public class BarGraph extends View {
 
-	private final static int VALUE_FONT_SIZE = 23, AXIS_LABEL_FONT_SIZE = 15;
+	private final static int VALUE_FONT_SIZE = 23, AXIS_LABEL_FONT_SIZE = 12;
 	
     private ArrayList<Bar> mBars = new ArrayList<Bar>();
     private Paint mPaint = new Paint();

+ 251 - 123
src/com/echo/holographlibrary/LineGraph.java

@@ -42,11 +42,18 @@ import android.view.View;
 import java.util.ArrayList;
 
 public class LineGraph extends View {
-	
-	private ArrayList<Line> lines = new ArrayList<Line>();
+
+    public interface AxisDataConverter {
+        public String convertDataForX_Position(double x);
+        public String convertDataForY_Position(double y);
+    }
+
+    private final static int AXIS_LABEL_FONT_SIZE = 10;
+
+    private ArrayList<Line> lines = new ArrayList<Line>();
 	Paint paint = new Paint();
-	private float minY = 0, minX = 0;
-	private float maxY = 0, maxX = 0;
+	private double minY = 0, minX = 0;
+	private double maxY = 0, maxX = 0;
 	private double rangeYRatio = 0;
 	private double rangeXRatio = 0;
 	private boolean isMaxYUserSet = false;
@@ -56,14 +63,39 @@ public class LineGraph extends View {
 	private OnPointClickedListener listener;
 	private Bitmap fullImage;
 	private boolean shouldUpdate = false;
+
+    static final float bottomPadding = 40, topPadding = 10;
+    static final float rightPadding = 10;
+    static final float leftPadding = 50;
+    static final float sidePadding = rightPadding + leftPadding;
+
+    private float xAxisStep = 4;
+    private float yAxisStep = 4;
+
+    private AxisDataConverter converter;
+
+    private Context mContext;
+
+    public void setxAxisStep(float step){
+        this.xAxisStep = step;
+    }
+    public void setYAxisStep(float step){
+        this.yAxisStep = step;
+    }
+
+    public void setConverter(AxisDataConverter conv){
+        this.converter = conv;
+    }
 	
 	public LineGraph(Context context){
 		super(context);
+        this.mContext = context;
         this.setWillNotDraw(false);
     }
 	
 	public LineGraph(Context context, AttributeSet attrs) {
 		super(context, attrs);
+        this.mContext = context;
         this.setWillNotDraw(false);
     }
 	public void setMinY(float minY){
@@ -172,13 +204,15 @@ public class LineGraph extends View {
 	}
 	
 	public void resetYLimits(){
-		float range = getMaxY() - getMinY();
+        double range = getMaxY() - getMinY();
 		setRangeY(getMinY()-range*getRangeYRatio(), getMaxY()+range*getRangeYRatio());
-	}
+        isMaxYUserSet = false;
+    }
 	public void resetXLimits(){
-		float range = getMaxX() - getMinX();
+        double range = getMaxX() - getMinX();
 		setRangeX(getMinX()-range*getRangeXRatio(), getMaxX()+range*getRangeXRatio());
-	}
+        isMaxXUserSet = false;
+    }
 	public void resetLimits() {
 		resetYLimits();
 		resetXLimits();
@@ -209,21 +243,24 @@ public class LineGraph extends View {
 		maxY = max;
 		isMaxYUserSet = true;
 	}
-	private void setRangeY(double min, double max){
-		minY = (float)min;
-		maxY = (float)max;
-		isMaxXUserSet = true;
+	public void setRangeY(double min, double max){
+		minY = min;
+		maxY = max;
+		isMaxYUserSet = true;
 	}
 	public void setRangeX(float min, float max) {
 		minX = min;
 		maxX = max;
-	}
-	private void setRangeX(double min, double max){
-		minX = (float)min;
-		maxX = (float)max;
-	}
-	public float getMaxY(){
-		float max = lines.get(0).getPoint(0).getY();
+        isMaxXUserSet = true;
+    }
+	public void setRangeX(double min, double max){
+		minX = min;
+		maxX = max;
+        isMaxXUserSet = true;
+    }
+	public double getMaxY(){
+        if (isMaxYUserSet)return maxY;
+        double max = lines.get(0).getPoint(0).getY();
 		for (Line line : lines){
 			for (LinePoint point : line.getPoints()){
 				max = point.getY() > max ? point.getY() : max;
@@ -233,8 +270,9 @@ public class LineGraph extends View {
 		return maxY;	
 	}
 
-	public float getMinY(){
-		float min = lines.get(0).getPoint(0).getY();
+	public double getMinY(){
+        if (isMaxYUserSet)return minY;
+        double min = lines.get(0).getPoint(0).getY();
 		for (Line line : lines){
 			for (LinePoint point : line.getPoints()){
 				min = point.getY() < min ? point.getY() : min;
@@ -243,16 +281,21 @@ public class LineGraph extends View {
 		minY = min;
 		return minY;
 	}
-	public float getMinLimY(){
+	public double getMinLimY(){
 		return minY;
 	}
-	public float getMaxLimY(){
+	public double getMaxLimY(){
 		return maxY;
 	}
-	public float getMinLimX(){
-		return minX;
+	public double getMinLimX(){
+        if (isMaxXUserSet) {
+            return minX;
+        }
+        else {
+            return getMinX();
+        }
 	}
-	public float getMaxLimX(){
+	public double getMaxLimX(){
 		if (isMaxXUserSet) {
 			return maxX;
 		}
@@ -260,22 +303,22 @@ public class LineGraph extends View {
 			return getMaxX();
 		}
 	}
-	public float getMaxX(){
-		float max = lines.size() > 0 ? lines.get(0).getPoint(0).getX() : 0;
+	public double getMaxX(){
+        double max = lines.size() > 0 ? lines.get(0).getPoint(0).getX() : 0;
 		for (Line line : lines){
 			for (LinePoint point : line.getPoints()){
-				max = point.getX() > max ? point.getX() : max;
+				max =Math.max(point.getX(), max);// point.getX() > max ? point.getX() : max;
 			}
 		}
 		maxX = max;
 		return maxX;
 		
 	}
-	public float getMinX(){
-		float min = lines.size() > 0 ? lines.get(0).getPoint(0).getX() : 0;
+	public double getMinX(){
+        double min = lines.size() > 0 ? lines.get(0).getPoint(0).getX() : 0;
 		for (Line line : lines){
 			for (LinePoint point : line.getPoints()){
-				min = point.getX() < min ? point.getX() : min;
+				min =Math.min(point.getX(), min);// point.getX() < min ? point.getX() : min;
 			}
 		}
 		minX = min;
@@ -283,7 +326,14 @@ public class LineGraph extends View {
 	}
 	
 
-
+    private String getX_AxisTitle(double x){
+        if (this.converter == null)return "" + (long)x;
+        return this.converter.convertDataForX_Position(x);
+    }
+    private String getY_AxisTitle(double y){
+        if (this.converter == null)return "" + (long)y;
+        return this.converter.convertDataForY_Position(y);
+    }
 	 
 	public void onDraw(Canvas ca) {
         super.onDraw(ca);
@@ -295,91 +345,26 @@ public class LineGraph extends View {
 			paint.reset();
 			Path path = new Path();
 
-			float bottomPadding = 10, topPadding = 10;
-			float sidePadding = 10;
+
 			float usableHeight = getHeight() - bottomPadding - topPadding;
 			float usableWidth = getWidth() - 2*sidePadding;
 
-			float maxY = getMaxLimY();
-			float minY = getMinLimY();
-			float maxX = getMaxLimX();
-			float minX = getMinLimX();
+            double maxY = getMaxLimY();
+            double minY = getMinLimY();
+            double maxX = getMaxLimX();
+            double minX = getMinLimX();
 
-	        
-			int lineCount = 0;
-			for (Line line : lines){
-				int count = 0;
-				float firstXPixels = 0, lastXPixels = 0, newYPixels = 0;
-				float lastYPixels = 0, newXPixels = 0;
-				
-				if (lineCount == lineToFill){
-					paint.setColor(Color.BLACK);
-					paint.setAlpha(30);
-					paint.setStrokeWidth(2);
-					for (int i = 10; i-getWidth() < getHeight(); i = i+20){
-						canvas.drawLine(i, getHeight()-bottomPadding, 0, getHeight()-bottomPadding-i, paint);
-					}
-					
-					paint.reset();
-					
-					paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR));
-					for (LinePoint p : line.getPoints()){
-						float yPercent = (p.getY()-minY)/(maxY - minY);
-						float xPercent = (p.getX()-minX)/(maxX - minX);
-						if (count == 0){
-							lastXPixels = sidePadding + (xPercent*usableWidth);
-							lastYPixels = getHeight() - bottomPadding - (usableHeight*yPercent);
-							firstXPixels = lastXPixels;
-							path.moveTo(lastXPixels, lastYPixels);
-						} else {
-							newXPixels = sidePadding + (xPercent*usableWidth);
-							newYPixels = getHeight() - bottomPadding - (usableHeight*yPercent);
-							path.lineTo(newXPixels, newYPixels);
-							Path pa = new Path();
-							pa.moveTo(lastXPixels, lastYPixels);
-							pa.lineTo(newXPixels, newYPixels);
-							pa.lineTo(newXPixels, 0);
-							pa.lineTo(lastXPixels, 0);
-							pa.close();
-							canvas.drawPath(pa, paint);
-							lastXPixels = newXPixels;
-							lastYPixels = newYPixels;
-						}
-						count++;
-					}
-					
-					path.reset();
-					
-					path.moveTo(0, getHeight()-bottomPadding);
-					path.lineTo(sidePadding, getHeight()-bottomPadding);
-					path.lineTo(sidePadding, 0);
-					path.lineTo(0, 0);
-					path.close();
-					canvas.drawPath(path, paint);
-					
-					path.reset();
-					
-					path.moveTo(getWidth(), getHeight()-bottomPadding);
-					path.lineTo(getWidth()-sidePadding, getHeight()-bottomPadding);
-					path.lineTo(getWidth()-sidePadding, 0);
-					path.lineTo(getWidth(), 0);
-					path.close();
-					
-					canvas.drawPath(path, paint);
-					
-				}
-				
-				lineCount++;
-			}
-			
-			paint.reset();
-			
-			paint.setColor(Color.BLACK);
-			paint.setAlpha(50);
-			paint.setAntiAlias(true);
-			canvas.drawLine(sidePadding, getHeight() - bottomPadding, getWidth()-sidePadding, getHeight()-bottomPadding, paint);
-			paint.setAlpha(255);
-			
+
+	        // DRAW THE BACKGROUND
+            //this.drawBackground(canvas);
+
+            // DRAW THE AXIS
+            this.drawAxis(canvas);
+
+
+            paint.reset();
+
+            // DRAW LINES
 			for (Line line : lines){
 				int count = 0;
 				float lastXPixels = 0, newYPixels = 0;
@@ -389,8 +374,8 @@ public class LineGraph extends View {
 				paint.setStrokeWidth(getStrokeWidth(line));
 				
 				for (LinePoint p : line.getPoints()){
-					float yPercent = (p.getY()-minY)/(maxY - minY);
-					float xPercent = (p.getX()-minX)/(maxX - minX);
+                    float yPercent =(float) ((p.getY()-minY)/(maxY - minY));
+                    float xPercent = (float)((p.getX()-minX)/(maxX - minX));
 					if (count == 0){
 						lastXPixels = sidePadding + (xPercent*usableWidth);
 						lastYPixels = getHeight() - bottomPadding - (usableHeight*yPercent);
@@ -407,7 +392,7 @@ public class LineGraph extends View {
 			
 			
 			int pointCount = 0;
-			
+			// DRAW POINTS
 			for (Line line : lines){
 
 				paint.setColor(line.getColor());
@@ -416,10 +401,10 @@ public class LineGraph extends View {
 				
 				if (line.isShowingPoints()){
 					for (LinePoint p : line.getPoints()){
-						float yPercent = (p.getY()-minY)/(maxY - minY);
-						float xPercent = (p.getX()-minX)/(maxX - minX);
+                        float yPercent =(float) ((p.getY()-minY)/(maxY - minY));
+						float xPercent =(float) ((p.getX()-minX)/(maxX - minX));
 						float xPixels = sidePadding + (xPercent*usableWidth);
-						float yPixels = getHeight() - bottomPadding - (usableHeight*yPercent);
+                        float yPixels = getHeight() - bottomPadding - (usableHeight*yPercent);
 
 						int outerRadius;
 						if (line.isUsingDips()) {
@@ -431,12 +416,12 @@ public class LineGraph extends View {
 						int innerRadius = outerRadius / 2;
 
 						paint.setColor(p.getColor());
-						canvas.drawCircle(xPixels, yPixels, outerRadius, paint);
+						canvas.drawCircle(xPixels,(float) yPixels, outerRadius, paint);
 						paint.setColor(Color.WHITE);
-						canvas.drawCircle(xPixels, yPixels, innerRadius, paint);
+						canvas.drawCircle(xPixels,(float) yPixels, innerRadius, paint);
 						
 						Path path2 = new Path();
-						path2.addCircle(xPixels, yPixels, 30, Direction.CW);
+						path2.addCircle(xPixels,(float) yPixels, 30, Direction.CW);
 						p.setPath(path2);
 						p.setRegion(new Region((int)(xPixels-30), (int)(yPixels-30), (int)(xPixels+30), (int)(yPixels+30)));
 						
@@ -460,6 +445,149 @@ public class LineGraph extends View {
 		
 	}
 
+    private void drawAxis(Canvas canvas){
+        paint.reset();
+
+        double maxX = getMaxLimX();
+        double minX = getMinLimX();
+
+        float usableWidth = getWidth() - 2*sidePadding;
+        float usableHeight = getHeight() - bottomPadding - topPadding;
+
+        float yPixels = getHeight() - (bottomPadding*3/5);
+
+        // DRAW SEPERATOR
+        paint.setColor(Color.BLACK);
+        paint.setAlpha(50);
+        paint.setAntiAlias(true);
+        // x Axis
+        canvas.drawLine(leftPadding ,yPixels, getWidth()-sidePadding, yPixels, paint);
+        // y Axis
+        canvas.drawLine(leftPadding ,topPadding, leftPadding, yPixels, paint);
+
+        paint.setAlpha(255);
+        this.paint.setTextSize(AXIS_LABEL_FONT_SIZE * mContext.getResources().getDisplayMetrics().scaledDensity);
+
+        // Draw y-axis label text
+        //double skippedValue = (maxY - minY ) / (Math.max(1., yAxisStep));
+        double step = Math.max(1., (maxY - minY) / (Math.max(1., yAxisStep)));
+
+        for (double y = minY; y <= maxY; y+=step){
+            double yPercent = (y-minY)/(maxY - minY);
+
+            double newYPixels = topPadding + (yPercent*usableHeight);
+            canvas.drawLine((float)leftPadding,(float)newYPixels,(float)leftPadding-5.f,(float)newYPixels, paint);
+            String title = this.getY_AxisTitle(maxY - y);
+            float textwidth = (this.paint.measureText(title));
+            canvas.drawText(title, 5.f ,(float)newYPixels + (textwidth/2), this.paint);
+
+            //value+=skippedValue;
+        }
+
+        // Draw x-axis label text
+        //value = minX;
+        //skippedValue = (maxX - minX ) / (Math.max(1,xAxisStep));
+        step = Math.max(1, (maxX - minX) / (Math.max(1, xAxisStep)));
+
+        for (double x = minX; x <= maxX; x+=step){
+            double xPercent = (x-minX)/(maxX - minX);
+
+            double newXPixels = sidePadding + (xPercent*usableWidth);
+            canvas.drawLine((float)newXPixels,(float) yPixels + 5,(float) newXPixels,(float) yPixels, paint);
+            String title = this.getX_AxisTitle(x);
+            float textwidth = (this.paint.measureText(title));
+            //this.paint.setTextSize(AXIS_LABEL_FONT_SIZE * mContext.getResources().getDisplayMetrics().scaledDensity);
+            canvas.drawText(title,(float) newXPixels - (textwidth/2),(float) yPixels + (bottomPadding / 2), this.paint);
+
+            //value+=skippedValue;
+        }
+        paint.reset();
+    }
+
+    private void drawBackground(Canvas canvas){
+
+        paint.reset();
+
+
+        float usableHeight = getHeight() - bottomPadding - topPadding;
+        float usableWidth = getWidth() - 2*sidePadding;
+
+        double maxY = getMaxLimY();
+        double minY = getMinLimY();
+        double maxX = getMaxLimX();
+        double minX = getMinLimX();
+
+        Path path = new Path();
+
+        // DRAW THE BACKGROUND
+			int lineCount = 0;
+			for (Line line : lines){
+				int count = 0;
+				float firstXPixels = 0, lastXPixels = 0, newYPixels = 0;
+				float lastYPixels = 0, newXPixels = 0;
+
+				if (lineCount == lineToFill){
+					paint.setColor(Color.BLACK);
+					paint.setAlpha(30);
+					paint.setStrokeWidth(2);
+					for (int i = 10; i-getWidth() < getHeight(); i = i+20){
+						canvas.drawLine(i, getHeight()-bottomPadding, 0, getHeight()-bottomPadding-i, paint);
+					}
+
+
+					paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR));
+					for (LinePoint p : line.getPoints()){
+						float yPercent =(float) ((p.getY()-minY)/(maxY - minY));
+						float xPercent =(float) ((p.getX()-minX)/(maxX - minX));
+						if (count == 0){
+							lastXPixels = sidePadding + (xPercent*usableWidth);
+							lastYPixels = getHeight() - bottomPadding - (usableHeight*yPercent);
+							firstXPixels = lastXPixels;
+							path.moveTo(lastXPixels, lastYPixels);
+						} else {
+							newXPixels = sidePadding + (xPercent*usableWidth);
+							newYPixels = getHeight() - bottomPadding - (usableHeight*yPercent);
+							path.lineTo(newXPixels, newYPixels);
+							Path pa = new Path();
+							pa.moveTo(lastXPixels, lastYPixels);
+							pa.lineTo(newXPixels, newYPixels);
+							pa.lineTo(newXPixels, 0);
+							pa.lineTo(lastXPixels, 0);
+							pa.close();
+							canvas.drawPath(pa, paint);
+							lastXPixels = newXPixels;
+							lastYPixels = newYPixels;
+						}
+						count++;
+					}
+
+					path.reset();
+
+					path.moveTo(0, getHeight()-bottomPadding);
+					path.lineTo(sidePadding, getHeight()-bottomPadding);
+					path.lineTo(sidePadding, 0);
+					path.lineTo(0, 0);
+					path.close();
+					canvas.drawPath(path, paint);
+
+					path.reset();
+
+					path.moveTo(getWidth(), getHeight()-bottomPadding);
+					path.lineTo(getWidth()-sidePadding, getHeight()-bottomPadding);
+					path.lineTo(getWidth()-sidePadding, 0);
+					path.lineTo(getWidth(), 0);
+					path.close();
+
+					canvas.drawPath(path, paint);
+
+				}
+
+				lineCount++;
+			}
+
+        this.paint.reset();
+    }
+
 	private int getStrokeWidth(Line line) {
 		int strokeWidth;
 		if (line.isUsingDips()) {

+ 8 - 8
src/com/echo/holographlibrary/LinePoint.java

@@ -28,8 +28,8 @@ import android.graphics.Path;
 import android.graphics.Region;
 
 public class LinePoint {
-	private float x = 0;
-	private float y = 0;
+	private double x = 0;
+	private double y = 0;
 	private Path path;
 	private Region region;
     private Integer color;
@@ -38,20 +38,20 @@ public class LinePoint {
     }
 
 	public LinePoint(double x, double y){
-		this.x = (float)x;
-		this.y = (float)y;
+		this.x = x;
+		this.y = y;
 	}
 	public LinePoint(float x, float y){
 		this.x = x;
 		this.y = y;
 	}
-	public float getX() {
+	public double getX() {
 		return x;
 	}
 	public void setX(float x) {
 		this.x = x;
 	}
-	public float getY() {
+	public double getY() {
 		return y;
 	}
 	public void setY(float y) {
@@ -59,11 +59,11 @@ public class LinePoint {
 	}
 	
 	public void setX(double x){
-		this.x = (float) x;
+		this.x =  x;
 	}
 	
 	public void setY(double y){
-		this.y = (float) y;
+		this.y =  y;
 	}
 	public Region getRegion() {
 		return region;

+ 84 - 5
src/com/echo/holographlibrary/PieGraph.java

@@ -30,17 +30,25 @@ import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Path.Direction;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Region;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
+import android.widget.TextView;
 
 import java.util.ArrayList;
 
 public class PieGraph extends View {
 
-	private ArrayList<PieSlice> slices = new ArrayList<PieSlice>();
+    private final static int TITLE_FONT_SIZE = 14;
+    private final static int SUBTITLE_FONT_SIZE = 30;
+
+    static final String ALL_TITLE = "All";
+
+
+    private ArrayList<PieSlice> slices = new ArrayList<PieSlice>();
 	private Paint paint = new Paint();
 	private Path path = new Path();
 	
@@ -49,21 +57,30 @@ public class PieGraph extends View {
 	private OnSliceClickedListener listener;
 	
 	private boolean drawCompleted = false;
+
+    private TextView titleTextView;
+    private TextView subtitleTextView;
+
+    private String title;
+    private String subtitle;
+
+    private Context mContext;
 	
 	
 	public PieGraph(Context context) {
 		super(context);
+        this.mContext = context;
 		thickness = (int) (25f * context.getResources().getDisplayMetrics().density);
         this.setWillNotDraw(false);
 	}
 	
 	public PieGraph(Context context, AttributeSet attrs) {
 		super(context, attrs);
+        this.mContext = context;
 		thickness = (int) (25f * context.getResources().getDisplayMetrics().density);
         this.setWillNotDraw(false);
     }
 
-
     public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
 
@@ -107,7 +124,7 @@ public class PieGraph extends View {
 			
 			if (indexSelected == count && listener != null){
 				path.reset();
-				paint.setColor(slice.getColor());
+				//paint.setColor(slice.getColor());
 				paint.setColor(Color.parseColor("#33B5E5"));
 				paint.setAlpha(100);
 				
@@ -127,10 +144,60 @@ public class PieGraph extends View {
 			
 			count++;
 		}
+
+
+        this.drawTitle(canvas);
+        this.drawSubtitle(canvas);
 		
 		drawCompleted = true;
 		
 	}
+
+    private void drawTitle(Canvas canvas){
+        String title = this.title;
+
+        if (title != null && title.length() != 0){
+            this.paint.reset();
+            paint.setColor(Color.BLACK);
+            paint.setAlpha(50);
+            paint.setAntiAlias(true);
+            paint.setAlpha(255);
+
+            this.paint.setTextSize(TITLE_FONT_SIZE * mContext.getResources().getDisplayMetrics().scaledDensity);
+
+            int yCenter = this.getHeight() / 2;
+            int xCenter = this.getWidth() / 2;
+
+            float textwidth = (this.paint.measureText(title));
+            Rect bounds = new Rect();
+            this.paint.getTextBounds(title,0,title.length(), bounds);
+            canvas.drawText(title,xCenter - (textwidth / 2),yCenter - bounds.height(), this.paint);
+
+            this.paint.reset();
+        }
+    }
+    private void drawSubtitle(Canvas canvas){
+        String title = this.subtitle;
+        if (title != null && title.length() != 0){
+            this.paint.reset();
+            paint.setColor(Color.BLACK);
+            paint.setAlpha(50);
+            paint.setAntiAlias(true);
+            paint.setAlpha(255);
+
+            this.paint.setTextSize(SUBTITLE_FONT_SIZE * mContext.getResources().getDisplayMetrics().scaledDensity);
+
+            int yCenter = this.getHeight() / 2;
+            int xCenter = this.getWidth() / 2;
+
+            float textwidth = (this.paint.measureText(title));
+            Rect bounds = new Rect();
+            this.paint.getTextBounds(title,0,title.length(), bounds);
+            canvas.drawText(title,xCenter - (textwidth / 2),yCenter + bounds.height(), this.paint);
+
+            this.paint.reset();
+        }
+    }
 	
 	@Override
 	public boolean onTouchEvent(MotionEvent event) {
@@ -147,6 +214,8 @@ public class PieGraph extends View {
 				r.setPath(slice.getPath(), slice.getRegion());
 				if (r.contains((int)point.x,(int) point.y) && event.getAction() == MotionEvent.ACTION_DOWN){
 					indexSelected = count;
+                    this.title = slice.getTitle();
+                    this.subtitle = "" + (long) slice.getValue();
 				} else if (event.getAction() == MotionEvent.ACTION_UP){
 					if (r.contains((int)point.x,(int) point.y) && listener != null){
 						if (indexSelected > -1){
@@ -156,8 +225,9 @@ public class PieGraph extends View {
 					}
 					
 				}
-				else if(event.getAction() == MotionEvent.ACTION_CANCEL)
-					indexSelected = -1;
+				else if(event.getAction() == MotionEvent.ACTION_CANCEL) {
+                    indexSelected = -1;
+                }
 				count++;
 			}
 			
@@ -182,6 +252,12 @@ public class PieGraph extends View {
 	}
 	public void addSlice(PieSlice slice) {
 		this.slices.add(slice);
+        long countedValue = 0;
+        for (PieSlice s : this.slices){
+            countedValue+=s.getValue();
+        }
+        this.title = ALL_TITLE;
+        this.subtitle = "" + countedValue;
 		postInvalidate();
 	}
 	public void setOnSliceClickedListener(OnSliceClickedListener listener) {
@@ -200,6 +276,9 @@ public class PieGraph extends View {
 		for (int i = slices.size()-1; i >= 0; i--){
 			slices.remove(i);
 		}
+        this.title = "";
+        this.subtitle = "";
+
 		postInvalidate();
 	}
 

+ 37 - 3
src/de/tudarmstadt/informatik/hostage/logging/UglyDbHelper.java

@@ -172,9 +172,12 @@ public class UglyDbHelper extends SQLiteOpenHelper {
 			selectQuery = selectQuery + filter.getProtocolsQueryStatement(TABLE_ATTACK_INFO, KEY_PROTOCOL);
 		}
 
-
-		// ORDERED BY TIME
-		selectQuery = selectQuery + " ORDER BY " + filter.getSorttype();
+        if (filter.getSorttype() == LogFilter.SortType.timestamp){
+            //DESC
+            selectQuery = selectQuery + " ORDER BY " + filter.getSorttype() + " DESC";
+        } else {
+            selectQuery = selectQuery + " ORDER BY " + filter.getSorttype();
+        }
 		System.out.println(selectQuery);
 		SQLiteDatabase db = this.getReadableDatabase();
 		Cursor cursor = db.rawQuery(selectQuery, null);
@@ -209,6 +212,37 @@ public class UglyDbHelper extends SQLiteOpenHelper {
 		return this.getUniqueDataEntryForKeyType(KEY_SSID, TABLE_BSSIDS);
 	}
 
+    public ArrayList<String> getUniqueESSIDRecordsForProtocol(String protocol){
+        return this.getUniqueIDForProtocol(KEY_SSID, protocol);
+    }
+    public ArrayList<String> getUniqueBSSIDRecordsForProtocol(String protocol){
+        return this.getUniqueIDForProtocol(KEY_BSSID, protocol);
+    }
+
+    private ArrayList<String> getUniqueIDForProtocol(String id, String protocol){
+        ArrayList<String> recordList = new ArrayList<String>();
+        String selectQuery = "SELECT DISTINCT " + id + " FROM " + TABLE_ATTACK_INFO + " JOIN " + TABLE_BSSIDS + " USING "+ "(" + id + ") " + " WHERE " + TABLE_ATTACK_INFO + "."+ KEY_PROTOCOL + " = " + "'" + protocol + "'"+ " ORDER BY " + id; // " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN " + TABLE_BSSIDS + " NATURAL JOIN " + TABLE_PORTS +
+
+
+        // ORDERED BY TIME
+        System.out.println(selectQuery);
+        SQLiteDatabase db = this.getReadableDatabase();
+        Cursor cursor = db.rawQuery(selectQuery, null);
+
+        // looping through all rows and adding to list
+        if (cursor.moveToFirst()) {
+            do {
+                String record = cursor.getString(0);
+                recordList.add(record);
+            } while (cursor.moveToNext());
+        }
+        cursor.close();
+
+        // return record list
+        db.close();
+        return recordList;
+    }
+
 	/**
 	 * Gets all non duplicate Data Entry For a specific KeyType ( e.g. BSSIDs).
 	 * @return A ArrayList with received Records.

+ 17 - 14
src/de/tudarmstadt/informatik/hostage/ui2/dialog/DateTimeDialogFragment.java

@@ -1,14 +1,5 @@
 package de.tudarmstadt.informatik.hostage.ui2.dialog;
 
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-
-import de.tudarmstadt.informatik.hostage.R;
-import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
-import de.tudarmstadt.informatik.hostage.ui2.dialog.ChecklistDialog.ChecklistDialogListener;
-
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -24,6 +15,13 @@ import android.widget.DatePicker.OnDateChangedListener;
 import android.widget.TimePicker;
 import android.widget.TimePicker.OnTimeChangedListener;
 
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+
+import de.tudarmstadt.informatik.hostage.R;
+import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
+
 @SuppressLint("ValidFragment")
 public class DateTimeDialogFragment extends DialogFragment implements OnDateChangedListener, OnTimeChangedListener {
     // Define constants for date-time picker.
@@ -124,15 +122,20 @@ public class DateTimeDialogFragment extends DialogFragment implements OnDateChan
     }
     private DateTimeDialogFragmentListener mListener;
 
+    public void setDateChangeListener(DateTimeDialogFragmentListener listener){
+        this.mListener = listener;
+    }
+
     @Override
     public void onAttach(Activity activity) {
         super.onAttach(activity);
         try {
-            
-            if (activity.getClass().equals(MainActivity.class)){
-            	mListener = (DateTimeDialogFragmentListener) (((MainActivity)activity).getDisplayedFragment());
-            } else {
-            	mListener = (DateTimeDialogFragmentListener) activity;
+            if (this.mListener == null){
+                if (activity.getClass().equals(MainActivity.class)){
+                    mListener = (DateTimeDialogFragmentListener) (((MainActivity)activity).getDisplayedFragment());
+                } else {
+                    mListener = (DateTimeDialogFragmentListener) activity;
+                }
             }
         } catch (ClassCastException e) {
             throw new ClassCastException(activity.toString()

+ 149 - 0
src/de/tudarmstadt/informatik/hostage/ui2/fragment/RecordDetailFragment.java

@@ -0,0 +1,149 @@
+package de.tudarmstadt.informatik.hostage.ui2.fragment;
+
+import android.annotation.SuppressLint;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import de.tudarmstadt.informatik.hostage.R;
+import de.tudarmstadt.informatik.hostage.logging.Record;
+import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
+
+/**
+ * Created by Julien on 02.03.14.
+ */
+public class RecordDetailFragment extends Fragment {
+
+    private class Location{
+        private double longitude;
+        private double latitude;
+        private float accuracy;
+
+        public double getLatitude() {
+            return latitude;
+        }
+        public void setLatitude(double latitude) {
+            this.latitude = latitude;
+        }
+        public float getAccuracy() {
+            return accuracy;
+        }
+        public void setAccuracy(float accuracy) {
+            this.accuracy = accuracy;
+        }
+        public double getLongitude(){
+            return this.longitude;
+        }
+        public void setLongitude(double longitude){
+            this.longitude = longitude;
+        }
+
+        public Location(){
+            super();
+        }
+        public Location(double latitude, double longitude, float accuracy){
+            super();
+            this.latitude = latitude;
+            this.longitude = longitude;
+            this.accuracy = accuracy;
+        }
+    }
+
+    private Record record;
+    private UglyDbHelper dbh;
+    private View rootView;
+
+    public void setRecord(Record rec){
+        this.record = rec;
+    }
+    public Record getRecord(){
+        return this.record;
+    }
+
+    public int getLayoutId(){
+        return R.layout.fragment_record_detail;
+    }
+
+
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setHasOptionsMenu(true);
+    }
+
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        super.onCreateView(inflater, container, savedInstanceState);
+
+        this.dbh = new UglyDbHelper(this.getActivity().getBaseContext());
+
+        this.rootView = inflater.inflate(this.getLayoutId(), container, false);
+        this.configurateRootView(rootView);
+
+
+        return rootView;
+    }
+
+    public void onStart() {
+        super.onStart();
+
+    }
+
+    private void configurateRootView(View rootView) {
+        String protocol = this.record.getProtocol();
+        String type = "" + this.record.getType();
+        String externalIP = this.record.getExternalIP();
+        String localIP = this.record.getLocalIP();
+        String localPort = "" + this.record.getLocalPort();
+        String remoteIP = this.record.getRemoteIP();
+        String bssid = this.record.getBssid() ;
+        String essid = this.record.getSsid();
+        double latitude = this.record.getLatitude();
+        double longitude = this.record.getLongitude();
+        float accuracy =this.record.getAccuracy();
+
+        Location  location = new Location(latitude, longitude, accuracy);
+
+        String packet = this.record.getPacket();
+        String timeStamp = this.getDateAsString(this.record.getTimestamp());
+
+    }
+
+
+    /*****************************
+     *
+     *          Date Transform
+     *
+     * ***************************/
+
+
+    @SuppressLint("SimpleDateFormat")
+    private String getDateAsString(long timeStamp) {
+
+        try {
+            DateFormat sdf = new SimpleDateFormat("H:mm d.M.yy");
+            Date netDate = (new Date(timeStamp));
+            return sdf.format(netDate);
+        } catch (Exception ex) {
+            return "xx";
+        }
+    }
+
+
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+
+
+
+
+
+}

+ 54 - 31
src/de/tudarmstadt/informatik/hostage/ui2/fragment/RecordOverviewFragment.java

@@ -2,6 +2,8 @@ package de.tudarmstadt.informatik.hostage.ui2.fragment;
 
 import android.annotation.SuppressLint;
 import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
@@ -11,10 +13,8 @@ import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.AdapterView;
 import android.widget.ExpandableListView;
 import android.widget.ImageButton;
-import android.widget.Toast;
 
 import com.google.android.gms.maps.model.LatLng;
 
@@ -71,9 +71,17 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 
     private String sectionToOpen = "";
 
+    public void setFilter(LogFilter filter){
+        this.filter = filter;
+    }
+
 
     public RecordOverviewFragment(){}
 
+    public void setGroupKey(String key){
+        this.groupingKey = key;
+    }
+
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -104,7 +112,7 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 	    this.setShowFilterButton(!this.filter.isNotEditable());
 	    this.addRecordToDB();
 
-		View rootView = inflater.inflate(R.layout.fragment_record_list, container, false);
+		View rootView = inflater.inflate(this.getLayoutId(), container, false);
 		ExpandableListView mylist = (ExpandableListView) rootView.findViewById(R.id.loglistview);
 		this.expListView = mylist;
 		populateListViewFromDB(mylist);
@@ -138,6 +146,10 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 		return rootView;
 	 }
 
+    public int getLayoutId(){
+        return R.layout.fragment_record_list;
+    }
+
 
 
 	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
@@ -190,7 +202,11 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
     public void onStart() {
         super.onStart();
         //this.populateListViewFromDB(this.expListView);
-        this.setSectionToOpen(this.sectionToOpen);
+        if (this.expListView.getExpandableListAdapter().getGroupCount() == 1){
+            this.expListView.expandGroup(0);
+        } else {
+            this.setSectionToOpen(this.sectionToOpen);
+        }
     }
 
 	/*****************************
@@ -250,8 +266,11 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 
             ExpandableListItem item = new ExpandableListItem();
             item.setData(map);
+
             item.setId_Mapping(mapping);
 
+            item.setTag(val.getId());
+
             String groupID = this.getGroupValue(val);
 
             ArrayList<ExpandableListItem> items = sectionData.get(groupID);
@@ -269,6 +288,7 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
                 return s1.compareToIgnoreCase(s2);
             }
         });
+
         RecordListAdapter adapter = new RecordListAdapter(this.getApplicationContext(), groupTitle, sectionData);
 
         mylist.setAdapter(adapter);
@@ -294,35 +314,20 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 	}
 
 	private void registerListClickCallback(ExpandableListView mylist) {
+        mylist.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
+            @Override
+            public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i2, long l) {
+                RecordListAdapter adapter = (RecordListAdapter)expandableListView.getExpandableListAdapter();
 
-		mylist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-			public void onItemClick(AdapterView<?> parent, View viewClicked,
-					int position, long idInDB) {
-				UglyDbHelper dbh = new UglyDbHelper(getBaseContext());
-				Record rec = dbh.getRecord((int) idInDB);
-				String message = createInformationStringFromRecord(rec);
-				Toast.makeText(getApplicationContext(), message,
-						Toast.LENGTH_LONG).show();
-			}
+                ExpandableListItem item = (ExpandableListItem)adapter.getChild(i,i2);
 
-			private String createInformationStringFromRecord(Record rec) {
-				String message = "id: " + rec.getId() + "\n" + "attack_id: "
-						+ rec.getAttack_id() + "\n" + "protocol: "
-						+ rec.getProtocol() + "\n" + "type: " + rec.getType()
-						+ "\n" + "externalIP: " + rec.getExternalIP() + "\n"
-						+ "localIP: " + rec.getLocalIP() + "\n"
-						+ "local port: " + rec.getLocalPort() + "\n"
-						+ "remoteIP: " + rec.getRemoteIP() + "\n" + "BSSID: "
-						+ rec.getBssid() + "\n" + "SSID: " + rec.getSsid()
-						+ "\n" + "latitude: " + rec.getLatitude() + "\n"
-						+ "longitude: " + rec.getLongitude() + "\n"
-						+ "accuracy: " + rec.getAccuracy() + "\n" + "packet: "
-						+ rec.getPacket() + "\n"
-						+ getDateAsString(rec.getTimestamp()) + "";
-				return message;
-			}
+                UglyDbHelper dbh = new UglyDbHelper(getBaseContext());
+                Record rec = dbh.getRecord((int) item.getTag());
+                RecordOverviewFragment.this.pushRecordDetailViewForRecord(rec);
+                return true;
+            }
+        });
 
-		});
 	}
 
 
@@ -338,7 +343,7 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 	private String getDateAsString(long timeStamp) {
 
 		try {
-			DateFormat sdf = new SimpleDateFormat("H:mm  dd/MM/yyyy");
+			DateFormat sdf = new SimpleDateFormat("H:mm d.M.yy");
 			Date netDate = (new Date(timeStamp));
 			return sdf.format(netDate);
 		} catch (Exception ex) {
@@ -767,4 +772,22 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
     }
 
 
+    /*Navigation*/
+    private void pushRecordDetailViewForRecord(Record record){
+
+        FragmentManager fm = this.getActivity().getFragmentManager();
+
+        if (fm != null){
+            RecordDetailFragment newFragment = new RecordDetailFragment();
+            newFragment.setRecord(record);
+
+            FragmentTransaction transaction = fm.beginTransaction();
+            transaction.replace(R.id.content_frame, newFragment, newFragment.getTag());
+            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
+            transaction.addToBackStack(null);
+
+            transaction.commit();
+        }
+
+    }
 }

+ 450 - 138
src/de/tudarmstadt/informatik/hostage/ui2/fragment/StatisticsFragment.java

@@ -2,6 +2,8 @@ package de.tudarmstadt.informatik.hostage.ui2.fragment;
 
 import android.annotation.SuppressLint;
 import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Color;
@@ -38,24 +40,31 @@ import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
 import de.tudarmstadt.informatik.hostage.ui.LogFilter;
 import de.tudarmstadt.informatik.hostage.ui2.adapter.StatisticListAdapter;
 import de.tudarmstadt.informatik.hostage.ui2.dialog.ChecklistDialog;
+import de.tudarmstadt.informatik.hostage.ui2.dialog.DateTimeDialogFragment;
 import de.tudarmstadt.informatik.hostage.ui2.helper.ColorSequenceGenerator;
 import de.tudarmstadt.informatik.hostage.ui2.model.PlotComparisonItem;
 import de.tudarmstadt.informatik.hostage.ui2.popup.AbstractPopup;
 import de.tudarmstadt.informatik.hostage.ui2.popup.AbstractPopupItem;
 import de.tudarmstadt.informatik.hostage.ui2.popup.SimplePopupItem;
 import de.tudarmstadt.informatik.hostage.ui2.popup.SimplePopupTable;
+import de.tudarmstadt.informatik.hostage.ui2.popup.SplitPopupItem;
 
 /**
  * Created by Julien on 16.02.14.
  */
-public class StatisticsFragment extends Fragment implements ChecklistDialog.ChecklistDialogListener {
+public class StatisticsFragment extends Fragment implements ChecklistDialog.ChecklistDialogListener, DateTimeDialogFragment.DateTimeDialogFragmentListener {
 
     static final String FILTER_MENU_TITLE_BSSID = "BSSID";
     static final String FILTER_MENU_TITLE_ESSID = "ESSID";
-    static final String FILTER_MENU_TITLE_PROTOCOLS = "Protocol";
+    static final String FILTER_MENU_TITLE_PROTOCOLS = "Protocols";
+    static final String FILTER_MENU_TITLE_PROTOCOL = "Protocol";
     static final String FILTER_MENU_TITLE_TIMESTAMP_BELOW = "Latest";
     static final String FILTER_MENU_TITLE_TIMESTAMP_ABOVE = "Earliest";
 
+    static final String FILTER_MENU_TITLE_REMOVE = "Reset Filter";
+    static final String FILTER_MENU_POPUP_TITLE = "Filter by";
+
+
     static final String MENU_TITLE_PROTOCOLS = "Protocols";
     static final String MENU_TITLE_NETWORK = "Networks";
     static final String MENU_TITLE_ATTACKS = "Attacks";
@@ -178,7 +187,7 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         this.legendListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
-                StatisticsFragment.this.userTappedOnItem(i);
+                StatisticsFragment.this.userTappedOnLegendItem(i);
             }
         });
         this.rootView = rootView;
@@ -209,11 +218,10 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         ImageButton visualButton = (ImageButton) rootView.findViewById(R.id.plot_data_button);
         visualButton.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
-                StatisticsFragment.this.openPopupMenuOnView(v);
+                StatisticsFragment.this.openBarSelectionMenuOnView(v);
             }
         });
 
-        this.setTitle(this.selectedCompareData);
 
         ImageButton filterButton = this.getFilterButton();
         filterButton.setOnClickListener(new View.OnClickListener() {
@@ -221,6 +229,12 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
                 StatisticsFragment.this.openFilterMenuOnView(v);
             }
         });
+
+        if (this.currentPlotView instanceof BarGraph){
+            this.setTitle("" + this.getCurrentSelectedProtocol() + ": " +this.selectedCompareData);
+        } else {
+            this.setTitle(this.selectedCompareData);
+        }
     }
 
     public void setTitle(String title){
@@ -243,6 +257,12 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         super.onStart();
         this.actualiseCurrentPlot();
         this.currentPlotView.invalidate();
+
+        if (this.currentPlotView instanceof BarGraph){
+            this.setTitle("" + this.getCurrentSelectedProtocol() + ": " +this.selectedCompareData);
+        } else {
+            this.setTitle(this.selectedCompareData);
+        }
     }
 
     public void setChartType(ChartType type){
@@ -251,27 +271,29 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         if (this.currentPlotView != null){
             if (type == ChartType.PIE_CHART){
                 shouldChange = ! (this.currentPlotView instanceof PieGraph);
+                // SET FILTER BUTTON HIDDEN
+                ImageButton filterButton = this.getFilterButton();
+                if (filterButton != null) filterButton.setVisibility(View.GONE);
             } else {
                 if (this.pieGraph != null)
-                     this.pieGraph.setVisibility(View.INVISIBLE);
+                     this.pieGraph.setVisibility(View.GONE);
+                // SHOW FILTER BUTTON
+                ImageButton filterButton = this.getFilterButton();
+                if (filterButton != null) filterButton.setVisibility(View.VISIBLE);
             }
             if (type == ChartType.LINE_CHART){
                 shouldChange = ! (this.currentPlotView instanceof LineGraph);
             } else {
                 if (this.lineGraph != null)
-                     this.lineGraph.setVisibility(View.INVISIBLE);
+                     this.lineGraph.setVisibility(View.GONE);
             }
             if (type == ChartType.BAR_CHART){
                 shouldChange = ! (this.currentPlotView instanceof BarGraph);
-                // SHOW FILTER BUTTON
-                ImageButton filterButton = this.getFilterButton();
-                if (filterButton != null) filterButton.setVisibility(View.VISIBLE);
+
             } else {
                 if (this.barGraph != null)
-                    this.barGraph.setVisibility(View.INVISIBLE);
-                // SET FILTER BUTTON HIDDEN
-                ImageButton filterButton = this.getFilterButton();
-                if (filterButton != null) filterButton.setVisibility(View.INVISIBLE);
+                    this.barGraph.setVisibility(View.GONE);
+
             }
         }
         if (shouldChange){
@@ -302,7 +324,7 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     /*
     * MENU
     * */
-    private void openPopupMenuOnView(View anchorView){
+    private void openBarSelectionMenuOnView(View anchorView){
         SimplePopupTable visualiseMenu = new SimplePopupTable(this.getActivity(), new AbstractPopup.OnPopupItemClickListener() {
             public void onItemClick(Object ob) {
                 if (ob instanceof AbstractPopupItem){
@@ -317,7 +339,7 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
             SimplePopupItem item = new SimplePopupItem(this.getActivity());
             item.setTitle(title);
             item.setItemId(id);
-            item.setSelected(this.isFilterSetForTitle(title));
+            item.setSelected(false);
             visualiseMenu.addItem(item);
             id++;
         }
@@ -327,7 +349,10 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     private void userSelectMenuItem(AbstractPopupItem item){
         // OPEN A DIALOG TO SPECIFY THE VISUALISE DATA
         if (item.getTitle().equals(MENU_TITLE_PROTOCOLS)){
-            this.openProtocolDataDialog();
+            ChartType chartType = ChartType.PIE_CHART;
+            this.selectedCompareData = COMPARE_TITLE_AttacksPerProtocol;
+            this.setChartType(chartType);
+            this.setTitle(COMPARE_TITLE_AttacksPerProtocol);
         }
         if (item.getTitle().equals(MENU_TITLE_NETWORK)){
             this.openNetworkDataDialog();
@@ -373,6 +398,11 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         String title = dialog.getTitle();
         ArrayList<String> titles =dialog.getSelectedItemTitles();
 
+        if (title.equals(FILTER_MENU_TITLE_PROTOCOLS)){
+            this.filter.setProtocols(titles.size() == 0 ? this.protocolTitles() : titles);
+            this.actualiseCurrentPlot();
+            return;
+        }
         if (title.equals(FILTER_MENU_PROTOCOL_SINGLE_CHOICE_TITLE)){
             this.filter.setProtocols(titles);
             this.actualiseCurrentPlot();
@@ -380,6 +410,16 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
             this.setTitle(fragTitle);
             return;
         }
+        if (title.equals(FILTER_MENU_TITLE_ESSID)){
+            this.filter.setESSIDs(titles);
+            this.actualiseCurrentPlot();
+            return;
+        }
+        if (title.equals(FILTER_MENU_TITLE_BSSID)){
+            this.filter.setBSSIDs(titles);
+            this.actualiseCurrentPlot();
+            return;
+        }
 
         if (titles.size() != 0){
             String data = titles.get(0);
@@ -428,8 +468,8 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     }
     private ArrayList<String> getDialogNetworkDataTitle(){
         ArrayList<String> data = new ArrayList<String>();
-        data.add(COMPARE_TITLE_AttacksPerBSSID);
         data.add(COMPARE_TITLE_AttacksPerESSID);
+        data.add(COMPARE_TITLE_AttacksPerBSSID);
         return data;
     }
     private boolean[] selectedData(ArrayList<String> data){
@@ -445,6 +485,107 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     *
     * */
     private void openFilterMenuOnView(View anchor){
+        SimplePopupTable filterMenu = new SimplePopupTable(this.getActivity(), new AbstractPopup.OnPopupItemClickListener() {
+            public void onItemClick(Object ob) {
+                if (ob instanceof  AbstractPopupItem){
+                    AbstractPopupItem item = (AbstractPopupItem) ob;
+                    StatisticsFragment.this.onFilterMenuItemSelected(item);
+                }
+            }
+        });
+
+        filterMenu.setTitle(FILTER_MENU_POPUP_TITLE);
+        for(String title : StatisticsFragment.this.filterMenuTitles()){
+            AbstractPopupItem item = null;
+            if (title.equals(FILTER_MENU_TITLE_TIMESTAMP_BELOW)) continue;
+            if (title.equals(FILTER_MENU_TITLE_TIMESTAMP_ABOVE)){
+                item = new SplitPopupItem(this.getActivity());
+                item.setValue(SplitPopupItem.RIGHT_TITLE, FILTER_MENU_TITLE_TIMESTAMP_BELOW);
+                item.setValue(SplitPopupItem.LEFT_TITLE, FILTER_MENU_TITLE_TIMESTAMP_ABOVE);
+                if (this.filter.hasBelowTimestamp()){
+                    item.setValue(SplitPopupItem.RIGHT_SUBTITLE, this.getDateAsString(this.filter.belowTimestamp));
+                }
+                if (this.filter.hasAboveTimestamp()){
+                    item.setValue(SplitPopupItem.LEFT_SUBTITLE, this.getDateAsString(this.filter.aboveTimestamp));
+                }
+            } else {
+                item = new SimplePopupItem(this.getActivity());
+                item.setTitle(title);
+                ((SimplePopupItem)item).setSelected(this.isFilterSetForTitle(title));
+            }
+
+            filterMenu.addItem(item);
+        }
+        if (this.filter.isSet()){
+            AbstractPopupItem item = new SimplePopupItem(this.getActivity());
+            item.setTitle(FILTER_MENU_TITLE_REMOVE);
+            filterMenu.addItem(item);
+        }
+        filterMenu.showOnView(anchor);
+    }
+
+    private void onFilterMenuItemSelected(AbstractPopupItem item){
+        if (item instanceof SplitPopupItem){
+            SplitPopupItem sItem = (SplitPopupItem) item;
+            this.wasBelowTimePicker = sItem.wasRightTouch;
+            if (this.wasBelowTimePicker){
+                this.openTimestampToFilterDialog();
+            } else {
+                this.openTimestampFromFilterDialog();
+            }
+            return;
+        }
+        String title = item.getTitle();
+        if (title.equals(FILTER_MENU_TITLE_ESSID)){
+            this.openESSIDFilterDialog();
+        }
+        if (title.equals(FILTER_MENU_TITLE_BSSID)){
+            this.openBSSIDFilterDialog();
+        }
+        if (title.equals(FILTER_MENU_TITLE_PROTOCOL)){
+            this.openFilterDialogSelectProtocol();
+        }
+        if (title.equals(FILTER_MENU_TITLE_PROTOCOLS)){
+            this.openProtocolsFilterDialog();
+        }
+        if (title.equals(FILTER_MENU_TITLE_REMOVE)){
+            this.clearFilter();
+            this.actualiseCurrentPlot();
+        }
+    }
+
+    private ArrayList<String> filterMenuTitles(){
+        ArrayList<String> titles = new ArrayList<String>();
+        if (this.currentPlotView instanceof LineGraph){
+            titles.add(FILTER_MENU_TITLE_ESSID);
+            titles.add(FILTER_MENU_TITLE_PROTOCOLS);
+            titles.add(FILTER_MENU_TITLE_TIMESTAMP_ABOVE);
+            if (this.filter.hasESSIDs() || this.filter.hasATimestamp()){
+                titles.add(FILTER_MENU_TITLE_REMOVE);
+            }
+        } else {
+            titles.add(FILTER_MENU_TITLE_PROTOCOL);
+            String protocol = this.getCurrentSelectedProtocol();
+            if (protocol.length() > 0){
+                if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerBSSID)){
+                    titles.add(FILTER_MENU_TITLE_BSSID);
+                }
+                // DEFAULT
+                titles.add(FILTER_MENU_TITLE_ESSID);
+            }
+            titles.add(FILTER_MENU_TITLE_TIMESTAMP_ABOVE);
+            if (this.filter.hasProtocols() || this.filter.hasATimestamp() || this.filter.hasESSIDs() || this.filter.hasBSSIDs()){
+                titles.add(FILTER_MENU_TITLE_REMOVE);
+            }
+        }
+        return titles;
+    }
+
+    private void openProtocolsFilterDialog(){
+        ChecklistDialog newFragment = new ChecklistDialog(FILTER_MENU_TITLE_PROTOCOLS,this.protocolTitles(), this.selectedProtocols(), true , this);
+        newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_PROTOCOLS);
+    }
+    private void openFilterDialogSelectProtocol(){
         ArrayList<String> titles = this.protocolTitles();
         boolean[] selected = new boolean[titles.size()];
         int i = 0;
@@ -454,21 +595,97 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         }
         ChecklistDialog newFragment = new ChecklistDialog(FILTER_MENU_PROTOCOL_SINGLE_CHOICE_TITLE, titles, selected, false , this);
         newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_PROTOCOL_SINGLE_CHOICE_TITLE);
+    }
 
+    private void openESSIDFilterDialog(){
+        ChecklistDialog newFragment = new ChecklistDialog(FILTER_MENU_TITLE_ESSID, this.essids(), this.selectedESSIDs(), true , this);
+        newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_ESSID);
     }
 
+    private void openBSSIDFilterDialog(){
+        ChecklistDialog newFragment = new ChecklistDialog(FILTER_MENU_TITLE_BSSID, this.bssids(), this.selectedBSSIDs(), true , this);
+        newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_BSSID);
+    }
 
-    /**
-    *
-    * PLOT TOUCH HANDLING
-    *
-    * */
-    public void onSliceClick(int index){
-        this.userTappedOnItem(index);
+    private void openTimestampFromFilterDialog(){
+        this.wasBelowTimePicker = false;
+        DateTimeDialogFragment newFragment = new DateTimeDialogFragment(this.getActivity());
+        newFragment.setDateChangeListener(this);
+        newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_TIMESTAMP_ABOVE);
+
+        if (this.filter.aboveTimestamp != Long.MIN_VALUE)newFragment.setDate(this.filter.aboveTimestamp);
     }
-    public void onBarClick(int index){
-        this.userTappedOnItem(index);
+
+    private void openTimestampToFilterDialog(){
+        this.wasBelowTimePicker = true;
+        DateTimeDialogFragment newFragment = new DateTimeDialogFragment(this.getActivity());
+        newFragment.setDateChangeListener(this);
+        newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_TIMESTAMP_BELOW);
+        if (this.filter.belowTimestamp != Long.MAX_VALUE) newFragment.setDate(this.filter.belowTimestamp);
+    }
+
+    public ArrayList<String> essids(){
+        ArrayList<String> records;
+        if (this.currentPlotView instanceof BarGraph){
+            records = dbh.getUniqueESSIDRecordsForProtocol(this.getCurrentSelectedProtocol());
+        } else {
+            records = dbh.getUniqueESSIDRecords();
+        }
+        return records;
+    }
+    public boolean[] selectedESSIDs(){
+        ArrayList<String> essids = this.essids();
+        boolean[] selected = new boolean[essids.size()];
+
+        int i = 0;
+        for(String essid : essids){
+            selected[i] =(this.filter.getESSIDs().contains(essid));
+            i++;
+        }
+        return selected;
+    }
+
+    public ArrayList<String> bssids(){
+        ArrayList<String> records ;
+        if (this.currentPlotView instanceof BarGraph){
+            records = dbh.getUniqueBSSIDRecordsForProtocol(this.getCurrentSelectedProtocol());
+        } else {
+            records = dbh.getUniqueBSSIDRecords();
+        }
+        return records;
+    }
+    public boolean[] selectedBSSIDs(){
+        ArrayList<String> bssids = this.bssids();
+
+        boolean[] selected = new boolean[bssids.size()];
+
+        int i = 0;
+        for(String bssid : bssids){
+            selected[i] =(this.filter.getBSSIDs().contains(bssid));
+            i++;
+        }
+        return selected;
+    }
+
+    public void onDateTimePickerPositiveClick(DateTimeDialogFragment dialog) {
+        if(this.wasBelowTimePicker){
+            this.filter.setBelowTimestamp(dialog.getDate());
+        } else {
+            this.filter.setAboveTimestamp(dialog.getDate());
+        }
+        this.actualiseCurrentPlot();
     }
+
+    public void onDateTimePickerNegativeClick(DateTimeDialogFragment dialog) {
+        if(this.wasBelowTimePicker){
+            this.filter.setBelowTimestamp(Long.MAX_VALUE);
+        } else {
+            this.filter.setAboveTimestamp(Long.MIN_VALUE);
+        }
+        this.actualiseCurrentPlot();
+    }
+
+
     /*
     *
     *  PLOT TYPES
@@ -502,7 +719,7 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         if (this.barGraph == null) {
             this.barGraph = new BarGraph(this.getActivity());
             LinearLayout plotLayout = (LinearLayout) this.rootView.findViewById(R.id.plot_layout);
-            this.barGraph.setLayoutParams(new ViewGroup.LayoutParams(plotLayout.getWidth() - plotLayout.getPaddingLeft() - plotLayout.getPaddingRight(), plotLayout.getHeight() -  - plotLayout.getPaddingTop() - plotLayout.getPaddingBottom()));
+            this.barGraph.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT ));
             plotLayout.addView(this.barGraph);
             this.barGraph.setShowBarText(false);
             this.barGraph.setPopupImageID(R.drawable.popup_black);
@@ -545,23 +762,81 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         if (this.currentData == null){
             this.currentData = new ArrayList<PlotComparisonItem>();
         }
-        int index = 0;
 
         this.lineGraph.removeAllLines();
-        Line l = new Line();
-        l.setColor(this.getColor(0));
+        double rangeMax_Y = 0;
+        double rangeMin_Y = 0;
+
+        double rangeMax_X = 0;
+        double rangeMin_X = 0;
+
+        int count = 0;
+        for (PlotComparisonItem lineItem : this.currentData){
+            ArrayList<PlotComparisonItem> data = lineItem.getOtherData();
+            int index = 0;
+            Line l = new Line();
+            int lineColor = lineItem.getColor();
+            l.setColor(lineColor);
+
+            for (PlotComparisonItem pointItem : data){
+                LinePoint p = new LinePoint();
+                p.setX(pointItem.getValue1());
+                Double value2 = pointItem.getValue2();
+                p.setY(value2);
+                p.setColor(lineColor);
+                l.addPoint(p);
+                rangeMax_Y = Math.max(pointItem.getValue2(), rangeMax_Y);
+                rangeMax_X = Math.max(pointItem.getValue1(), rangeMax_X);
+
+                if (count != 0){
+                    rangeMin_Y = Math.min(pointItem.getValue2(), rangeMin_Y);
+                    rangeMin_X = Math.min(pointItem.getValue1(), rangeMin_X);
+                } else {
+                    rangeMin_Y = pointItem.getValue2();
+                    rangeMin_X = pointItem.getValue1();
+                }
+                index++;
+                count++;
+            }
+            this.lineGraph.addLine(l);
+        }
+        // add a bit more space
+        rangeMax_Y++;
+        rangeMin_Y--;
 
-        for (PlotComparisonItem item : this.currentData){
-            LinePoint p = new LinePoint();
-            p.setX(index);
-            Double value2 = (Double) item.getValue2();
-            p.setY(value2.floatValue());
-            p.setColor(item.getColor());
-            l.addPoint(p);
-            index++;
+        boolean shouldUseDate = this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerDate);
+        if (shouldUseDate){
+            this.lineGraph.resetXLimits();
+
+            if (this.filter.hasBelowTimestamp()){
+                rangeMax_X = Math.max(this.filter.belowTimestamp, rangeMax_X);
+            }
+            if (this.filter.hasAboveTimestamp()){
+                rangeMin_X = Math.min(this.filter.aboveTimestamp, rangeMin_X);
+            }
+
+            double stepRange = (rangeMax_X - rangeMin_X)/(60*60*24*1000);
+            this.lineGraph.setxAxisStep(Math.max(1, (float) Math.min(stepRange, 4)));
+
+            this.lineGraph.setRangeX(rangeMin_X  , rangeMax_X);
+
+            this.lineGraph.setConverter(new LineGraph.AxisDataConverter() {
+                @Override
+                public String convertDataForX_Position(double x) {
+                    return StatisticsFragment.this.getDateAsDayString((long)x);
+                }
+                @Override
+                public  String convertDataForY_Position(double y){
+                    return "" + (long)y;
+                }
+            });
+        } else {
+            this.lineGraph.setxAxisStep(12.f);
+            this.lineGraph.setRangeX(0, 24);
+            this.lineGraph.setConverter(null);
         }
-        this.lineGraph.addLine(l);
-        this.lineGraph.setRangeY(0, index);
+
+        this.lineGraph.setRangeY(rangeMin_Y, rangeMax_Y);
         this.lineGraph.setLineToFill(0);
         this.lineGraph.invalidate();
     }
@@ -597,7 +872,6 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         return this.dbh.getRecordsForFilter(this.filter);
     }
 
-
      public void actualiseCurrentPlot(){
          LinearLayout plotLayout = (LinearLayout) this.rootView.findViewById(R.id.plot_layout);
         View plot = this.currentPlotView;
@@ -605,25 +879,38 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
              this.currentPlotView = this.getPieGraphView();
              plot = this.currentPlotView;
          }
-        if (plot.getVisibility() == View.INVISIBLE) plot.setVisibility(View.VISIBLE);
+         if (plot.getParent() != null && !plot.getParent().equals(plotLayout)){
+             LinearLayout linLayout = (LinearLayout)plot.getParent();
+             linLayout.removeView(plot);
+             plot.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT ));
+             plotLayout.addView(plot);
+         }
+
+         if (plot.getVisibility() == View.GONE) plot.setVisibility(View.VISIBLE);
 
         if (plot instanceof PieGraph){
             PieGraph pie = (PieGraph) plot;
             this.setPieGraphData(pie);
+            // HIDE FILTER BUTTON
+            ImageButton filterButton = this.getFilterButton();
+            if (filterButton != null) filterButton.setVisibility(View.GONE);
         } else {
             if (this.pieGraph != null){
-                this.pieGraph.setVisibility(View.INVISIBLE);
+                this.pieGraph.setVisibility(View.GONE);
                 if (this.pieGraph.getParent() != null){
                     plotLayout.removeView(this.pieGraph);
                 }
             }
+            // SHOW FILTER BUTTON
+            ImageButton filterButton = this.getFilterButton();
+            if (filterButton != null) filterButton.setVisibility(View.VISIBLE);
         }
         if (plot instanceof BarGraph){
             BarGraph bar = (BarGraph) plot;
             this.setBarGraphData(bar);
         } else {
             if (this.barGraph != null){
-                this.barGraph.setVisibility(View.INVISIBLE);
+                this.barGraph.setVisibility(View.GONE);
                 if (this.barGraph.getParent() != null){
                     plotLayout.removeView(this.barGraph);
                 }
@@ -634,7 +921,7 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
            this.setLineGraphData(line);
         }else {
             if (this.lineGraph != null){
-                this.lineGraph.setVisibility(View.INVISIBLE);
+                this.lineGraph.setVisibility(View.GONE);
                 if (this.lineGraph.getParent() != null){
                     plotLayout.removeView(this.lineGraph);
                 }
@@ -650,9 +937,6 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
      }
 
     public ArrayList<PlotComparisonItem> getPieData(){
-        if (this.selectedCompareData.equals(COMPARE_TITLE_UsesPerProtocol)){
-            return this.usesPerProtocol();
-        }
         // DEFAULT
         return this.attacksPerProtocols();
     }
@@ -663,20 +947,14 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
             if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerESSID)){
                 return this.attacksPerESSID(protocol);
             }
-
             // DEFAULT
             return this.attacksPerBSSID(protocol);
         }
-
         // Nothing available
         return new ArrayList<PlotComparisonItem>();
     }
     public ArrayList<PlotComparisonItem> getLineData(){
-        if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerTime)){
-            return this.attacksPerTime();
-        }
-        // DEFAULT
-        return this.attacksPerDate();
+        return this.attacksPerTime();
     }
 
     /*
@@ -702,90 +980,85 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
          });
          return this.resizeData(plotItems);
     }
-    public ArrayList<PlotComparisonItem> usesPerProtocol(){
-        ArrayList<PlotComparisonItem> plotItems = new ArrayList<PlotComparisonItem>();
-        for (String title : this.getSelectedProtocolTitles()){
-            /*At the moment there is no possibillity to get the number of uses for each protocol*/
-            // TODO GET USES PER PROTOCOL
-            int uses = 0;
-            if (uses == 0) continue;
-            // ADD ITEMS
-        }
-        Collections.sort(plotItems, new Comparator<PlotComparisonItem>() {
-            @Override
-            public int compare(PlotComparisonItem s1, PlotComparisonItem s2) {
-                return s1.getTitle().compareToIgnoreCase(s2.getTitle());
-            }
-        });
-        return plotItems;
-    }
     /*LINE PLOT DATA*/
-    public ArrayList<PlotComparisonItem> attacksPerDate(){
-        ArrayList<PlotComparisonItem> plotItems = new ArrayList<PlotComparisonItem>();
-        HashMap<Long, ArrayList<Record> > recordMap = new HashMap<Long, ArrayList<Record> >();
+
+    public ArrayList<PlotComparisonItem> attacksPerTime(){
+        HashMap<String,HashMap<Long, ArrayList<Record> > > lineMap = new HashMap<String, HashMap<Long, ArrayList<Record>>>();
+
+        boolean shouldUseDate = this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerDate);
 
         for (Record record : this.getFetchedRecords()){
             long timestamp = record.getTimestamp();
-            long date = this.getDateFromMilliseconds(timestamp);
-            ArrayList<Record> list = recordMap.get(date);
-            if (list == null){
-                list = new ArrayList<Record>();
-                recordMap.put(date, list);
+            long time = 0;
+            if (shouldUseDate){
+                time = this.getDateFromMilliseconds(timestamp);
+            } else {
+                time = this.getDayHourFromDate(timestamp);
             }
-            list.add(record);
-        }
-        int index = 0;
-        for (long date : recordMap.keySet()){
-            ArrayList<Record> list = recordMap.get(date);
-            if (list.size() == 0) continue;
-            // TODO SET CORRECT COLOR
-            PlotComparisonItem item = new PlotComparisonItem(this.getDateAsDayString(date), this.getColor(0), (double) date, (double)list.size());
-            plotItems.add(item);
-            index++;
-        }
-        Collections.sort(plotItems, new Comparator<PlotComparisonItem>() {
-            @Override
-            public int compare(PlotComparisonItem s1, PlotComparisonItem s2) {
-                return s1.getValue1().compareTo(s2.getValue1());
+
+            // GET CORRECT MAP
+            HashMap<Long, ArrayList<Record> > recordMap;
+            String groupKey = record.getSsid();
+            if (lineMap.containsKey(groupKey)){
+                recordMap = lineMap.get(record.getSsid());
+            } else {
+                recordMap = new HashMap<Long, ArrayList<Record> >();
+                lineMap.put(groupKey, recordMap);
             }
-        });
-        return  plotItems;
-    }
-    public ArrayList<PlotComparisonItem> attacksPerTime(){
-        ArrayList<PlotComparisonItem> plotItems = new ArrayList<PlotComparisonItem>();
-        HashMap<Long, ArrayList<Record> > recordMap = new HashMap<Long, ArrayList<Record> >();
 
-        for (Record record : this.getFetchedRecords()){
-            long timestamp = record.getTimestamp();
-            long time = this.getDayHourFromDate(timestamp);
-            ArrayList<Record> list = recordMap.get(time);
-            if (list == null){
+            // GET LIST OF RECORDS
+            ArrayList<Record> list;
+            if (recordMap.containsKey(time)){
+                list = recordMap.get(time);
+            } else {
                 list = new ArrayList<Record>();
                 recordMap.put(time, list);
             }
             list.add(record);
         }
+
+        ArrayList<PlotComparisonItem> plotItems = new ArrayList<PlotComparisonItem>();
+
         int index = 0;
-        for (long time : recordMap.keySet()){
-            ArrayList<Record> list = recordMap.get(time);
-            if (list.size() == 0) continue;
-            // TODO SET CURRECT COLOR
-            PlotComparisonItem item = new PlotComparisonItem(this.getDateAsTimeString(time), this.getColor(0) , (double)time, (double) list.size());
+        for (String groupKey : lineMap.keySet()){
+            HashMap<Long, ArrayList<Record> > recordMap = lineMap.get(groupKey);
+            ArrayList<PlotComparisonItem> singleLineItems = new ArrayList<PlotComparisonItem>();
+
+            for (long time : recordMap.keySet()){
+                ArrayList<Record>list = recordMap.get(time);
+                if (list.size() == 0) continue;
+                PlotComparisonItem item = new PlotComparisonItem(this.getHourAsTimeString(time), 0 , (double)time, (double) list.size());
+                singleLineItems.add(item);
+            }
+
+            Collections.sort(singleLineItems, new Comparator<PlotComparisonItem>() {
+                @Override
+                public int compare(PlotComparisonItem s1, PlotComparisonItem s2) {
+                    return s1.getValue1().compareTo(s2.getValue1());
+                }
+            });
+
+
+            PlotComparisonItem item = new PlotComparisonItem(groupKey, this.getColor(index), 0., (double) singleLineItems.size());
+            item.setOtherData(singleLineItems);
             plotItems.add(item);
             index++;
         }
         Collections.sort(plotItems, new Comparator<PlotComparisonItem>() {
             @Override
             public int compare(PlotComparisonItem s1, PlotComparisonItem s2) {
-                return s1.getValue1().compareTo(s2.getValue1());
+                return s2.getValue2().compareTo(s1.getValue2());
             }
         });
-        return  plotItems;
+        return plotItems;
     }
     // BAR PLOT DATA
     public ArrayList<PlotComparisonItem> attacksPerBSSID(String protocol){
         LogFilter filter = new LogFilter();
         ArrayList<String> protocollist = new ArrayList<String>();
+        filter.setAboveTimestamp(this.filter.getAboveTimestamp());
+        filter.setBelowTimestamp(this.filter.getBelowTimestamp());
+        filter.setBSSIDs(this.filter.getBSSIDs());
         protocollist.add(protocol);
         filter.setProtocols(protocollist);
 
@@ -819,6 +1092,9 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     }
     public ArrayList<PlotComparisonItem> attacksPerESSID(String protocol){
         LogFilter filter = new LogFilter();
+        filter.setAboveTimestamp(this.filter.getAboveTimestamp());
+        filter.setBelowTimestamp(this.filter.getBelowTimestamp());
+        filter.setESSIDs(this.filter.getESSIDs());
         ArrayList<String> protocollist = new ArrayList<String>();
         protocollist.add(protocol);
         filter.setProtocols(protocollist);
@@ -1001,39 +1277,33 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         long millisInDay = 60 * 60 * 24 * 1000;
         return (timeInMillis / millisInDay) * millisInDay;
 
-        /*
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTimeInMillis (timeInMillis);
-
-        int year    = calendar.get(Calendar.YEAR) ;
-        int month   = calendar.get(Calendar.MONTH);
-        int day     = calendar.get(Calendar.DATE);
+    }
 
-        calendar.set(year, month, day, 0,0);
-        return calendar.getTimeInMillis();
-        */
+    /*
+    *
+    * */
+    private String getHourAsTimeString(long hour) {
+        return "" + hour + ":00";
     }
 
-    static final DateFormat timeFormat = new SimpleDateFormat("H:mm");
+    static final DateFormat dateFormat = new SimpleDateFormat("d.M.yyyy");
     @SuppressLint("SimpleDateFormat")
-    private String getDateAsTimeString(long timeStamp) {
-        return "" + timeStamp + ":00";
-        /*
+    private String getDateAsDayString(long timeStamp) {
         try {
             Date netDate = (new Date(timeStamp));
-            return timeFormat.format(netDate);
+            return dateFormat.format(netDate);
         } catch (Exception ex) {
             return "xx";
         }
-        */
     }
 
-    static final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
     @SuppressLint("SimpleDateFormat")
-    private String getDateAsDayString(long timeStamp) {
+    private String getDateAsString(long timeStamp) {
+
         try {
+            DateFormat sdf = new SimpleDateFormat("H:mm  dd/MM/yyyy");
             Date netDate = (new Date(timeStamp));
-            return dateFormat.format(netDate);
+            return sdf.format(netDate);
         } catch (Exception ex) {
             return "xx";
         }
@@ -1043,10 +1313,11 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     /**
      * USERINTERACTION
      */
-    private void userTappedOnItem(int index){
+    private void userTappedOnLegendItem(int index){
         if (index < this.currentData.size()){
             PlotComparisonItem item = this.currentData.get(index);
             ArrayList<String> selectedData;
+            String sortKey = null;
             selectedData = new ArrayList<String>();
 
             if (item.getOtherData() == null){
@@ -1061,20 +1332,61 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
                 filter.setProtocols(selectedData);
             }
             if (this.currentPlotView instanceof BarGraph){
-                // TODO set data for BSSID / ESSID
+
+                if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerESSID)){
+                    filter.setESSIDs(selectedData);
+                    sortKey = "ESSID";
+                } else {
+                    filter.setBSSIDs(selectedData);
+                    sortKey = "BSSID";
+                }
+                ArrayList<String> currentSelectedProtocol = new ArrayList<String>();
+                currentSelectedProtocol.add(this.getCurrentSelectedProtocol());
+                filter.setProtocols(currentSelectedProtocol);
             }
             if (this.currentPlotView instanceof  LineGraph){
-                // TODO set data for BSSID / ESSID
+                selectedData = new ArrayList<String>();
+                selectedData.add(item.getTitle());
+                filter.setESSIDs(selectedData);
+                filter.setProtocols(this.filter.getProtocols());
+                sortKey = "ESSID";
             }
 
-            this.pushRecordOverviewForFilter(filter);
+            if (this.filter.hasATimestamp()){
+                filter.setAboveTimestamp(this.filter.getAboveTimestamp());
+                filter.setBelowTimestamp(this.filter.getBelowTimestamp());
+            }
+
+            this.pushRecordOverviewForFilter(filter, sortKey);
         }
+    }
 
+    public void onSliceClick(int index){
 
     }
+    public void onBarClick(int index){
+        this.userTappedOnLegendItem(index);
+    }
+
+    private void pushRecordOverviewForFilter(LogFilter filter, String sortKey){
 
-    private void pushRecordOverviewForFilter(LogFilter filter){
+        FragmentManager fm = this.getActivity().getFragmentManager();
+
+        if (fm != null){
+            RecordOverviewFragment newFragment = new RecordOverviewFragment();
+            newFragment.setFilter(filter);
+
+            if (sortKey != null && sortKey.length() != 0) newFragment.setGroupKey(sortKey);
+
+            FragmentTransaction transaction = fm.beginTransaction();
+            transaction.replace(R.id.content_frame, newFragment, newFragment.getTag());
+            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
+            transaction.addToBackStack(null);
+
+            transaction.commit();
+        }
 
     }
 
+
 }

+ 9 - 0
src/de/tudarmstadt/informatik/hostage/ui2/model/ExpandableListItem.java

@@ -14,6 +14,15 @@ public class ExpandableListItem {
     /*Data Key To Textual Information*/
     public HashMap<String, String> data;
 
+    public long getTag() {
+        return tag;
+    }
+    public void setTag(long tag) {
+        this.tag = tag;
+    }
+
+    private long tag;
+
 
 
     public HashMap<String, Integer> getId_Mapping() {