diff options
author | ByteHamster <info@bytehamster.com> | 2022-02-20 12:07:21 +0100 |
---|---|---|
committer | ByteHamster <info@bytehamster.com> | 2022-02-21 22:54:40 +0100 |
commit | 7ab6d08ea589aae7db2f7bdf1b28833f45ba9943 (patch) | |
tree | 3cb1943e5640e65f8876e4053d131f88a3df66fe /app/src/main/java/de/danoeh/antennapod/view | |
parent | b6d23168707bd55e5bb4060a9cd8e8ecf96a9716 (diff) | |
download | AntennaPod-7ab6d08ea589aae7db2f7bdf1b28833f45ba9943.zip |
Add line graph to statistics screen
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod/view')
-rw-r--r-- | app/src/main/java/de/danoeh/antennapod/view/LineChartView.java | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/view/LineChartView.java b/app/src/main/java/de/danoeh/antennapod/view/LineChartView.java new file mode 100644 index 000000000..0eb225e8e --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/view/LineChartView.java @@ -0,0 +1,138 @@ +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.DashPathEffect; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PixelFormat; +import android.graphics.Shader; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import androidx.annotation.NonNull; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.appcompat.widget.ThemeUtils; +import de.danoeh.antennapod.R; +import io.reactivex.annotations.Nullable; + +public class LineChartView extends AppCompatImageView { + private LineChartDrawable drawable; + + public LineChartView(Context context) { + super(context); + setup(); + } + + public LineChartView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + setup(); + } + + public LineChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + setup(); + } + + @SuppressLint("ClickableViewAccessibility") + private void setup() { + drawable = new LineChartDrawable(); + setImageDrawable(drawable); + } + + /** + * Set of data values to display. + */ + public void setData(LineChartData data) { + drawable.data = data; + } + + public static class LineChartData { + private final long valueMax; + private final long[] values; + private final long[] verticalLines; + + public LineChartData(long[] values, long[] verticalLines) { + this.values = values; + long valueMax = 0; + for (long datum : values) { + valueMax = Math.max(datum, valueMax); + } + this.valueMax = valueMax; + this.verticalLines = verticalLines; + } + + public float getHeight(int item) { + return (float) values[item] / valueMax; + } + } + + private class LineChartDrawable extends Drawable { + private LineChartData data; + private final Paint paintLine; + private final Paint paintBackground; + private final Paint paintVerticalLines; + + private LineChartDrawable() { + paintLine = new Paint(); + paintLine.setFlags(Paint.ANTI_ALIAS_FLAG); + paintLine.setStyle(Paint.Style.STROKE); + paintLine.setStrokeJoin(Paint.Join.ROUND); + paintLine.setStrokeCap(Paint.Cap.ROUND); + paintLine.setColor(ThemeUtils.getThemeAttrColor(getContext(), R.attr.colorAccent)); + paintBackground = new Paint(); + paintBackground.setStyle(Paint.Style.FILL); + paintVerticalLines = new Paint(); + paintVerticalLines.setStyle(Paint.Style.STROKE); + paintVerticalLines.setPathEffect(new DashPathEffect(new float[] {10f, 10f}, 0f)); + paintVerticalLines.setColor(0x66777777); + } + + @Override + public void draw(@NonNull Canvas canvas) { + float width = getBounds().width(); + float height = getBounds().height(); + float usableHeight = height * 0.9f; + float stepSize = width / (data.values.length + 1); + + paintVerticalLines.setStrokeWidth(height * 0.005f); + for (long line : data.verticalLines) { + canvas.drawLine((line + 1) * stepSize, 0, (line + 1) * stepSize, height, paintVerticalLines); + } + + paintLine.setStrokeWidth(height * 0.015f); + Path path = new Path(); + for (int i = 0; i < data.values.length; i++) { + if (i == 0) { + path.moveTo((i + 1) * stepSize, (1 - data.getHeight(i)) * usableHeight + height * 0.05f); + } else { + path.lineTo((i + 1) * stepSize, (1 - data.getHeight(i)) * usableHeight + height * 0.05f); + } + } + canvas.drawPath(path, paintLine); + + path.lineTo(data.values.length * stepSize, height); + path.lineTo(stepSize, height); + paintBackground.setShader(new LinearGradient(0, 0, 0, height, + (ThemeUtils.getThemeAttrColor(getContext(), R.attr.colorAccent) & 0xffffff) + 0x66000000, + Color.TRANSPARENT, Shader.TileMode.CLAMP)); + canvas.drawPath(path, paintBackground); + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + @Override + public void setAlpha(int alpha) { + } + + @Override + public void setColorFilter(ColorFilter cf) { + } + } +} |