Created
March 26, 2015 07:56
-
-
Save chooblarin/ed7942f8e9ca59b1a7ea to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CircleGraphView extends View { | |
static class Data { | |
int value; | |
int color; | |
Data(int value, int color) { | |
this.value = value; | |
this.color = color; | |
} | |
} | |
static final int DIVIDER_SPACE = 2; | |
static final int GRAPH_WIDTH = 24; | |
static final int STROKE_WIDTH = 2; | |
private int centerX; | |
private int centerY; | |
private float outerRadius; | |
private float innerRadius; | |
private RectF outerBounds; | |
private RectF innerBounds; | |
Path path; | |
Paint fillPaint; | |
Paint strokePaint; | |
private List<Data> dataList = new ArrayList<Data>(); | |
public CircleGraphView(Context context) { | |
this(context, null); | |
} | |
public CircleGraphView(Context context, AttributeSet attrs) { | |
this(context, attrs, 0); | |
} | |
public CircleGraphView(Context context, AttributeSet attrs, int defStyleAttr) { | |
super(context, attrs, defStyleAttr); | |
init(context); | |
} | |
@Override | |
protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
super.onSizeChanged(w, h, oldw, oldh); | |
centerX = w / 2; | |
centerY = h / 2; | |
outerRadius = w > h ? centerY : centerX; | |
innerRadius = outerRadius - Utils.convertDpToPixel(GRAPH_WIDTH); | |
outerBounds = new RectF( | |
centerX - outerRadius, centerY - outerRadius, | |
centerX + outerRadius, centerY + outerRadius | |
); | |
innerBounds = new RectF( | |
centerX - innerRadius, centerY - innerRadius, | |
centerX + innerRadius, centerY + innerRadius | |
); | |
} | |
@Override | |
protected void onDraw(Canvas canvas) { | |
super.onDraw(canvas); | |
int total = 0; | |
for (Data data : dataList) { | |
total += data.value; | |
} | |
if (0 >= total) { | |
return; | |
} | |
float offset = 0; | |
for (Data data : dataList) { | |
float angle = 360f * data.value / total; | |
drawPie(canvas, offset, angle, data.color); | |
offset += angle; | |
} | |
} | |
public void setData() { | |
List<Data> dataList = new ArrayList<>(); | |
dataList.add(new Data(500, Color.BLUE)); | |
dataList.add(new Data(300, Color.RED)); | |
dataList.add(new Data(300, Color.YELLOW)); | |
dataList.add(new Data(200, Color.GREEN)); | |
this.dataList.addAll(dataList); | |
} | |
private void init(Context context) { | |
Utils.init(context.getResources()); | |
path = new Path(); | |
fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
} | |
private void drawPie(Canvas canvas, float startAngle, float sweepAngle, int color) { | |
int x, y; | |
float adjustedStartAngle = startAngle - 90 + DIVIDER_SPACE; | |
float adjustedSweepAngle = sweepAngle - (2 * DIVIDER_SPACE); | |
float deltaTheta = adjustedStartAngle + adjustedSweepAngle; | |
path.reset(); | |
// inner arc | |
path.arcTo(innerBounds, adjustedStartAngle, adjustedSweepAngle); | |
// divider (inner -> outer) | |
x = (int) (Math.cos(deltaTheta * Math.PI / 180) * outerRadius); | |
y = (int) (Math.sin(deltaTheta * Math.PI / 180) * outerRadius); | |
path.lineTo(centerX + x, centerY + y); | |
// outer arc | |
path.arcTo(outerBounds, deltaTheta, -adjustedSweepAngle); | |
// divider (outer -> inner) | |
x = (int) (Math.cos(adjustedStartAngle * Math.PI / 180) * innerRadius); | |
y = (int) (Math.sin(adjustedStartAngle * Math.PI / 180) * innerRadius); | |
path.lineTo(centerX + x, centerY + y); | |
fillPaint.setColor(color); | |
fillPaint.setAlpha(160); | |
canvas.drawPath(path, fillPaint); | |
strokePaint.setColor(color); | |
strokePaint.setStrokeWidth(Utils.convertDpToPixel(STROKE_WIDTH)); | |
strokePaint.setStyle(Paint.Style.STROKE); | |
canvas.drawPath(path, strokePaint); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment