summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/danoeh/antennapod/view/PieChartView.java
blob: aaa685396513c76613a7ea7af8886dd6f4eed8a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package de.danoeh.antennapod.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import io.reactivex.annotations.Nullable;

public class PieChartView extends AppCompatImageView {
    private PieChartDrawable drawable;

    public PieChartView(Context context) {
        super(context);
        setup();
    }

    public PieChartView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setup();
    }

    public PieChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setup();
    }

    @SuppressLint("ClickableViewAccessibility")
    private void setup() {
        drawable = new PieChartDrawable();
        setImageDrawable(drawable);
    }

    /**
     * Set array od names, array of values and array of colors.
     */
    public void setData(float[] dataValues) {
        drawable.dataValues = dataValues;
        drawable.valueSum = 0;
        for (float datum : dataValues) {
            drawable.valueSum += datum;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = getMeasuredWidth();
        setMeasuredDimension(width, width / 2);
    }

    private static class PieChartDrawable extends Drawable {
        private static final float MIN_DEGREES = 10f;
        private static final float PADDING_DEGREES = 3f;
        private static final float STROKE_SIZE = 15f;
        private static final int[] COLOR_VALUES = new int[]{0xFF3775E6, 0xffe51c23, 0xffff9800, 0xff259b24, 0xff9c27b0,
                0xff0099c6, 0xffdd4477, 0xff66aa00, 0xffb82e2e, 0xff316395,
                0xff994499, 0xff22aa99, 0xffaaaa11, 0xff6633cc, 0xff0073e6};
        private float[] dataValues;
        private float valueSum;
        private final Paint paint;

        private PieChartDrawable() {
            paint = new Paint();
            paint.setFlags(Paint.ANTI_ALIAS_FLAG);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeJoin(Paint.Join.ROUND);
            paint.setStrokeCap(Paint.Cap.ROUND);
            paint.setStrokeWidth(STROKE_SIZE);
        }

        @Override
        public void draw(@NonNull Canvas canvas) {
            if (valueSum == 0) {
                return;
            }
            float radius = getBounds().height() - STROKE_SIZE;
            float center = getBounds().width() / 2.f;
            RectF arcBounds = new RectF(center - radius, STROKE_SIZE, center + radius, STROKE_SIZE + radius * 2);

            float startAngle = 180;
            for (int i = 0; i < dataValues.length; i++) {
                float datum = dataValues[i];
                float sweepAngle = 180 * datum / valueSum;
                if (sweepAngle < MIN_DEGREES) {
                    break;
                }
                paint.setColor(COLOR_VALUES[i % COLOR_VALUES.length]);
                float padding = i == 0 ? PADDING_DEGREES / 2 : PADDING_DEGREES;
                canvas.drawArc(arcBounds, startAngle + padding, sweepAngle - padding, false, paint);
                startAngle = startAngle + sweepAngle;
            }

            paint.setColor(Color.GRAY);
            float sweepAngle = 360 - startAngle - PADDING_DEGREES / 2;
            if (sweepAngle > PADDING_DEGREES) {
                canvas.drawArc(arcBounds, startAngle + PADDING_DEGREES, sweepAngle - PADDING_DEGREES, false, paint);
            }
        }

        @Override
        public int getOpacity() {
            return PixelFormat.TRANSLUCENT;
        }

        @Override
        public void setAlpha(int alpha) {
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
        }
    }
}