Open adnanafzal565 opened 6 years ago
package im.dacer.androidcharts;
public class PieHelper {
int velocity = 5;
private float startDegree;
private float endDegree;
private float targetStartDegree;
private float targetEndDegree;
private String title;
private int color;
private float sweepDegree;
/**
* @param percent from 0 to 100
*/
public PieHelper(float percent) {
this(percent, null, 0);
}
public PieHelper(float percent, int color) {
this(percent, null, color);
}
/**
* @param percent from 0 to 100
*/
public PieHelper(float percent, String title) {
this(percent, title, 0);
}
/**
* @param percent from 0 to 100
*/
public PieHelper(float percent, String title, int color) {
this.sweepDegree = percent * 360 / 100;
this.title = title;
this.color = color;
}
PieHelper(float startDegree, float endDegree, PieHelper targetPie) {
this.startDegree = startDegree;
this.endDegree = endDegree;
targetStartDegree = targetPie.getStartDegree();
targetEndDegree = targetPie.getEndDegree();
this.sweepDegree = targetPie.getSweep();
this.title = targetPie.getTitle();
this.color = targetPie.getColor();
}
PieHelper setTarget(PieHelper targetPie) {
this.targetStartDegree = targetPie.getStartDegree();
this.targetEndDegree = targetPie.getEndDegree();
this.title = targetPie.getTitle();
this.color = targetPie.getColor();
this.sweepDegree = targetPie.getSweep();
return this;
}
void setDegree(float startDegree, float endDegree) {
this.startDegree = startDegree;
this.endDegree = endDegree;
}
boolean isColorSetted() {
return color != 0;
}
boolean isAtRest() {
return (startDegree == targetStartDegree) && (endDegree == targetEndDegree);
}
void update() {
this.startDegree = updateSelf(startDegree, targetStartDegree, velocity);
this.endDegree = updateSelf(endDegree, targetEndDegree, velocity);
this.sweepDegree = endDegree - startDegree;
}
String getPercentStr() {
float percent = sweepDegree / 360 * 100;
return String.valueOf((int) percent) + "%";
}
public int getColor() {
return color;
}
public String getTitle() {
return title;
}
public float getSweep() {
return sweepDegree;
}
public float getStartDegree() {
return startDegree;
}
public float getEndDegree() {
return endDegree;
}
private float updateSelf(float origin, float target, int velocity) {
if (origin < target) {
origin += velocity;
} else if (origin > target) {
origin -= velocity;
}
if (Math.abs(target - origin) < velocity) {
origin = target;
}
return origin;
}
}
package im.dacer.androidcharts;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
public class PieView extends View {
public static final int NO_SELECTED_INDEX = -1;
private final int[] DEFAULT_COLOR_LIST = {
Color.parseColor("#33B5E5"), Color.parseColor("#AA66CC"), Color.parseColor("#99CC00"),
Color.parseColor("#FFBB33"), Color.parseColor("#FF4444")
};
private Paint cirPaint;
private Paint whiteLinePaint;
private Point pieCenterPoint;
private Paint textPaint;
private RectF cirRect;
private RectF cirSelectedRect;
private int mViewWidth;
private int mViewHeight;
private int margin;
private int pieRadius;
private OnPieClickListener onPieClickListener;
private ArrayList<PieHelper> pieHelperList;
private int selectedIndex = NO_SELECTED_INDEX;
private boolean showPercentLabel = true;
private Runnable animator = new Runnable() {
@Override
public void run() {
boolean needNewFrame = false;
for (PieHelper pie : pieHelperList) {
pie.update();
if (!pie.isAtRest()) {
needNewFrame = true;
}
}
if (needNewFrame) {
postDelayed(this, 10);
}
invalidate();
}
};
public PieView(Context context) {
this(context, null);
}
public PieView(Context context, AttributeSet attrs) {
super(context, attrs);
pieHelperList = new ArrayList<PieHelper>();
cirPaint = new Paint();
cirPaint.setAntiAlias(true);
cirPaint.setColor(Color.GRAY);
whiteLinePaint = new Paint(cirPaint);
whiteLinePaint.setColor(Color.WHITE);
whiteLinePaint.setStrokeWidth(2f);
textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.WHITE);
textPaint.setTextSize(MyUtils.sp2px(getContext(), 13));
textPaint.setStrokeWidth(5);
textPaint.setTextAlign(Paint.Align.CENTER);
pieCenterPoint = new Point();
cirRect = new RectF();
cirSelectedRect = new RectF();
}
public void showPercentLabel(boolean show) {
showPercentLabel = show;
postInvalidate();
}
public void setOnPieClickListener(OnPieClickListener listener) {
onPieClickListener = listener;
}
public void setDate(ArrayList<PieHelper> helperList) {
initPies(helperList);
pieHelperList.clear();
removeSelectedPie();
if (helperList != null && !helperList.isEmpty()) {
for (PieHelper pieHelper : helperList) {
pieHelperList.add(
new PieHelper(pieHelper.getStartDegree(), pieHelper.getStartDegree(),
pieHelper));
}
} else {
pieHelperList.clear();
}
removeCallbacks(animator);
post(animator);
// pieHelperList = helperList;
// postInvalidate();
}
/**
* Set startDegree and endDegree for each PieHelper
*/
private void initPies(ArrayList<PieHelper> helperList) {
float totalAngel = 270;
for (PieHelper pie : helperList) {
pie.setDegree(totalAngel, totalAngel + pie.getSweep());
totalAngel += pie.getSweep();
}
}
public void selectedPie(int index) {
selectedIndex = index;
if (onPieClickListener != null) onPieClickListener.onPieClick(index);
postInvalidate();
}
public void removeSelectedPie() {
selectedIndex = NO_SELECTED_INDEX;
if (onPieClickListener != null) onPieClickListener.onPieClick(NO_SELECTED_INDEX);
postInvalidate();
}
@Override
protected void onDraw(Canvas canvas) {
if (pieHelperList.isEmpty()) {
return;
}
int index = 0;
for (PieHelper pieHelper : pieHelperList) {
boolean selected = (selectedIndex == index);
RectF rect = selected ? cirSelectedRect : cirRect;
if (pieHelper.isColorSetted()) {
cirPaint.setColor(pieHelper.getColor());
} else {
cirPaint.setColor(DEFAULT_COLOR_LIST[index % 5]);
}
canvas.drawArc(rect, pieHelper.getStartDegree(), pieHelper.getSweep(), true, cirPaint);
drawPercentText(canvas, pieHelper);
//drawText(canvas, pieHelper);
drawLineBesideCir(canvas, pieHelper.getStartDegree(), selected);
drawLineBesideCir(canvas, pieHelper.getEndDegree(), selected);
index++;
}
}
private void drawLineBesideCir(Canvas canvas, float angel, boolean selectedCir) {
int sth2 = selectedCir ? mViewHeight / 2
: pieRadius; // Sorry I'm really don't know how to name the variable..
int sth = 1; // And it's
if (angel % 360 > 180 && angel % 360 < 360) {
sth = -1;
}
float lineToX = (float) (mViewHeight / 2 + Math.cos(Math.toRadians(-angel)) * sth2);
float lineToY =
(float) (mViewHeight / 2 + sth * Math.abs(Math.sin(Math.toRadians(-angel))) * sth2);
canvas.drawLine(pieCenterPoint.x, pieCenterPoint.y, lineToX, lineToY, whiteLinePaint);
}
private void drawPercentText(Canvas canvas, PieHelper pieHelper) {
if (!showPercentLabel) return;
float angel = (pieHelper.getStartDegree() + pieHelper.getEndDegree()) / 2;
int sth = 1;
if (angel % 360 > 180 && angel % 360 < 360) {
sth = -1;
}
float x = (float) (mViewHeight / 2 + Math.cos(Math.toRadians(-angel)) * pieRadius / 2);
float y = (float) (mViewHeight / 2
+ sth * Math.abs(Math.sin(Math.toRadians(-angel))) * pieRadius / 2);
canvas.drawText(pieHelper.getPercentStr(), x, y, textPaint);
canvas.drawText(pieHelper.getTitle(), x, y + 30, textPaint);
}
private void drawText(Canvas canvas, PieHelper pieHelper) {
if (pieHelper.getTitle() == null) return;
float angel = (pieHelper.getStartDegree() + pieHelper.getEndDegree()) / 2;
int sth = 1;
if (angel % 360 > 180 && angel % 360 < 360) {
sth = -1;
}
float x = (float) (mViewHeight / 2 + Math.cos(Math.toRadians(-angel)) * pieRadius / 2);
float y = (float) (mViewHeight / 2
+ sth * Math.abs(Math.sin(Math.toRadians(-angel))) * pieRadius / 2);
canvas.drawText(pieHelper.getTitle(), x, y, textPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
int clickedIndex = findPointAt((int) event.getX(), (int) event.getY());
if (clickedIndex == selectedIndex) {
selectedIndex = NO_SELECTED_INDEX;
} else {
selectedIndex = clickedIndex;
}
if (onPieClickListener != null) {
onPieClickListener.onPieClick(selectedIndex);
}
postInvalidate();
}
return true;
}
/**
* find pie index where point is
*/
private int findPointAt(int x, int y) {
double degree = Math.atan2(x - pieCenterPoint.x, y - pieCenterPoint.y) * 180 / Math.PI;
degree = -(degree - 180) + 270;
int index = 0;
for (PieHelper pieHelper : pieHelperList) {
if (degree >= pieHelper.getStartDegree() && degree <= pieHelper.getEndDegree()) {
return index;
}
index++;
}
return NO_SELECTED_INDEX;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mViewWidth = measureWidth(widthMeasureSpec);
mViewHeight = measureHeight(heightMeasureSpec);
margin = mViewWidth / 16;
pieRadius = (mViewWidth) / 2 - margin;
pieCenterPoint.set(pieRadius + margin, pieRadius + margin);
cirRect.set(pieCenterPoint.x - pieRadius, pieCenterPoint.y - pieRadius,
pieCenterPoint.x + pieRadius, pieCenterPoint.y + pieRadius);
cirSelectedRect.set(2, //minor margin for bigger circle
2, mViewWidth - 2, mViewHeight - 2);
setMeasuredDimension(mViewWidth, mViewHeight);
}
private int measureWidth(int measureSpec) {
int preferred = 3;
return getMeasurement(measureSpec, preferred);
}
private int measureHeight(int measureSpec) {
int preferred = mViewWidth;
return getMeasurement(measureSpec, preferred);
}
private int getMeasurement(int measureSpec, int preferred) {
int specSize = View.MeasureSpec.getSize(measureSpec);
int measurement;
switch (View.MeasureSpec.getMode(measureSpec)) {
case View.MeasureSpec.EXACTLY:
measurement = specSize;
break;
case View.MeasureSpec.AT_MOST:
measurement = Math.min(preferred, specSize);
break;
default:
measurement = preferred;
break;
}
return measurement;
}
public interface OnPieClickListener {
void onPieClick(int index);
}
}
How to Set Title (Kotlin Code) :
var pieHelperArrayList = ArrayList
Please try to remove below line and check; canvas.drawText(pieHelper.getPercentStr(), x, y, textPaint); canvas.drawText(pieHelper.getTitle(), x, y + 30, textPaint);
On Tue, 6 Aug 2019 at 21:20, feifeikuaifeiba notifications@github.com wrote:
What's the point of displaying pie charts without any label information ?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/HackPlan/AndroidCharts/issues/32?email_source=notifications&email_token=ALX4IM4VO7BGR5TYHDTCUWTQDGMTBA5CNFSM4FAH67D2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3VS6GQ#issuecomment-518729498, or mute the thread https://github.com/notifications/unsubscribe-auth/ALX4IM2QLFSPDS7MX3ZHYMTQDGMTBANCNFSM4FAH67DQ .
What's the point of displaying pie charts without any label information ?