package com.hmkcode.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.util.AttributeSet;
import android.view.View;
public class DonutChart extends View {
private float radius;
Paint paint;
Paint shadowPaint;
Path myPath;
Path shadowPath;
RectF outterCircle;
RectF innerCircle;
RectF shadowRectF;
public DonutChart(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.DonutChart,
0, 0
);
try {
radius = a.getDimension(R.styleable.DonutChart_radius, 20.0f);
} finally {
a.recycle();
}
paint = new Paint();
paint.setDither(true);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setAntiAlias(true);
paint.setStrokeWidth(radius / 14.0f);
shadowPaint = new Paint();
shadowPaint.setColor(0xf0000000);
shadowPaint.setStyle(Paint.Style.STROKE);
shadowPaint.setAntiAlias(true);
shadowPaint.setStrokeWidth(6.0f);
shadowPaint.setMaskFilter(new BlurMaskFilter(4, BlurMaskFilter.Blur.SOLID));
myPath = new Path();
shadowPath = new Path();
outterCircle = new RectF();
innerCircle = new RectF();
shadowRectF = new RectF();
float adjust = (.019f*radius);
shadowRectF.set(adjust, adjust, radius*2-adjust, radius*2-adjust);
adjust = .038f * radius;
outterCircle.set(adjust, adjust, radius*2-adjust, radius*2-adjust);
adjust = .276f * radius;
innerCircle.set(adjust, adjust, radius*2-adjust, radius*2-adjust);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// draw shadow
paint.setShader(null);
float adjust = (.0095f*radius);
paint.setShadowLayer(8, adjust, -adjust, 0xaa000000);
drawDonut(canvas,paint, 0,359.9f);
// green
setGradient(0xff84BC3D,0xff5B8829);
drawDonut(canvas,paint, 0,60);
//red
setGradient(0xffe04a2f,0xffB7161B);
drawDonut(canvas,paint, 60,60);
// blue
setGradient(0xff4AB6C1,0xff2182AD);
drawDonut(canvas,paint, 120,60);
// yellow
setGradient(0xffFFFF00,0xfffed325);
drawDonut(canvas,paint, 180,180);
}
public void drawDonut(Canvas canvas, Paint paint, float start,float sweep){
myPath.reset();
myPath.arcTo(outterCircle, start, sweep, false);
myPath.arcTo(innerCircle, start+sweep, -sweep, false);
myPath.close();
canvas.drawPath(myPath, paint);
}
public void setGradient(int sColor, int eColor){
paint.setShader(new RadialGradient(radius, radius, radius-5,
new int[]{sColor,eColor},
new float[]{.6f,.95f},TileMode.CLAMP) );
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int desiredWidth = (int) radius*2;
int desiredHeight = (int) radius*2;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//70dp exact
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
}else if (widthMode == MeasureSpec.AT_MOST) {
//wrap content
width = Math.min(desiredWidth, widthSize);
} else {
width = desiredWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(desiredHeight, heightSize);
} else {
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(width, height);
}
}