Commits

Anonymous committed 7fc65f9

Improved performances by removing object allocations.

  • Participants
  • Parent commits 6feeb60

Comments (0)

Files changed (10)

HoloGraphLibrary/src/com/echo/holographlibrary/Bar.java

 import android.graphics.Region;
 
 public class Bar {
+
+    private final Path mPath = new Path();
+    private final Region mRegion = new Region();
     private int mColor = 0xFF33B5E5;
-	private int mLabelColor = -1;
-    private int mSelectedColor = 0x8033B5E5;
-	private String mName = null;
-	private float mValue;
-	private String mValueString = null;
-	private Path mPath = null;
-	private Region mRegion = null;
-	
+    private int mLabelColor = -1;
+    private int mSelectedColor = -1;
+    private String mName = null;
+    private float mValue;
+    private String mValueString = null;
+
 	public int getColor() {
 		return mColor;
 	}
 	}
 
     public int getSelectedColor() {
+        if(-1 == mSelectedColor) mSelectedColor = Utils.darkenColor(mColor);
         return mSelectedColor;
     }
 
 		this.mValue = value;
 	}
 	
-	public String getValueString()
-	{
+	public String getValueString() {
 		if (mValueString != null) {
 			return mValueString;
 		} else {
 	public Path getPath() {
 		return mPath;
 	}
-	public void setPath(Path path) {
-		this.mPath = path;
-	}
+
 	public Region getRegion() {
 		return mRegion;
 	}
-	public void setRegion(Region region) {
-		this.mRegion = region;
-	}
-	
 }

HoloGraphLibrary/src/com/echo/holographlibrary/BarGraph.java

 import android.graphics.Region;
 import android.graphics.drawable.NinePatchDrawable;
 import android.util.AttributeSet;
+import android.util.SparseArray;
 import android.view.MotionEvent;
 import android.view.View;
 
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
 
 public class BarGraph extends View {
 
     private final int mOrientation;
     private ArrayList<Bar> mBars = new ArrayList<Bar>();
     private Paint mPaint = new Paint();
-    private Rect mRectangle = null;
+    private Rect mBoundsRect = new Rect();
+    private Rect mTextRect = new Rect();
     private boolean mShowBarText = true;
     private boolean mShowAxis = true;
-    private int mIndexSelected = -1;
+    private int mSelectedIndex = -1;
     private OnBarClickedListener mListener;
     private Bitmap mFullImage;
     private boolean mShouldUpdate = false;
             
             float maxValue = 0;
             float padding = 7 * getContext().getResources().getDisplayMetrics().density;
-            int selectPadding = (int) (4 * resources.getDisplayMetrics().density);
             float bottomPadding = 30 * resources.getDisplayMetrics().density;
             
             float usableHeight;
             if (mShowBarText) {
                 this.mPaint.setTextSize(VALUE_FONT_SIZE * resources.getDisplayMetrics().scaledDensity);
-                Rect r3 = new Rect();
-                this.mPaint.getTextBounds("$", 0, 1, r3);
-                usableHeight = getHeight()-bottomPadding-Math.abs(r3.top-r3.bottom)-24 * resources.getDisplayMetrics().density;
+                this.mPaint.getTextBounds("$", 0, 1, mTextRect);
+                usableHeight = getHeight()-bottomPadding-Math.abs(mTextRect.top-mTextRect.bottom)
+                        -24 * resources.getDisplayMetrics().density;
             } else {
                 usableHeight = getHeight()-bottomPadding;
             }
                 mPaint.setStrokeWidth(2 * resources.getDisplayMetrics().density);
                 mPaint.setAlpha(50);
                 mPaint.setAntiAlias(true);
-                canvas.drawLine(0, getHeight()-bottomPadding+10* resources.getDisplayMetrics().density, getWidth(), getHeight()-bottomPadding+10* resources.getDisplayMetrics().density, mPaint);
+                canvas.drawLine(0,
+                        getHeight()-bottomPadding+10* resources.getDisplayMetrics().density,
+                        getWidth(),
+                        getHeight()-bottomPadding+10* resources.getDisplayMetrics().density, mPaint);
             }
             float barWidth = (getWidth() - (padding*2)*mBars.size())/mBars.size();
 
                 maxValue = 1;
             }
             
-            mRectangle = new Rect();
-            
             int count = 0;
-            Map<Integer, Float> valueTextSizes = new HashMap<Integer, Float>();
+            SparseArray<Float> valueTextSizes = new SparseArray<Float>();
             for (final Bar bar : mBars) {
                 // Set bar bounds
                 int left = (int)((padding*2)*count + padding + barWidth*count);
                 int top = (int)(getHeight()-bottomPadding-(usableHeight*(bar.getValue()/maxValue)));
                 int right = (int)((padding*2)*count + padding + barWidth*(count+1));
                 int bottom = (int)(getHeight()-bottomPadding);
-                mRectangle.set(left, top, right, bottom);
+                mBoundsRect.set(left, top, right, bottom);
 
                 // Draw bar
-                this.mPaint.setColor(bar.getColor());
-                this.mPaint.setAlpha(255);
-                canvas.drawRect(mRectangle, this.mPaint);
+                if(count == mSelectedIndex && null != mListener) {
+                    this.mPaint.setColor(bar.getSelectedColor());
+                }
+                else {
+                    this.mPaint.setColor(bar.getColor());
+                }
+                canvas.drawRect(mBoundsRect, this.mPaint);
 
                 // Create selection region
-                Path path = new Path();
-                path.addRect(new RectF(mRectangle.left-selectPadding, mRectangle.top-selectPadding, mRectangle.right+selectPadding, mRectangle.bottom+selectPadding), Path.Direction.CW);
-                bar.setPath(path);
-                bar.setRegion(new Region(mRectangle.left-selectPadding, mRectangle.top-selectPadding, mRectangle.right+selectPadding, mRectangle.bottom+selectPadding));
+                bar.getPath().reset();
+                bar.getPath().addRect(new RectF(mBoundsRect.left,
+                                mBoundsRect.top,
+                                mBoundsRect.right,
+                                mBoundsRect.bottom),
+                        Path.Direction.CW
+                );
+                bar.getRegion().set(mBoundsRect.left,
+                        mBoundsRect.top,
+                        mBoundsRect.right,
+                        mBoundsRect.bottom);
 
                 // Draw x-axis label text
                 if (mShowAxis){
                     this.mPaint.setColor(bar.getLabelColor());
                     this.mPaint.setTextSize(AXIS_LABEL_FONT_SIZE * resources.getDisplayMetrics().scaledDensity);
                     float textWidth = this.mPaint.measureText(bar.getName());
-                    while (right - left + (padding *LABEL_PADDING_MULTIPLIER)< textWidth)//decrease text size to fit and not overlap with other labels.
-                    {
+                    while (right - left + (padding *LABEL_PADDING_MULTIPLIER)< textWidth) {
+                        //decrease text size to fit and not overlap with other labels.
                         this.mPaint.setTextSize(this.mPaint.getTextSize() -  1);
                         textWidth = this.mPaint.measureText(bar.getName());
                     }
-                    int x = (int)(((mRectangle.left+mRectangle.right)/2)-(textWidth/2));
+                    int x = (int)(((mBoundsRect.left+ mBoundsRect.right)/2)-(textWidth/2));
                     int y = (int) (getHeight()-3 * resources.getDisplayMetrics().scaledDensity);
                     canvas.drawText(bar.getName(), x, y, this.mPaint);
                 }
                 if (mShowBarText){
                     this.mPaint.setTextSize(VALUE_FONT_SIZE * resources.getDisplayMetrics().scaledDensity);
                     this.mPaint.setColor(Color.WHITE);
-                    Rect r2 = new Rect();
-                    this.mPaint.getTextBounds(bar.getValueString(), 0, 1, r2);
+                    this.mPaint.getTextBounds(bar.getValueString(), 0, 1, mTextRect);
                     
-                    int boundLeft = (int) (((mRectangle.left+mRectangle.right)/2)-(this.mPaint.measureText(bar.getValueString())/2)-10 * resources.getDisplayMetrics().density);
-                    int boundTop = (int) (mRectangle.top+(r2.top-r2.bottom)-18 * resources.getDisplayMetrics().density);
-                    int boundRight = (int)(((mRectangle.left+mRectangle.right)/2)+(this.mPaint.measureText(bar.getValueString())/2)+10 * resources.getDisplayMetrics().density);
+                    int boundLeft = (int) (((mBoundsRect.left+ mBoundsRect.right)/2)
+                            -(this.mPaint.measureText(bar.getValueString())/2)-10 * resources.getDisplayMetrics().density);
+                    int boundTop = (int) (mBoundsRect.top+(mTextRect.top-mTextRect.bottom)
+                            -18 * resources.getDisplayMetrics().density);
+                    int boundRight = (int)(((mBoundsRect.left+ mBoundsRect.right)/2)
+                            +(this.mPaint.measureText(bar.getValueString())/2)
+                            +10 * resources.getDisplayMetrics().density);
 
-                    if (boundLeft < mRectangle.left) boundLeft = mRectangle.left - ((int)padding /2);//limit popup width to bar width
-                    if (boundRight > mRectangle.right)boundRight = mRectangle.right + ((int) padding /2);
+                    if (boundLeft < mBoundsRect.left) boundLeft = mBoundsRect.left - ((int)padding /2);//limit popup width to bar width
+                    if (boundRight > mBoundsRect.right)boundRight = mBoundsRect.right + ((int) padding /2);
 
-                    popup.setBounds(boundLeft, boundTop, boundRight, mRectangle.top);
+                    popup.setBounds(boundLeft, boundTop, boundRight, mBoundsRect.top);
                     popup.draw(canvas);
 
-                    if (!valueTextSizes.containsKey(bar.getValueString().length()))//check cache to see if we've done this calculation before
-                    {
+                    if (0 > valueTextSizes.indexOfKey(bar.getValueString().length())) {
+                        //check cache to see if we've done this calculation before
                         while (this.mPaint.measureText(bar.getValueString()) > boundRight - boundLeft)
                             this.mPaint.setTextSize(this.mPaint.getTextSize() - (float)1);
                         valueTextSizes.put(bar.getValueString().length(), mPaint.getTextSize());
                     }
-                    else this.mPaint.setTextSize(valueTextSizes.get(bar.getValueString().length()));
-                    canvas.drawText(bar.getValueString(), (int)(((mRectangle.left+mRectangle.right)/2)-(this.mPaint.measureText(bar.getValueString()))/2), mRectangle.top-(mRectangle.top - boundTop)/2f+(float)Math.abs(r2.top-r2.bottom)/2f*0.7f, this.mPaint);
-                }
-                if (mIndexSelected == count && mListener != null) {
-                    this.mPaint.setColor(bar.getSelectedColor());
-                    canvas.drawPath(bar.getPath(), this.mPaint);
-                    this.mPaint.setAlpha(255);
+                    else {
+                        this.mPaint.setTextSize(valueTextSizes.get(bar.getValueString().length()));
+                    }
+                    canvas.drawText(bar.getValueString(),
+                            (int) (((mBoundsRect.left + mBoundsRect.right) / 2)
+                                    - (this.mPaint.measureText(bar.getValueString())) / 2),
+                            mBoundsRect.top - (mBoundsRect.top - boundTop) / 2f
+                                    + (float) Math.abs(mTextRect.top - mTextRect.bottom) / 2f * 0.7f,
+                            this.mPaint
+                    );
                 }
                 count++;
             }
         for (Bar bar : mBars){
             Region r = new Region();
             r.setPath(bar.getPath(), bar.getRegion());
-            if (r.contains((int)point.x,(int) point.y) && event.getAction() == MotionEvent.ACTION_DOWN){
-                mIndexSelected = count;
-            } else if (event.getAction() == MotionEvent.ACTION_UP){
-                if (r.contains((int)point.x,(int) point.y) && mListener != null){
-                    if (mIndexSelected > -1) mListener.onClick(mIndexSelected);
-                    mIndexSelected = -1;
-                }
+            switch (event.getAction()) {
+                default:
+                    break;
+                case MotionEvent.ACTION_DOWN:
+                    if (r.contains(point.x, point.y)) {
+                        mSelectedIndex = count;
+                        mShouldUpdate = true;
+                        postInvalidate();
+                    }
+                    break;
+                case MotionEvent.ACTION_UP:
+                    if (r.contains(point.x, point.y) && null != mListener){
+                        if (mSelectedIndex > -1){
+                            mListener.onClick(mSelectedIndex);
+                        }
+                        mSelectedIndex = -1;
+                    }
+                    mShouldUpdate = true;
+                    postInvalidate();
+                    break;
+                case MotionEvent.ACTION_CANCEL:
+                    mSelectedIndex = -1;
+                    postInvalidate();
+                    break;
             }
-            else if(event.getAction() == MotionEvent.ACTION_CANCEL)
-            	mIndexSelected = -1;
-            
             count++;
         }
-        
-        if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL){
-            mShouldUpdate = true;
-            postInvalidate();
-        }
-
         return true;
     }
     
     @Override
-    protected void onDetachedFromWindow()
-    {
+    protected void onDetachedFromWindow() {
     	if(mFullImage != null)
     		mFullImage.recycle();
     	

HoloGraphLibrary/src/com/echo/holographlibrary/LineGraph.java

     private final float mStrokeWidth;
     private final int mStrokeSpacing;
 	private ArrayList<Line> lines = new ArrayList<Line>();
-	Paint paint = new Paint();
+	private Paint paint = new Paint();
 	private float minY = 0, minX = 0;
 	private float maxY = 0, maxX = 0;
 	private double rangeYRatio = 0;
 	private boolean shouldUpdate = false;
 	// since this is a new addition, it has to default to false to be backwards compatible
 	private boolean isUsingDips;
+    private Path mPath = new Path();
 
 	public LineGraph(Context context){
 		this(context, null);
 			Canvas canvas = new Canvas(fullImage);
 			
 			paint.reset();
-			Path path = new Path();
 
 			float bottomPadding = 10, topPadding = 10;
 			float sidePadding = 10;
 					}
 					
 					paint.reset();
+                    mPath.reset();
 
 					paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR));
 					for (LinePoint p : line.getPoints()){
 						if (count == 0){
 							lastXPixels = sidePadding + (xPercent*usableWidth);
 							lastYPixels = getHeight() - bottomPadding - (usableHeight*yPercent);
-							path.moveTo(lastXPixels, lastYPixels);
+                            mPath.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);
+                            mPath.lineTo(newXPixels, newYPixels);
+                            mPath.moveTo(lastXPixels, lastYPixels);
+                            mPath.lineTo(newXPixels, newYPixels);
+                            mPath.lineTo(newXPixels, 0);
+                            mPath.lineTo(lastXPixels, 0);
+                            mPath.close();
+							canvas.drawPath(mPath, paint);
 							lastXPixels = newXPixels;
 							lastYPixels = newYPixels;
 						}
 						count++;
 					}
+
+                    mPath.reset();
+                    mPath.moveTo(0, getHeight()-bottomPadding);
+                    mPath.lineTo(sidePadding, getHeight()-bottomPadding);
+					mPath.lineTo(sidePadding, 0);
+					mPath.lineTo(0, 0);
+					mPath.close();
+					canvas.drawPath(mPath, paint);
 					
-					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);
+					mPath.reset();
+					mPath.moveTo(getWidth(), getHeight()-bottomPadding);
+					mPath.lineTo(getWidth()-sidePadding, getHeight()-bottomPadding);
+					mPath.lineTo(getWidth()-sidePadding, 0);
+					mPath.lineTo(getWidth(), 0);
+					mPath.close();
 					
+					canvas.drawPath(mPath, paint);
 				}
 				
 				lineCount++;
 						paint.setColor(Color.WHITE);
 						canvas.drawCircle(xPixels, yPixels, innerRadius, paint);
 						
-						Path path2 = new Path();
-						path2.addCircle(xPixels, yPixels, 30, Direction.CW);
-						p.setPath(path2);
-						p.setRegion(new Region((int)(xPixels-30), (int)(yPixels-30), (int)(xPixels+30), (int)(yPixels+30)));
+                        p.getPath().reset();
+                        p.getPath().addCircle(xPixels, yPixels, 30, Direction.CW);
+						p.getRegion().set((int) (xPixels - 30), (int) (yPixels - 30), (int) (xPixels + 30), (int) (yPixels + 30));
 						
 						if (indexSelected == pointCount && listener != null){
                             paint.setColor(p.getSelectedColor());
 					}
 				}
 			}
-			
+
 			shouldUpdate = false;
 		}
 		
 	    
 	    int count = 0;
 	    int lineCount = 0;
-	    int pointCount = 0;
+	    int pointCount;
 	    
 	    Region r = new Region();
 	    for (Line line : lines){
 	    		
 	    		if (p.getPath() != null && p.getRegion() != null){
 	    			r.setPath(p.getPath(), p.getRegion());
-			    	if (r.contains((int)point.x,(int) point.y) && event.getAction() == MotionEvent.ACTION_DOWN){
+			    	if (r.contains(point.x, point.y) && event.getAction() == MotionEvent.ACTION_DOWN){
 			    		indexSelected = count;
 			    	} else if (event.getAction() == MotionEvent.ACTION_UP){
-			    		if (r.contains((int)point.x,(int) point.y) && listener != null){
+			    		if (r.contains(point.x, point.y) && listener != null){
 			    			listener.onClick(lineCount, pointCount);
 			    		}
 			    		indexSelected = -1;
 			    count++;
 	    	}
 	    	lineCount++;
-	    	
 	    }
 	    
 	    if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP){
 	    	shouldUpdate = true;
 	    	postInvalidate();
 	    }
-	    
-	    
 
 	    return true;
 	}

HoloGraphLibrary/src/com/echo/holographlibrary/LinePoint.java

 import android.graphics.Region;
 
 public class LinePoint {
-	private float mX = 0;
-	private float mY = 0;
-	private Path mPath;
-	private Region mRegion;
+
+    final private Path mPath = new Path();
+    final private Region mRegion = new Region();
+    private float mX = 0;
+    private float mY = 0;
     private int mColor = 0xFF000000;
-    private int mSelectedColor = 0x8033B5E5;
+    private int mSelectedColor = -1;
 
     public LinePoint(){
     }
 		this.mX = (float)x;
 		this.mY = (float)y;
 	}
+
 	public LinePoint(float x, float y){
 		this.mX = x;
 		this.mY = y;
 	}
+
 	public float getX() {
 		return mX;
 	}
 	public Region getRegion() {
 		return mRegion;
 	}
-	public void setRegion(Region region) {
-		this.mRegion = region;
-	}
 	public Path getPath() {
 		return mPath;
 	}
-	public void setPath(Path path) {
-		this.mPath = path;
-	}
-	
+
 	@Override
 	public String toString(){
 		return "x= " + mX + ", y= " + mY;
     }
 
     public int getSelectedColor() {
+        if(-1 == mSelectedColor) {
+            mSelectedColor = Utils.darkenColor(mColor);
+            mSelectedColor &= 0x80FFFFFF;
+        }
         return mSelectedColor;
     }
 

HoloGraphLibrary/src/com/echo/holographlibrary/PieGraph.java

 
 public class PieGraph extends View {
 
-    private final int mPadding;
-    private final int mInnerCircleRatio;
+    private int mPadding;
+    private int mInnerCircleRatio;
     private ArrayList<PieSlice> mSlices = new ArrayList<PieSlice>();
     private Paint mPaint = new Paint();
-    private Path mPath = new Path();
     private int mSelectedIndex = -1;
 	private OnSliceClickedListener mListener;
 	private boolean mDrawCompleted = false;
+    private RectF mRectF = new RectF();
 
 	public PieGraph(Context context) {
 		this(context, null);
 	}
 
 	public void onDraw(Canvas canvas) {
-		canvas.drawColor(Color.TRANSPARENT);
-		mPaint.reset();
-		mPaint.setAntiAlias(true);
-		float midX, midY, radius, innerRadius;
-		mPath.reset();
+        float midX, midY, radius, innerRadius;
+
+        canvas.drawColor(Color.TRANSPARENT);
+        mPaint.reset();
+        mPaint.setAntiAlias(true);
 
 		float currentAngle = 270;
 		float currentSweep = 0;
 
 		int count = 0;
 		for (PieSlice slice : mSlices){
-			Path p = new Path();
+            Path p = slice.getPath();
+            p.reset();
+
             if (mSelectedIndex == count && mListener != null){
                 mPaint.setColor(slice.getSelectedColor());
             }
                 mPaint.setColor(slice.getColor());
             }
 			currentSweep = (slice.getValue()/totalValue)*(360);
-			p.arcTo(new RectF(midX-radius, midY-radius, midX+radius, midY+radius),
-                    currentAngle+mPadding, currentSweep - mPadding);
-			p.arcTo(new RectF(midX-innerRadius, midY-innerRadius, midX+innerRadius, midY+innerRadius),
+            mRectF.set(midX - radius, midY - radius, midX + radius, midY + radius);
+			p.arcTo(mRectF,
+                    currentAngle + mPadding, currentSweep - mPadding);
+            mRectF.set(midX-innerRadius, midY-innerRadius, midX+innerRadius, midY+innerRadius);
+			p.arcTo(mRectF,
                     (currentAngle+mPadding) + (currentSweep - mPadding), -(currentSweep-mPadding));
 			p.close();
 
-			slice.setPath(p);
-			slice.setRegion(new Region((int)(midX-radius), (int)(midY-radius),
-                    (int)(midX+radius), (int)(midY+radius)));
+            Region r = slice.getRegion();
+            r.set((int)(midX-radius),
+                    (int)(midY-radius),
+                    (int)(midX+radius),
+                    (int)(midY+radius));
 			canvas.drawPath(p, mPaint);
 			currentAngle = currentAngle+currentSweep;
 
 			for (PieSlice slice : mSlices){
 				Region r = new Region();
 				r.setPath(slice.getPath(), slice.getRegion());
-				if (r.contains((int)point.x,(int) point.y) && event.getAction() == MotionEvent.ACTION_DOWN){
-					mSelectedIndex = count;
-				} else if (event.getAction() == MotionEvent.ACTION_UP){
-					if (r.contains((int)point.x,(int) point.y) && mListener != null){
-						if (mSelectedIndex > -1){
-							mListener.onClick(mSelectedIndex);
-						}
-						mSelectedIndex = -1;
-					}
-
-				}
-				else if(event.getAction() == MotionEvent.ACTION_CANCEL)
-					mSelectedIndex = -1;
+                switch (event.getAction()) {
+                    default:
+                        break;
+                    case MotionEvent.ACTION_DOWN:
+                        if (r.contains(point.x, point.y)) {
+                            mSelectedIndex = count;
+                            postInvalidate();
+                        }
+                        break;
+                    case MotionEvent.ACTION_UP:
+                        if (r.contains(point.x, point.y) && mListener != null){
+                            if (mSelectedIndex > -1){
+                                mListener.onClick(mSelectedIndex);
+                            }
+                            mSelectedIndex = -1;
+                            postInvalidate();
+                        }
+                        break;
+                    case MotionEvent.ACTION_CANCEL:
+                        mSelectedIndex = -1;
+                        postInvalidate();
+                        break;
+                }
 				count++;
 			}
-
-			if (event.getAction() == MotionEvent.ACTION_DOWN ||
-                    event.getAction() == MotionEvent.ACTION_UP ||
-                    event.getAction() == MotionEvent.ACTION_CANCEL){
-				postInvalidate();
-			}
 	    }
 	    return true;
 	}
 
-	public ArrayList<PieSlice> getSlices() {
+    public void setPadding(int padding) {
+        mPadding = padding;
+        postInvalidate();
+    }
+
+    public void setInnerCircleRatio(int innerCircleRatio) {
+        mInnerCircleRatio = innerCircleRatio;
+        postInvalidate();
+    }
+
+    public ArrayList<PieSlice> getSlices() {
 		return mSlices;
 	}
 
 	}
 
 	public void removeSlices(){
-		for (int i = mSlices.size()-1; i >= 0; i--){
-			mSlices.remove(i);
-		}
+        this.mSlices.clear();
 		postInvalidate();
 	}
 

HoloGraphLibrary/src/com/echo/holographlibrary/PieSlice.java

 import android.graphics.Region;
 
 public class PieSlice {
+
+    private final Path mPath = new Path();
+    private final Region mRegion = new Region();
 	private int mColor = 0xFF33B5E5;
-    private int mSelectedColor = 0x8033B5E5;
+    private int mSelectedColor = -1;
 	private float mValue;
 	private String mTitle;
-	private Path mPath;
-	private Region mRegion;
 
 	public String getTitle() {
 		return mTitle;
 	}
 
     public int getSelectedColor() {
+        if(-1 == mSelectedColor) mSelectedColor = Utils.darkenColor(mColor);
         return mSelectedColor;
     }
 
 	public Path getPath() {
 		return mPath;
 	}
-	public void setPath(Path path) {
-		this.mPath = path;
-	}
 	public Region getRegion() {
 		return mRegion;
 	}
-	public void setRegion(Region region) {
-		this.mRegion = region;
-	}
-	
 }

HoloGraphLibrary/src/com/echo/holographlibrary/Utils.java

+package com.echo.holographlibrary;
+
+import android.graphics.Color;
+
+/**
+ * Created by sbaiget on 11/04/2014.
+ */
+public class Utils {
+
+    public static int darkenColor(int color) {
+        float[] hsv = new float[3];
+        Color.colorToHSV(color, hsv);
+        hsv[2] *= 0.8f;
+        return Color.HSVToColor(hsv);
+    }
+}

HoloGraphLibrarySample/res/layout/activity_main.xml

     android:layout_height="match_parent"
     tools:context=".MainActivity">
 
-
     <android.support.v4.view.ViewPager
         android:id="@+id/view_pager"
         android:layout_width="match_parent"

HoloGraphLibrarySample/res/layout/fragment_piegraph.xml

     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical">
-    
-    
+
     <com.echo.holographlibrary.PieGraph
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:id="@+id/piegraph"
+        android:layout_height="0dip"
+        android:layout_weight="1"
         android:layout_margin="@dimen/default_margin"
+        android:id="@+id/piegraph"
         app:innerCircleRatio="128"
         app:slicePadding="0dip"/>
 
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_margin="@dimen/default_margin"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:gravity="center_vertical"
+            android:text="Inner Circle Ratio"
+            android:layout_weight="1"/>
+
+        <SeekBar
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:progress="128"
+            android:max="255"
+            android:id="@+id/seekBarRatio"
+            android:layout_weight="1"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_margin="@dimen/default_margin"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:gravity="center_vertical"
+            android:text="Padding"
+            android:layout_weight="1"/>
+
+        <SeekBar
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:progress="0"
+            android:max="10"
+            android:id="@+id/seekBarPadding"
+            android:layout_weight="1"/>
+    </LinearLayout>
+
 </LinearLayout>

HoloGraphLibrarySample/src/com/echo/holographlibrarysample/PieFragment.java

 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.SeekBar;
+import android.widget.Toast;
 
 import com.echo.holographlibrary.PieGraph;
 import com.echo.holographlibrary.PieGraph.OnSliceClickedListener;
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         final View v = inflater.inflate(R.layout.fragment_piegraph, container, false);
         final Resources resources = getResources();
-        PieGraph pg = (PieGraph) v.findViewById(R.id.piegraph);
+        final PieGraph pg = (PieGraph) v.findViewById(R.id.piegraph);
         PieSlice slice = new PieSlice();
         slice.setColor(resources.getColor(R.color.green_light));
         slice.setSelectedColor(resources.getColor(R.color.transparent_orange));
 
             @Override
             public void onClick(int index) {
+                Toast.makeText(getActivity(),
+                        "Slice " + index + " clicked",
+                        Toast.LENGTH_SHORT)
+                        .show();
+            }
+        });
+
+        SeekBar seekBar = (SeekBar) v.findViewById(R.id.seekBarRatio);
+        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                pg.setInnerCircleRatio(progress);
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
 
             }
+        });
+
+        seekBar = (SeekBar) v.findViewById(R.id.seekBarPadding);
+        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                pg.setPadding(progress);
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
 
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+
+            }
         });
 
         return v;