Android Open Source - AndroidCharts Pie View






From Project

Back to project page AndroidCharts.

License

The source code is released under:

MIT License

If you think the Android project AndroidCharts listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.dacer.androidcharts;
//from  www .j a  va  2  s  .  com
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;

/**
 * Created by Dacer on 9/26/14.
 */
public class PieView extends View {

    public interface OnPieClickListener{
        void onPieClick(int index);
    }

    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;
    public static final int NO_SELECTED_INDEX = -999;
    private final int[] DEFAULT_COLOR_LIST = {Color.parseColor("#33B5E5"),
            Color.parseColor("#AA66CC"),
            Color.parseColor("#99CC00"),
            Color.parseColor("#FFBB33"),
            Color.parseColor("#FF4444")};


    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
     * @param helperList
     */
    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);

            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);
    }

    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_DOWN ||event.getAction() == MotionEvent.ACTION_MOVE){
            selectedIndex = findPointAt((int) event.getX(), (int) event.getY());
            if(onPieClickListener != null){
                onPieClickListener.onPieClick(selectedIndex);
            }
            postInvalidate();
        }

        return true;
    }

    /**
     * find pie index where point is
     * @param x
     * @param y
     * @return
     */
    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;
    }
}




Java Source Code List

com.dacer.androidcharts.BarView.java
com.dacer.androidcharts.ClockPieHelper.java
com.dacer.androidcharts.ClockPieView.java
com.dacer.androidcharts.LineView.java
com.dacer.androidcharts.MyUtils.java
com.dacer.androidcharts.PieHelper.java
com.dacer.androidcharts.PieView.java
com.dacer.androidcharts.TempLog.java
com.dacer.androidchartsexample.BarFragment.java
com.dacer.androidchartsexample.ClockPieFragment.java
com.dacer.androidchartsexample.LineFragment.java
com.dacer.androidchartsexample.MainActivity.java
com.dacer.androidchartsexample.NavigationDrawerFragment.java
com.dacer.androidchartsexample.PieFragment.java