From 67a5442bc4c1adc8be4b0106e554cf546d6404a1 Mon Sep 17 00:00:00 2001 From: Mohini Katara Date: Wed, 4 Oct 2023 17:50:32 +0530 Subject: [PATCH 1/6] Add RoundedBar renderer for corner radius positive/negative BarChart --- .../renderer/RoundedBarChartRenderer.java | 324 ++++++++++++++++++ .../RoundedHorizontalBarChartRenderer.java | 242 +++++++++++++ 2 files changed, 566 insertions(+) create mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java create mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java new file mode 100644 index 0000000000..86d3ce4799 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java @@ -0,0 +1,324 @@ +package com.github.mikephil.charting.renderer; + +import android.graphics.Canvas; +import android.graphics.LinearGradient; +import android.graphics.Path; +import android.graphics.RectF; +import android.graphics.Shader; + +import com.github.mikephil.charting.animation.ChartAnimator; +import com.github.mikephil.charting.buffer.BarBuffer; +import com.github.mikephil.charting.data.BarData; +import com.github.mikephil.charting.data.BarEntry; +import com.github.mikephil.charting.highlight.Highlight; +import com.github.mikephil.charting.highlight.Range; +import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider; +import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; +import com.github.mikephil.charting.utils.Transformer; +import com.github.mikephil.charting.utils.Utils; +import com.github.mikephil.charting.utils.ViewPortHandler; + +public class RoundedBarChartRenderer extends BarChartRenderer { + + public RoundedBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) { + super(chart, animator, viewPortHandler); + } + private final RectF mBarShadowRectBuffer = new RectF(); + private float mRadius = 20f; + private float roundedShadowRadius = 0f; + private float roundedPositiveDataSetRadius = 0f; + private float roundedNegativeDataSetRadius = 0f; + public void setRoundedNegativeDataSetRadius(float roundedNegativeDataSet) { + roundedNegativeDataSetRadius = roundedNegativeDataSet; + } + public void setRoundedShadowRadius(float roundedShadow) { + roundedShadowRadius = roundedShadow; + } + public void setRoundedPositiveDataSetRadius(float roundedPositiveDataSet) { + roundedPositiveDataSetRadius = roundedPositiveDataSet; + } + + @Override + protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { + initBuffers(); + Transformer trans = mChart.getTransformer(dataSet.getAxisDependency()); + mBarBorderPaint.setColor(dataSet.getBarBorderColor()); + mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth())); + mShadowPaint.setColor(dataSet.getBarShadowColor()); + boolean drawBorder = dataSet.getBarBorderWidth() > 0f; + float phaseX = mAnimator.getPhaseX(); + float phaseY = mAnimator.getPhaseY(); + + if (mChart.isDrawBarShadowEnabled()) { + mShadowPaint.setColor(dataSet.getBarShadowColor()); + BarData barData = mChart.getBarData(); + float barWidth = barData.getBarWidth(); + float barWidthHalf = barWidth / 2.0f; + float x; + int i = 0; + double count = Math.min(Math.ceil((int) (double) ((float) dataSet.getEntryCount() * phaseX)), dataSet.getEntryCount()); + while (i < count) { + BarEntry e = dataSet.getEntryForIndex(i); + x = e.getX(); + mBarShadowRectBuffer.left = x - barWidthHalf; + mBarShadowRectBuffer.right = x + barWidthHalf; + trans.rectValueToPixel(mBarShadowRectBuffer); + if (!mViewPortHandler.isInBoundsLeft(mBarShadowRectBuffer.right)) { + i++; + continue; + } + if (!mViewPortHandler.isInBoundsRight(mBarShadowRectBuffer.left)) + break; + mBarShadowRectBuffer.top = mViewPortHandler.contentTop(); + mBarShadowRectBuffer.bottom = mViewPortHandler.contentBottom(); + + + if (roundedShadowRadius >0) { + c.drawRoundRect(mBarRect, roundedShadowRadius, roundedShadowRadius, mShadowPaint); + } else { + c.drawRect(mBarShadowRectBuffer, mShadowPaint); + } + i++; + } + } + + BarBuffer buffer = mBarBuffers[index]; + buffer.setPhases(phaseX, phaseY); + buffer.setDataSet(index); + buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency())); + buffer.setBarWidth(mChart.getBarData().getBarWidth()); + buffer.feed(dataSet); + trans.pointValuesToPixel(buffer.buffer); + + // if multiple colors has been assigned to Bar Chart + if (dataSet.getColors().size() > 1) { + + for (int j = 0; j < buffer.size(); j += 4) { + + if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) + continue; + + if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) + break; + + if (mChart.isDrawBarShadowEnabled()) { + if (roundedShadowRadius >0) + c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), + buffer.buffer[j + 2], + mViewPortHandler.contentBottom()), roundedShadowRadius, roundedShadowRadius, mShadowPaint); + else + c.drawRect(buffer.buffer[j], mViewPortHandler.contentTop(), + buffer.buffer[j + 2], + mViewPortHandler.contentBottom(), mShadowPaint); + } + + // Set the color for the currently drawn value. If the index + mRenderPaint.setColor(dataSet.getColor(j / 4)); + + if (roundedPositiveDataSetRadius >0) + c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, mRenderPaint); + else + c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3], mRenderPaint); + } + } else { + + mRenderPaint.setColor(dataSet.getColor()); + + for (int j = 0; j < buffer.size(); j += 4) { + + if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) + continue; + + if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) + break; + + if (mChart.isDrawBarShadowEnabled()) { + if (roundedShadowRadius >0) + c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), + buffer.buffer[j + 2], + mViewPortHandler.contentBottom()), roundedShadowRadius, roundedShadowRadius, mShadowPaint); + else + c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3], mRenderPaint); + } + + if (roundedPositiveDataSetRadius >0) + c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, mRenderPaint); + else + c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3], mRenderPaint); + } + } + + + boolean isSingleColor = dataSet.getColors().size() == 1; + if (isSingleColor) { + mRenderPaint.setColor(dataSet.getColor(index)); + } + + int j = 0; + while (j < buffer.size()) { + + if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) { + j += 4; + continue; + } + + if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) + break; + + if (!isSingleColor) { + mRenderPaint.setColor(dataSet.getColor(j/4)); + } + + mRenderPaint.setShader(new LinearGradient( + buffer.buffer[j], + buffer.buffer[j + 3], + buffer.buffer[j], + buffer.buffer[j + 1], + dataSet.getColor(j/4), + dataSet.getColor(j/4), + Shader.TileMode.MIRROR)); + + mRenderPaint.setShader(new LinearGradient( + buffer.buffer[j], + buffer.buffer[j + 3], + buffer.buffer[j], + buffer.buffer[j + 1], + dataSet.getColor(j/4), + dataSet.getColor(j/4), + Shader.TileMode.MIRROR)); + + + if((dataSet.getEntryForIndex(j/4).getY()<0 && roundedNegativeDataSetRadius >0)) { + Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedNegativeDataSetRadius, roundedNegativeDataSetRadius, true, true, true, true); + c.drawPath(path2, mRenderPaint); + } else if((dataSet.getEntryForIndex(j/4).getY()>0 && roundedPositiveDataSetRadius >0)){ + Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, true, true, true, true); + c.drawPath(path2, mRenderPaint); + } + else { + c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3], mRenderPaint); + } + + j += 4; + } + + } + + @Override + public void drawHighlighted(Canvas c, Highlight[] indices) { + BarData barData = mChart.getBarData(); + + for (Highlight high : indices) { + + IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex()); + + if (set == null || !set.isHighlightEnabled()) { + continue; + } + + BarEntry e = set.getEntryForXValue(high.getX(), high.getY()); + + if (!isInBoundsX(e, set)) { + continue; + } + + Transformer trans = mChart.getTransformer(set.getAxisDependency()); + + mHighlightPaint.setColor(set.getHighLightColor()); + mHighlightPaint.setAlpha(set.getHighLightAlpha()); + + boolean isStack = high.getStackIndex() >= 0 && e.isStacked(); + + final float y1; + final float y2; + + if (isStack) { + + if (mChart.isHighlightFullBarEnabled()) { + + y1 = e.getPositiveSum(); + y2 = -e.getNegativeSum(); + + } else { + + Range range = e.getRanges()[high.getStackIndex()]; + + y1 = range.from; + y2 = range.to; + } + + } else { + y1 = e.getY(); + y2 = 0.f; + } + + prepareBarHighlight(e.getX(), y1, y2, barData.getBarWidth() / 2f, trans); + + setHighlightDrawPos(high, mBarRect); + + Path path2 = roundRect(new RectF(mBarRect.left, mBarRect.top, mBarRect.right, + mBarRect.bottom), mRadius, mRadius, true, true, true, true); + + c.drawPath(path2, mHighlightPaint); + } + } + + private Path roundRect(RectF rect, float rx, float ry, boolean tl, boolean tr, boolean br, boolean bl) { + float top = rect.top; + float left = rect.left; + float right = rect.right; + float bottom = rect.bottom; + Path path = new Path(); + if (rx < 0) rx = 0; + if (ry < 0) ry = 0; + float width = right - left; + float height = bottom - top; + if (rx > width / 2) rx = width / 2; + if (ry > height / 2) ry = height / 2; + float widthMinusCorners = (width - (2 * rx)); + float heightMinusCorners = (height - (2 * ry)); + + path.moveTo(right, top + ry); + if (tr) + path.rQuadTo(0, -ry, -rx, -ry);//top-right corner + else { + path.rLineTo(0, -ry); + path.rLineTo(-rx, 0); + } + path.rLineTo(-widthMinusCorners, 0); + if (tl) + path.rQuadTo(-rx, 0, -rx, ry); //top-left corner + else { + path.rLineTo(-rx, 0); + path.rLineTo(0, ry); + } + path.rLineTo(0, heightMinusCorners); + + if (bl) + path.rQuadTo(0, ry, rx, ry);//bottom-left corner + else { + path.rLineTo(0, ry); + path.rLineTo(rx, 0); + } + + path.rLineTo(widthMinusCorners, 0); + if (br) + path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner + else { + path.rLineTo(rx, 0); + path.rLineTo(0, -ry); + } + + path.rLineTo(0, -heightMinusCorners); + path.close(); + return path; + } +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java new file mode 100644 index 0000000000..9d14a321ba --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java @@ -0,0 +1,242 @@ +package com.github.mikephil.charting.renderer; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RectF; + +import com.github.mikephil.charting.animation.ChartAnimator; +import com.github.mikephil.charting.buffer.BarBuffer; +import com.github.mikephil.charting.data.BarData; +import com.github.mikephil.charting.data.BarEntry; +import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider; +import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; +import com.github.mikephil.charting.utils.Transformer; +import com.github.mikephil.charting.utils.Utils; +import com.github.mikephil.charting.utils.ViewPortHandler; + +public class RoundedHorizontalBarChartRenderer extends HorizontalBarChartRenderer { + + private final RectF mBarShadowRectBuffer = new RectF(); + private float roundedShadowRadius = 0f; + private float roundedPositiveDataSetRadius = 0f; + private float roundedNegativeDataSetRadius = 0f; + public void setRoundedNegativeDataSetRadius(float roundedNegativeDataSet) { + roundedNegativeDataSetRadius = roundedNegativeDataSet; + } + public void setRoundedShadowRadius(float roundedShadow) { + roundedShadowRadius = roundedShadow; + } + public void setRoundedPositiveDataSetRadius(float roundedPositiveDataSet) { + roundedPositiveDataSetRadius = roundedPositiveDataSet; + } + public RoundedHorizontalBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) { + super(chart, animator, viewPortHandler); + + mValuePaint.setTextAlign(Paint.Align.LEFT); + } + + @Override + protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { + initBuffers(); + Transformer trans = mChart.getTransformer(dataSet.getAxisDependency()); + mBarBorderPaint.setColor(dataSet.getBarBorderColor()); + mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth())); + mShadowPaint.setColor(dataSet.getBarShadowColor()); + boolean drawBorder = dataSet.getBarBorderWidth() > 0f; + float phaseX = mAnimator.getPhaseX(); + float phaseY = mAnimator.getPhaseY(); + + if (mChart.isDrawBarShadowEnabled()) { + mShadowPaint.setColor(dataSet.getBarShadowColor()); + BarData barData = mChart.getBarData(); + float barWidth = barData.getBarWidth(); + float barWidthHalf = barWidth / 2.0f; + float x; + int i = 0; + double count = Math.min(Math.ceil((int) (double) ((float) dataSet.getEntryCount() * phaseX)), dataSet.getEntryCount()); + while (i < count) { + BarEntry e = dataSet.getEntryForIndex(i); + x = e.getX(); + mBarShadowRectBuffer.top = x - barWidthHalf; + mBarShadowRectBuffer.bottom = x + barWidthHalf; + trans.rectValueToPixel(mBarShadowRectBuffer); + if (!mViewPortHandler.isInBoundsTop(mBarShadowRectBuffer.bottom)) { + i++; + continue; + } + if (!mViewPortHandler.isInBoundsBottom(mBarShadowRectBuffer.top)) + break; + mBarShadowRectBuffer.left = mViewPortHandler.contentLeft(); + mBarShadowRectBuffer.right = mViewPortHandler.contentRight(); + + + if (roundedShadowRadius >0) { + c.drawRoundRect(mBarRect, roundedShadowRadius, roundedShadowRadius, mShadowPaint); + } else { + c.drawRect(mBarShadowRectBuffer, mShadowPaint); + } + i++; + } + } + + BarBuffer buffer = mBarBuffers[index]; + buffer.setPhases(phaseX, phaseY); + buffer.setDataSet(index); + buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency())); + buffer.setBarWidth(mChart.getBarData().getBarWidth()); + buffer.feed(dataSet); + trans.pointValuesToPixel(buffer.buffer); + + // if multiple colors has been assigned to Bar Chart + if (dataSet.getColors().size() > 1) { + + for (int j = 0; j < buffer.size(); j += 4) { + + if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3])) + continue; + + if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j+1])) + break; + + if (mChart.isDrawBarShadowEnabled()) { + if (roundedShadowRadius >0) + c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), + buffer.buffer[j + 2], + mViewPortHandler.contentBottom()), roundedShadowRadius, roundedShadowRadius, mShadowPaint); + else + c.drawRect(buffer.buffer[j], mViewPortHandler.contentTop(), + buffer.buffer[j + 2], + mViewPortHandler.contentBottom(), mShadowPaint); + } + + // Set the color for the currently drawn value. If the index + mRenderPaint.setColor(dataSet.getColor(j / 4)); + + if (roundedPositiveDataSetRadius >0) + c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, mRenderPaint); + else + c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3], mRenderPaint); + } + } else { + + mRenderPaint.setColor(dataSet.getColor()); + + for (int j = 0; j < buffer.size(); j += 4) { + + if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3])) + continue; + + if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j+1])) + break; + + if (mChart.isDrawBarShadowEnabled()) { + if (roundedShadowRadius >0) + c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), + buffer.buffer[j + 2], + mViewPortHandler.contentBottom()), roundedShadowRadius, roundedShadowRadius, mShadowPaint); + else + c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3], mRenderPaint); + } + + if (roundedPositiveDataSetRadius >0) + c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, mRenderPaint); + else + c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3], mRenderPaint); + } + } + + + boolean isSingleColor = dataSet.getColors().size() == 1; + if (isSingleColor) { + mRenderPaint.setColor(dataSet.getColor(index)); + } + + int j = 0; + while (j < buffer.size()) { + + if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3])) { + j += 4; + continue; + } + + if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j+1])) + break; + + if (!isSingleColor) { + mRenderPaint.setColor(dataSet.getColor(j/4)); + } + + if((dataSet.getEntryForIndex(j/4).getY()<0 && roundedNegativeDataSetRadius >0)) { + Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedNegativeDataSetRadius, roundedNegativeDataSetRadius, true, true, true, true); + c.drawPath(path2, mRenderPaint); + } else if((dataSet.getEntryForIndex(j/4).getY()>0 && roundedPositiveDataSetRadius >0)){ + Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, true, true, true, true); + c.drawPath(path2, mRenderPaint); + } + else { + c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3], mRenderPaint); + } + j += 4; + } + } + + private Path roundRect(RectF rect, float rx, float ry, boolean tl, boolean tr, boolean br, boolean bl) { + float top = rect.top; + float left = rect.left; + float right = rect.right; + float bottom = rect.bottom; + Path path = new Path(); + if (rx < 0) rx = 0; + if (ry < 0) ry = 0; + float width = right - left; + float height = bottom - top; + if (rx > width / 2) rx = width / 2; + if (ry > height / 2) ry = height / 2; + float widthMinusCorners = (width - (2 * rx)); + float heightMinusCorners = (height - (2 * ry)); + + path.moveTo(right, top + ry); + if (tr) + path.rQuadTo(0, -ry, -rx, -ry);//top-right corner + else { + path.rLineTo(0, -ry); + path.rLineTo(-rx, 0); + } + path.rLineTo(-widthMinusCorners, 0); + if (tl) + path.rQuadTo(-rx, 0, -rx, ry); //top-left corner + else { + path.rLineTo(-rx, 0); + path.rLineTo(0, ry); + } + path.rLineTo(0, heightMinusCorners); + + if (bl) + path.rQuadTo(0, ry, rx, ry);//bottom-left corner + else { + path.rLineTo(0, ry); + path.rLineTo(rx, 0); + } + + path.rLineTo(widthMinusCorners, 0); + if (br) + path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner + else { + path.rLineTo(rx, 0); + path.rLineTo(0, -ry); + } + + path.rLineTo(0, -heightMinusCorners); + path.close(); + return path; + } +} From fbf7b21aa35965cef7b2abfad3ed1f726afd5090 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sat, 22 Jun 2024 06:48:00 +0200 Subject: [PATCH 2/6] Format code --- .../renderer/RoundedBarChartRenderer.java | 451 +++++++++--------- .../RoundedHorizontalBarChartRenderer.java | 339 +++++++------ 2 files changed, 416 insertions(+), 374 deletions(-) diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java index 86d3ce4799..f99eba4b79 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java @@ -20,305 +20,326 @@ public class RoundedBarChartRenderer extends BarChartRenderer { - public RoundedBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) { - super(chart, animator, viewPortHandler); - } - private final RectF mBarShadowRectBuffer = new RectF(); - private float mRadius = 20f; - private float roundedShadowRadius = 0f; - private float roundedPositiveDataSetRadius = 0f; - private float roundedNegativeDataSetRadius = 0f; - public void setRoundedNegativeDataSetRadius(float roundedNegativeDataSet) { - roundedNegativeDataSetRadius = roundedNegativeDataSet; - } - public void setRoundedShadowRadius(float roundedShadow) { - roundedShadowRadius = roundedShadow; - } - public void setRoundedPositiveDataSetRadius(float roundedPositiveDataSet) { - roundedPositiveDataSetRadius = roundedPositiveDataSet; - } - - @Override - protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { - initBuffers(); - Transformer trans = mChart.getTransformer(dataSet.getAxisDependency()); - mBarBorderPaint.setColor(dataSet.getBarBorderColor()); - mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth())); - mShadowPaint.setColor(dataSet.getBarShadowColor()); - boolean drawBorder = dataSet.getBarBorderWidth() > 0f; - float phaseX = mAnimator.getPhaseX(); - float phaseY = mAnimator.getPhaseY(); - - if (mChart.isDrawBarShadowEnabled()) { - mShadowPaint.setColor(dataSet.getBarShadowColor()); - BarData barData = mChart.getBarData(); - float barWidth = barData.getBarWidth(); - float barWidthHalf = barWidth / 2.0f; - float x; - int i = 0; - double count = Math.min(Math.ceil((int) (double) ((float) dataSet.getEntryCount() * phaseX)), dataSet.getEntryCount()); - while (i < count) { - BarEntry e = dataSet.getEntryForIndex(i); - x = e.getX(); - mBarShadowRectBuffer.left = x - barWidthHalf; - mBarShadowRectBuffer.right = x + barWidthHalf; - trans.rectValueToPixel(mBarShadowRectBuffer); - if (!mViewPortHandler.isInBoundsLeft(mBarShadowRectBuffer.right)) { - i++; - continue; - } - if (!mViewPortHandler.isInBoundsRight(mBarShadowRectBuffer.left)) + public RoundedBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) { + super(chart, animator, viewPortHandler); + } + + private final RectF mBarShadowRectBuffer = new RectF(); + private float mRadius = 20f; + private float roundedShadowRadius = 0f; + private float roundedPositiveDataSetRadius = 0f; + private float roundedNegativeDataSetRadius = 0f; + + public void setRoundedNegativeDataSetRadius(float roundedNegativeDataSet) { + roundedNegativeDataSetRadius = roundedNegativeDataSet; + } + + public void setRoundedShadowRadius(float roundedShadow) { + roundedShadowRadius = roundedShadow; + } + + public void setRoundedPositiveDataSetRadius(float roundedPositiveDataSet) { + roundedPositiveDataSetRadius = roundedPositiveDataSet; + } + + @Override + protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { + initBuffers(); + Transformer trans = mChart.getTransformer(dataSet.getAxisDependency()); + mBarBorderPaint.setColor(dataSet.getBarBorderColor()); + mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth())); + mShadowPaint.setColor(dataSet.getBarShadowColor()); + boolean drawBorder = dataSet.getBarBorderWidth() > 0f; + float phaseX = mAnimator.getPhaseX(); + float phaseY = mAnimator.getPhaseY(); + + if (mChart.isDrawBarShadowEnabled()) { + mShadowPaint.setColor(dataSet.getBarShadowColor()); + BarData barData = mChart.getBarData(); + float barWidth = barData.getBarWidth(); + float barWidthHalf = barWidth / 2.0f; + float x; + int i = 0; + double count = Math.min(Math.ceil((int) (double) ((float) dataSet.getEntryCount() * phaseX)), dataSet.getEntryCount()); + while (i < count) { + BarEntry e = dataSet.getEntryForIndex(i); + x = e.getX(); + mBarShadowRectBuffer.left = x - barWidthHalf; + mBarShadowRectBuffer.right = x + barWidthHalf; + trans.rectValueToPixel(mBarShadowRectBuffer); + if (!mViewPortHandler.isInBoundsLeft(mBarShadowRectBuffer.right)) { + i++; + continue; + } + if (!mViewPortHandler.isInBoundsRight(mBarShadowRectBuffer.left)) { break; - mBarShadowRectBuffer.top = mViewPortHandler.contentTop(); - mBarShadowRectBuffer.bottom = mViewPortHandler.contentBottom(); + } + mBarShadowRectBuffer.top = mViewPortHandler.contentTop(); + mBarShadowRectBuffer.bottom = mViewPortHandler.contentBottom(); - if (roundedShadowRadius >0) { - c.drawRoundRect(mBarRect, roundedShadowRadius, roundedShadowRadius, mShadowPaint); - } else { - c.drawRect(mBarShadowRectBuffer, mShadowPaint); - } - i++; - } - } + if (roundedShadowRadius > 0) { + c.drawRoundRect(mBarRect, roundedShadowRadius, roundedShadowRadius, mShadowPaint); + } else { + c.drawRect(mBarShadowRectBuffer, mShadowPaint); + } + i++; + } + } - BarBuffer buffer = mBarBuffers[index]; - buffer.setPhases(phaseX, phaseY); - buffer.setDataSet(index); - buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency())); - buffer.setBarWidth(mChart.getBarData().getBarWidth()); - buffer.feed(dataSet); - trans.pointValuesToPixel(buffer.buffer); + BarBuffer buffer = mBarBuffers[index]; + buffer.setPhases(phaseX, phaseY); + buffer.setDataSet(index); + buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency())); + buffer.setBarWidth(mChart.getBarData().getBarWidth()); + buffer.feed(dataSet); + trans.pointValuesToPixel(buffer.buffer); - // if multiple colors has been assigned to Bar Chart - if (dataSet.getColors().size() > 1) { + // if multiple colors has been assigned to Bar Chart + if (dataSet.getColors().size() > 1) { - for (int j = 0; j < buffer.size(); j += 4) { + for (int j = 0; j < buffer.size(); j += 4) { - if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) + if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) { continue; + } - if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) + if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) { break; + } - if (mChart.isDrawBarShadowEnabled()) { - if (roundedShadowRadius >0) + if (mChart.isDrawBarShadowEnabled()) { + if (roundedShadowRadius > 0) { c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), buffer.buffer[j + 2], mViewPortHandler.contentBottom()), roundedShadowRadius, roundedShadowRadius, mShadowPaint); - else + } else { c.drawRect(buffer.buffer[j], mViewPortHandler.contentTop(), buffer.buffer[j + 2], mViewPortHandler.contentBottom(), mShadowPaint); - } + } + } - // Set the color for the currently drawn value. If the index - mRenderPaint.setColor(dataSet.getColor(j / 4)); + // Set the color for the currently drawn value. If the index + mRenderPaint.setColor(dataSet.getColor(j / 4)); - if (roundedPositiveDataSetRadius >0) + if (roundedPositiveDataSetRadius > 0) { c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, mRenderPaint); - else + } else { c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], mRenderPaint); - } - } else { + } + } + } else { - mRenderPaint.setColor(dataSet.getColor()); + mRenderPaint.setColor(dataSet.getColor()); - for (int j = 0; j < buffer.size(); j += 4) { + for (int j = 0; j < buffer.size(); j += 4) { - if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) + if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) { continue; + } - if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) + if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) { break; + } - if (mChart.isDrawBarShadowEnabled()) { - if (roundedShadowRadius >0) + if (mChart.isDrawBarShadowEnabled()) { + if (roundedShadowRadius > 0) { c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), buffer.buffer[j + 2], mViewPortHandler.contentBottom()), roundedShadowRadius, roundedShadowRadius, mShadowPaint); - else + } else { c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], mRenderPaint); - } + } + } - if (roundedPositiveDataSetRadius >0) + if (roundedPositiveDataSetRadius > 0) { c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, mRenderPaint); - else + } else { c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], mRenderPaint); - } - } + } + } + } - boolean isSingleColor = dataSet.getColors().size() == 1; - if (isSingleColor) { - mRenderPaint.setColor(dataSet.getColor(index)); - } + boolean isSingleColor = dataSet.getColors().size() == 1; + if (isSingleColor) { + mRenderPaint.setColor(dataSet.getColor(index)); + } - int j = 0; - while (j < buffer.size()) { + int j = 0; + while (j < buffer.size()) { - if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) { - j += 4; - continue; - } + if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) { + j += 4; + continue; + } - if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) + if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) { break; - - if (!isSingleColor) { - mRenderPaint.setColor(dataSet.getColor(j/4)); } - mRenderPaint.setShader(new LinearGradient( - buffer.buffer[j], - buffer.buffer[j + 3], - buffer.buffer[j], - buffer.buffer[j + 1], - dataSet.getColor(j/4), - dataSet.getColor(j/4), - Shader.TileMode.MIRROR)); - - mRenderPaint.setShader(new LinearGradient( - buffer.buffer[j], - buffer.buffer[j + 3], - buffer.buffer[j], - buffer.buffer[j + 1], - dataSet.getColor(j/4), - dataSet.getColor(j/4), - Shader.TileMode.MIRROR)); - - - if((dataSet.getEntryForIndex(j/4).getY()<0 && roundedNegativeDataSetRadius >0)) { - Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], - buffer.buffer[j + 3]), roundedNegativeDataSetRadius, roundedNegativeDataSetRadius, true, true, true, true); - c.drawPath(path2, mRenderPaint); - } else if((dataSet.getEntryForIndex(j/4).getY()>0 && roundedPositiveDataSetRadius >0)){ - Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], - buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, true, true, true, true); - c.drawPath(path2, mRenderPaint); - } - else { - c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], - buffer.buffer[j + 3], mRenderPaint); - } + if (!isSingleColor) { + mRenderPaint.setColor(dataSet.getColor(j / 4)); + } - j += 4; - } + mRenderPaint.setShader(new LinearGradient( + buffer.buffer[j], + buffer.buffer[j + 3], + buffer.buffer[j], + buffer.buffer[j + 1], + dataSet.getColor(j / 4), + dataSet.getColor(j / 4), + Shader.TileMode.MIRROR)); - } + mRenderPaint.setShader(new LinearGradient( + buffer.buffer[j], + buffer.buffer[j + 3], + buffer.buffer[j], + buffer.buffer[j + 1], + dataSet.getColor(j / 4), + dataSet.getColor(j / 4), + Shader.TileMode.MIRROR)); - @Override - public void drawHighlighted(Canvas c, Highlight[] indices) { - BarData barData = mChart.getBarData(); - for (Highlight high : indices) { + if ((dataSet.getEntryForIndex(j / 4).getY() < 0 && roundedNegativeDataSetRadius > 0)) { + Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedNegativeDataSetRadius, roundedNegativeDataSetRadius, true, true, true, true); + c.drawPath(path2, mRenderPaint); + } else if ((dataSet.getEntryForIndex(j / 4).getY() > 0 && roundedPositiveDataSetRadius > 0)) { + Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, true, true, true, true); + c.drawPath(path2, mRenderPaint); + } else { + c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3], mRenderPaint); + } - IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex()); + j += 4; + } - if (set == null || !set.isHighlightEnabled()) { - continue; - } + } - BarEntry e = set.getEntryForXValue(high.getX(), high.getY()); + @Override + public void drawHighlighted(Canvas c, Highlight[] indices) { + BarData barData = mChart.getBarData(); - if (!isInBoundsX(e, set)) { - continue; - } + for (Highlight high : indices) { - Transformer trans = mChart.getTransformer(set.getAxisDependency()); + IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex()); - mHighlightPaint.setColor(set.getHighLightColor()); - mHighlightPaint.setAlpha(set.getHighLightAlpha()); + if (set == null || !set.isHighlightEnabled()) { + continue; + } - boolean isStack = high.getStackIndex() >= 0 && e.isStacked(); + BarEntry e = set.getEntryForXValue(high.getX(), high.getY()); - final float y1; - final float y2; + if (!isInBoundsX(e, set)) { + continue; + } - if (isStack) { + Transformer trans = mChart.getTransformer(set.getAxisDependency()); - if (mChart.isHighlightFullBarEnabled()) { + mHighlightPaint.setColor(set.getHighLightColor()); + mHighlightPaint.setAlpha(set.getHighLightAlpha()); - y1 = e.getPositiveSum(); - y2 = -e.getNegativeSum(); + boolean isStack = high.getStackIndex() >= 0 && e.isStacked(); - } else { + final float y1; + final float y2; - Range range = e.getRanges()[high.getStackIndex()]; + if (isStack) { - y1 = range.from; - y2 = range.to; - } + if (mChart.isHighlightFullBarEnabled()) { - } else { - y1 = e.getY(); - y2 = 0.f; - } + y1 = e.getPositiveSum(); + y2 = -e.getNegativeSum(); + + } else { + + Range range = e.getRanges()[high.getStackIndex()]; + + y1 = range.from; + y2 = range.to; + } + + } else { + y1 = e.getY(); + y2 = 0.f; + } - prepareBarHighlight(e.getX(), y1, y2, barData.getBarWidth() / 2f, trans); + prepareBarHighlight(e.getX(), y1, y2, barData.getBarWidth() / 2f, trans); - setHighlightDrawPos(high, mBarRect); + setHighlightDrawPos(high, mBarRect); - Path path2 = roundRect(new RectF(mBarRect.left, mBarRect.top, mBarRect.right, - mBarRect.bottom), mRadius, mRadius, true, true, true, true); + Path path2 = roundRect(new RectF(mBarRect.left, mBarRect.top, mBarRect.right, + mBarRect.bottom), mRadius, mRadius, true, true, true, true); - c.drawPath(path2, mHighlightPaint); + c.drawPath(path2, mHighlightPaint); + } + } + + private Path roundRect(RectF rect, float rx, float ry, boolean tl, boolean tr, boolean br, boolean bl) { + float top = rect.top; + float left = rect.left; + float right = rect.right; + float bottom = rect.bottom; + Path path = new Path(); + if (rx < 0) { + rx = 0; + } + if (ry < 0) { + ry = 0; + } + float width = right - left; + float height = bottom - top; + if (rx > width / 2) { + rx = width / 2; } - } - - private Path roundRect(RectF rect, float rx, float ry, boolean tl, boolean tr, boolean br, boolean bl) { - float top = rect.top; - float left = rect.left; - float right = rect.right; - float bottom = rect.bottom; - Path path = new Path(); - if (rx < 0) rx = 0; - if (ry < 0) ry = 0; - float width = right - left; - float height = bottom - top; - if (rx > width / 2) rx = width / 2; - if (ry > height / 2) ry = height / 2; - float widthMinusCorners = (width - (2 * rx)); - float heightMinusCorners = (height - (2 * ry)); - - path.moveTo(right, top + ry); - if (tr) + if (ry > height / 2) { + ry = height / 2; + } + float widthMinusCorners = (width - (2 * rx)); + float heightMinusCorners = (height - (2 * ry)); + + path.moveTo(right, top + ry); + if (tr) { path.rQuadTo(0, -ry, -rx, -ry);//top-right corner - else { + } else { path.rLineTo(0, -ry); path.rLineTo(-rx, 0); } - path.rLineTo(-widthMinusCorners, 0); - if (tl) + path.rLineTo(-widthMinusCorners, 0); + if (tl) { path.rQuadTo(-rx, 0, -rx, ry); //top-left corner - else { + } else { path.rLineTo(-rx, 0); path.rLineTo(0, ry); } - path.rLineTo(0, heightMinusCorners); + path.rLineTo(0, heightMinusCorners); - if (bl) + if (bl) { path.rQuadTo(0, ry, rx, ry);//bottom-left corner - else { + } else { path.rLineTo(0, ry); path.rLineTo(rx, 0); } - path.rLineTo(widthMinusCorners, 0); - if (br) - path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner - else { - path.rLineTo(rx, 0); - path.rLineTo(0, -ry); - } - - path.rLineTo(0, -heightMinusCorners); - path.close(); - return path; - } + path.rLineTo(widthMinusCorners, 0); + if (br) + path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner + else { + path.rLineTo(rx, 0); + path.rLineTo(0, -ry); + } + + path.rLineTo(0, -heightMinusCorners); + path.close(); + return path; + } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java index 9d14a321ba..7aa5f4d917 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java @@ -17,226 +17,247 @@ public class RoundedHorizontalBarChartRenderer extends HorizontalBarChartRenderer { - private final RectF mBarShadowRectBuffer = new RectF(); - private float roundedShadowRadius = 0f; - private float roundedPositiveDataSetRadius = 0f; - private float roundedNegativeDataSetRadius = 0f; - public void setRoundedNegativeDataSetRadius(float roundedNegativeDataSet) { - roundedNegativeDataSetRadius = roundedNegativeDataSet; - } - public void setRoundedShadowRadius(float roundedShadow) { - roundedShadowRadius = roundedShadow; - } - public void setRoundedPositiveDataSetRadius(float roundedPositiveDataSet) { - roundedPositiveDataSetRadius = roundedPositiveDataSet; - } - public RoundedHorizontalBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) { - super(chart, animator, viewPortHandler); - - mValuePaint.setTextAlign(Paint.Align.LEFT); - } - - @Override - protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { - initBuffers(); - Transformer trans = mChart.getTransformer(dataSet.getAxisDependency()); - mBarBorderPaint.setColor(dataSet.getBarBorderColor()); - mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth())); - mShadowPaint.setColor(dataSet.getBarShadowColor()); - boolean drawBorder = dataSet.getBarBorderWidth() > 0f; - float phaseX = mAnimator.getPhaseX(); - float phaseY = mAnimator.getPhaseY(); - - if (mChart.isDrawBarShadowEnabled()) { - mShadowPaint.setColor(dataSet.getBarShadowColor()); - BarData barData = mChart.getBarData(); - float barWidth = barData.getBarWidth(); - float barWidthHalf = barWidth / 2.0f; - float x; - int i = 0; - double count = Math.min(Math.ceil((int) (double) ((float) dataSet.getEntryCount() * phaseX)), dataSet.getEntryCount()); - while (i < count) { - BarEntry e = dataSet.getEntryForIndex(i); - x = e.getX(); - mBarShadowRectBuffer.top = x - barWidthHalf; - mBarShadowRectBuffer.bottom = x + barWidthHalf; - trans.rectValueToPixel(mBarShadowRectBuffer); - if (!mViewPortHandler.isInBoundsTop(mBarShadowRectBuffer.bottom)) { - i++; - continue; - } - if (!mViewPortHandler.isInBoundsBottom(mBarShadowRectBuffer.top)) + private final RectF mBarShadowRectBuffer = new RectF(); + private float roundedShadowRadius = 0f; + private float roundedPositiveDataSetRadius = 0f; + private float roundedNegativeDataSetRadius = 0f; + + public void setRoundedNegativeDataSetRadius(float roundedNegativeDataSet) { + roundedNegativeDataSetRadius = roundedNegativeDataSet; + } + + public void setRoundedShadowRadius(float roundedShadow) { + roundedShadowRadius = roundedShadow; + } + + public void setRoundedPositiveDataSetRadius(float roundedPositiveDataSet) { + roundedPositiveDataSetRadius = roundedPositiveDataSet; + } + + public RoundedHorizontalBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) { + super(chart, animator, viewPortHandler); + + mValuePaint.setTextAlign(Paint.Align.LEFT); + } + + @Override + protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { + initBuffers(); + Transformer trans = mChart.getTransformer(dataSet.getAxisDependency()); + mBarBorderPaint.setColor(dataSet.getBarBorderColor()); + mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth())); + mShadowPaint.setColor(dataSet.getBarShadowColor()); + boolean drawBorder = dataSet.getBarBorderWidth() > 0f; + float phaseX = mAnimator.getPhaseX(); + float phaseY = mAnimator.getPhaseY(); + + if (mChart.isDrawBarShadowEnabled()) { + mShadowPaint.setColor(dataSet.getBarShadowColor()); + BarData barData = mChart.getBarData(); + float barWidth = barData.getBarWidth(); + float barWidthHalf = barWidth / 2.0f; + float x; + int i = 0; + double count = Math.min(Math.ceil((int) (double) ((float) dataSet.getEntryCount() * phaseX)), dataSet.getEntryCount()); + while (i < count) { + BarEntry e = dataSet.getEntryForIndex(i); + x = e.getX(); + mBarShadowRectBuffer.top = x - barWidthHalf; + mBarShadowRectBuffer.bottom = x + barWidthHalf; + trans.rectValueToPixel(mBarShadowRectBuffer); + if (!mViewPortHandler.isInBoundsTop(mBarShadowRectBuffer.bottom)) { + i++; + continue; + } + if (!mViewPortHandler.isInBoundsBottom(mBarShadowRectBuffer.top)) { break; - mBarShadowRectBuffer.left = mViewPortHandler.contentLeft(); - mBarShadowRectBuffer.right = mViewPortHandler.contentRight(); + } + mBarShadowRectBuffer.left = mViewPortHandler.contentLeft(); + mBarShadowRectBuffer.right = mViewPortHandler.contentRight(); - if (roundedShadowRadius >0) { - c.drawRoundRect(mBarRect, roundedShadowRadius, roundedShadowRadius, mShadowPaint); - } else { - c.drawRect(mBarShadowRectBuffer, mShadowPaint); - } - i++; - } - } + if (roundedShadowRadius > 0) { + c.drawRoundRect(mBarRect, roundedShadowRadius, roundedShadowRadius, mShadowPaint); + } else { + c.drawRect(mBarShadowRectBuffer, mShadowPaint); + } + i++; + } + } - BarBuffer buffer = mBarBuffers[index]; - buffer.setPhases(phaseX, phaseY); - buffer.setDataSet(index); - buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency())); - buffer.setBarWidth(mChart.getBarData().getBarWidth()); - buffer.feed(dataSet); - trans.pointValuesToPixel(buffer.buffer); + BarBuffer buffer = mBarBuffers[index]; + buffer.setPhases(phaseX, phaseY); + buffer.setDataSet(index); + buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency())); + buffer.setBarWidth(mChart.getBarData().getBarWidth()); + buffer.feed(dataSet); + trans.pointValuesToPixel(buffer.buffer); - // if multiple colors has been assigned to Bar Chart - if (dataSet.getColors().size() > 1) { + // if multiple colors has been assigned to Bar Chart + if (dataSet.getColors().size() > 1) { - for (int j = 0; j < buffer.size(); j += 4) { + for (int j = 0; j < buffer.size(); j += 4) { - if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3])) + if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3])) { continue; + } - if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j+1])) + if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j + 1])) { break; + } - if (mChart.isDrawBarShadowEnabled()) { - if (roundedShadowRadius >0) + if (mChart.isDrawBarShadowEnabled()) { + if (roundedShadowRadius > 0) { c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), buffer.buffer[j + 2], mViewPortHandler.contentBottom()), roundedShadowRadius, roundedShadowRadius, mShadowPaint); - else + } else { c.drawRect(buffer.buffer[j], mViewPortHandler.contentTop(), buffer.buffer[j + 2], mViewPortHandler.contentBottom(), mShadowPaint); - } + } + } - // Set the color for the currently drawn value. If the index - mRenderPaint.setColor(dataSet.getColor(j / 4)); + // Set the color for the currently drawn value. If the index + mRenderPaint.setColor(dataSet.getColor(j / 4)); - if (roundedPositiveDataSetRadius >0) + if (roundedPositiveDataSetRadius > 0) { c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, mRenderPaint); - else + } else { c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], mRenderPaint); - } - } else { + } + } + } else { - mRenderPaint.setColor(dataSet.getColor()); + mRenderPaint.setColor(dataSet.getColor()); - for (int j = 0; j < buffer.size(); j += 4) { + for (int j = 0; j < buffer.size(); j += 4) { - if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3])) + if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3])) { continue; + } - if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j+1])) + if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j + 1])) { break; + } - if (mChart.isDrawBarShadowEnabled()) { - if (roundedShadowRadius >0) + if (mChart.isDrawBarShadowEnabled()) { + if (roundedShadowRadius > 0) { c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), buffer.buffer[j + 2], mViewPortHandler.contentBottom()), roundedShadowRadius, roundedShadowRadius, mShadowPaint); - else + } else { c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], mRenderPaint); - } + } + } - if (roundedPositiveDataSetRadius >0) + if (roundedPositiveDataSetRadius > 0) { c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, mRenderPaint); - else + } else { c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], mRenderPaint); - } - } + } + } + } - boolean isSingleColor = dataSet.getColors().size() == 1; - if (isSingleColor) { - mRenderPaint.setColor(dataSet.getColor(index)); - } + boolean isSingleColor = dataSet.getColors().size() == 1; + if (isSingleColor) { + mRenderPaint.setColor(dataSet.getColor(index)); + } - int j = 0; - while (j < buffer.size()) { + int j = 0; + while (j < buffer.size()) { - if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3])) { - j += 4; - continue; - } + if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3])) { + j += 4; + continue; + } - if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j+1])) + if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j + 1])) { break; - - if (!isSingleColor) { - mRenderPaint.setColor(dataSet.getColor(j/4)); } - if((dataSet.getEntryForIndex(j/4).getY()<0 && roundedNegativeDataSetRadius >0)) { - Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], - buffer.buffer[j + 3]), roundedNegativeDataSetRadius, roundedNegativeDataSetRadius, true, true, true, true); - c.drawPath(path2, mRenderPaint); - } else if((dataSet.getEntryForIndex(j/4).getY()>0 && roundedPositiveDataSetRadius >0)){ - Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], - buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, true, true, true, true); - c.drawPath(path2, mRenderPaint); - } - else { - c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], - buffer.buffer[j + 3], mRenderPaint); - } - j += 4; + if (!isSingleColor) { + mRenderPaint.setColor(dataSet.getColor(j / 4)); + } + + if ((dataSet.getEntryForIndex(j / 4).getY() < 0 && roundedNegativeDataSetRadius > 0)) { + Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedNegativeDataSetRadius, roundedNegativeDataSetRadius, true, true, true, true); + c.drawPath(path2, mRenderPaint); + } else if ((dataSet.getEntryForIndex(j / 4).getY() > 0 && roundedPositiveDataSetRadius > 0)) { + Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3]), roundedPositiveDataSetRadius, roundedPositiveDataSetRadius, true, true, true, true); + c.drawPath(path2, mRenderPaint); + } else { + c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], + buffer.buffer[j + 3], mRenderPaint); + } + j += 4; + } + } + + private Path roundRect(RectF rect, float rx, float ry, boolean tl, boolean tr, boolean br, boolean bl) { + float top = rect.top; + float left = rect.left; + float right = rect.right; + float bottom = rect.bottom; + Path path = new Path(); + if (rx < 0) { + rx = 0; + } + if (ry < 0) { + ry = 0; + } + float width = right - left; + float height = bottom - top; + if (rx > width / 2) { + rx = width / 2; } - } - - private Path roundRect(RectF rect, float rx, float ry, boolean tl, boolean tr, boolean br, boolean bl) { - float top = rect.top; - float left = rect.left; - float right = rect.right; - float bottom = rect.bottom; - Path path = new Path(); - if (rx < 0) rx = 0; - if (ry < 0) ry = 0; - float width = right - left; - float height = bottom - top; - if (rx > width / 2) rx = width / 2; - if (ry > height / 2) ry = height / 2; - float widthMinusCorners = (width - (2 * rx)); - float heightMinusCorners = (height - (2 * ry)); - - path.moveTo(right, top + ry); - if (tr) + if (ry > height / 2) { + ry = height / 2; + } + float widthMinusCorners = (width - (2 * rx)); + float heightMinusCorners = (height - (2 * ry)); + + path.moveTo(right, top + ry); + if (tr) { path.rQuadTo(0, -ry, -rx, -ry);//top-right corner - else { + } else { path.rLineTo(0, -ry); path.rLineTo(-rx, 0); } - path.rLineTo(-widthMinusCorners, 0); - if (tl) + path.rLineTo(-widthMinusCorners, 0); + if (tl) { path.rQuadTo(-rx, 0, -rx, ry); //top-left corner - else { + } else { path.rLineTo(-rx, 0); path.rLineTo(0, ry); } - path.rLineTo(0, heightMinusCorners); + path.rLineTo(0, heightMinusCorners); - if (bl) + if (bl) { path.rQuadTo(0, ry, rx, ry);//bottom-left corner - else { + } else { path.rLineTo(0, ry); path.rLineTo(rx, 0); } - path.rLineTo(widthMinusCorners, 0); - if (br) - path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner - else { - path.rLineTo(rx, 0); - path.rLineTo(0, -ry); - } - - path.rLineTo(0, -heightMinusCorners); - path.close(); - return path; - } + path.rLineTo(widthMinusCorners, 0); + if (br) + path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner + else { + path.rLineTo(rx, 0); + path.rLineTo(0, -ry); + } + + path.rLineTo(0, -heightMinusCorners); + path.close(); + return path; + } } From a98db4fa63941618304a5b7bb65683a32e79403b Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sat, 22 Jun 2024 06:49:54 +0200 Subject: [PATCH 3/6] Apply lint suggestions --- .../mikephil/charting/renderer/RoundedBarChartRenderer.java | 5 +++-- .../charting/renderer/RoundedHorizontalBarChartRenderer.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java index f99eba4b79..e06228c6df 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedBarChartRenderer.java @@ -18,6 +18,7 @@ import com.github.mikephil.charting.utils.Utils; import com.github.mikephil.charting.utils.ViewPortHandler; +/** @noinspection unused*/ public class RoundedBarChartRenderer extends BarChartRenderer { public RoundedBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) { @@ -25,7 +26,7 @@ public RoundedBarChartRenderer(BarDataProvider chart, ChartAnimator animator, Vi } private final RectF mBarShadowRectBuffer = new RectF(); - private float mRadius = 20f; + private final float mRadius = 20f; private float roundedShadowRadius = 0f; private float roundedPositiveDataSetRadius = 0f; private float roundedNegativeDataSetRadius = 0f; @@ -60,7 +61,7 @@ protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { float barWidthHalf = barWidth / 2.0f; float x; int i = 0; - double count = Math.min(Math.ceil((int) (double) ((float) dataSet.getEntryCount() * phaseX)), dataSet.getEntryCount()); + double count = Math.min((double) (int) (double) ((float) dataSet.getEntryCount() * phaseX), dataSet.getEntryCount()); while (i < count) { BarEntry e = dataSet.getEntryForIndex(i); x = e.getX(); diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java index 7aa5f4d917..7921480cb9 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/RoundedHorizontalBarChartRenderer.java @@ -15,6 +15,7 @@ import com.github.mikephil.charting.utils.Utils; import com.github.mikephil.charting.utils.ViewPortHandler; +/** @noinspection unused*/ public class RoundedHorizontalBarChartRenderer extends HorizontalBarChartRenderer { private final RectF mBarShadowRectBuffer = new RectF(); @@ -58,7 +59,7 @@ protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { float barWidthHalf = barWidth / 2.0f; float x; int i = 0; - double count = Math.min(Math.ceil((int) (double) ((float) dataSet.getEntryCount() * phaseX)), dataSet.getEntryCount()); + double count = Math.min((double) (int) (double) ((float) dataSet.getEntryCount() * phaseX), dataSet.getEntryCount()); while (i < count) { BarEntry e = dataSet.getEntryForIndex(i); x = e.getX(); From 3bc194d7e12ab83ada2e28c44ee44a34abfd1085 Mon Sep 17 00:00:00 2001 From: Mohini Katara Date: Wed, 11 Oct 2023 23:27:11 +0530 Subject: [PATCH 4/6] Added Rounded corner for Pie chart --- MPChartExample/src/main/AndroidManifest.xml | 1 + .../PieChartRoundedActivity.java | 334 ++++++++++++++++++ .../notimportant/MainActivity.kt | 1 + .../charting/renderer/PieChartRenderer.java | 36 ++ 4 files changed, 372 insertions(+) create mode 100644 MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/PieChartRoundedActivity.java diff --git a/MPChartExample/src/main/AndroidManifest.xml b/MPChartExample/src/main/AndroidManifest.xml index 14eeed1810..d357bdf1b7 100644 --- a/MPChartExample/src/main/AndroidManifest.xml +++ b/MPChartExample/src/main/AndroidManifest.xml @@ -25,6 +25,7 @@ + diff --git a/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/PieChartRoundedActivity.java b/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/PieChartRoundedActivity.java new file mode 100644 index 0000000000..6c3ddd216a --- /dev/null +++ b/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/PieChartRoundedActivity.java @@ -0,0 +1,334 @@ + +package com.xxmassdeveloper.mpchartexample; + +import android.Manifest; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Color; +import android.graphics.Typeface; +import android.net.Uri; +import android.os.Bundle; +import android.text.SpannableString; +import android.text.style.ForegroundColorSpan; +import android.text.style.RelativeSizeSpan; +import android.text.style.StyleSpan; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.WindowManager; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; +import android.widget.TextView; + +import com.github.mikephil.charting.animation.Easing; +import com.github.mikephil.charting.charts.PieChart; +import com.github.mikephil.charting.components.Legend; +import com.github.mikephil.charting.data.Entry; +import com.github.mikephil.charting.data.PieData; +import com.github.mikephil.charting.data.PieDataSet; +import com.github.mikephil.charting.data.PieEntry; +import com.github.mikephil.charting.formatter.PercentFormatter; +import com.github.mikephil.charting.highlight.Highlight; +import com.github.mikephil.charting.interfaces.datasets.IDataSet; +import com.github.mikephil.charting.listener.OnChartValueSelectedListener; +import com.github.mikephil.charting.renderer.PieChartRenderer; +import com.github.mikephil.charting.utils.ColorTemplate; +import com.github.mikephil.charting.utils.MPPointF; +import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase; + +import java.util.ArrayList; + +import androidx.core.content.ContextCompat; + +public class PieChartRoundedActivity extends DemoBase implements OnSeekBarChangeListener, + OnChartValueSelectedListener { + + private PieChart chart; + private SeekBar seekBarX, seekBarY; + private TextView tvX, tvY; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + setContentView(R.layout.activity_piechart); + + setTitle("PieChartActivity"); + + tvX = findViewById(R.id.tvXMax); + tvY = findViewById(R.id.tvYMax); + + seekBarX = findViewById(R.id.seekBarX); + seekBarY = findViewById(R.id.seekBarY); + + seekBarX.setOnSeekBarChangeListener(this); + seekBarY.setOnSeekBarChangeListener(this); + + chart = findViewById(R.id.chart1); + chart.setUsePercentValues(true); + chart.getDescription().setEnabled(false); + chart.setExtraOffsets(5, 10, 5, 5); + + chart.setDragDecelerationFrictionCoef(0.95f); + + chart.setCenterTextTypeface(tfLight); + chart.setCenterText(generateCenterSpannableText()); + + chart.setDrawHoleEnabled(true); + chart.setHoleColor(Color.TRANSPARENT); + + chart.setTransparentCircleColor(Color.TRANSPARENT); + chart.setTransparentCircleAlpha(110); + + chart.setHoleRadius(50f); + + chart.setTransparentCircleRadius(0f); + + chart.setDrawCenterText(true); + + chart.setRotationAngle(0); + // enable rotation of the chart by touch + chart.setRotationEnabled(true); + chart.setHighlightPerTapEnabled(true); + + // chart.setUnit(" €"); + // chart.setDrawUnitsInChart(true); + + // add a selection listener + chart.setOnChartValueSelectedListener(this); + + seekBarX.setProgress(4); + seekBarY.setProgress(10); + + chart.animateY(1400, Easing.EaseInOutQuad); + // chart.spin(2000, 0, 360); + + Legend l = chart.getLegend(); + l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); + l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT); + l.setOrientation(Legend.LegendOrientation.VERTICAL); + l.setDrawInside(false); + l.setXEntrySpace(7f); + l.setYEntrySpace(0f); + l.setYOffset(0f); + + // entry label styling + chart.setEntryLabelColor(Color.WHITE); + chart.setEntryLabelTypeface(tfRegular); + chart.setEntryLabelTextSize(12f); + } + + private void setData(int count, float range) { + ArrayList entries = new ArrayList<>(); + Double[] sampleValues = DataTools.Companion.getValues(100); + + // NOTE: The order of the entries when being added to the entries array determines their position around the center of + // the chart. + for (int i = 0; i < count ; i++) { + entries.add(new PieEntry((float) ((sampleValues[i].floatValue() * range) + range / 5), + parties[i % parties.length], + getResources().getDrawable(R.drawable.star))); + } + + PieDataSet dataSet = new PieDataSet(entries, "Election Results"); + + dataSet.setDrawIcons(false); + + dataSet.setSliceSpace(3f); + dataSet.setIconsOffset(new MPPointF(0, 40)); + dataSet.setSelectionShift(5f); + + // add a lot of colors + + ArrayList colors = new ArrayList<>(); + + for (int c : ColorTemplate.VORDIPLOM_COLORS) + colors.add(c); + + for (int c : ColorTemplate.JOYFUL_COLORS) + colors.add(c); + + for (int c : ColorTemplate.COLORFUL_COLORS) + colors.add(c); + + for (int c : ColorTemplate.LIBERTY_COLORS) + colors.add(c); + + for (int c : ColorTemplate.PASTEL_COLORS) + colors.add(c); + + colors.add(ColorTemplate.getHoloBlue()); + + dataSet.setColors(colors); + //dataSet.setSelectionShift(0f); + + PieData data = new PieData(dataSet); + data.setValueFormatter(new PercentFormatter()); + data.setValueTextSize(11f); + data.setValueTextColor(Color.WHITE); + data.setValueTypeface(tfLight); + chart.setData(data); + + // undo all highlights + chart.highlightValues(null); + + PieChartRenderer renderer =(PieChartRenderer) chart.getRenderer(); + renderer.setRoundedCornerRadius(30f); + dataSet.setSliceSpace(renderer.getRoundedCornerRadius()/2); + + chart.invalidate(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.pie, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { + case R.id.viewGithub: { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse("https://github.com/AppDevNext/AndroidChart/blob/master/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/PieChartActivity.java")); + startActivity(i); + break; + } + case R.id.actionToggleValues: { + for (IDataSet set : chart.getData().getDataSets()) + set.setDrawValues(!set.isDrawValuesEnabled()); + + chart.invalidate(); + break; + } + case R.id.actionToggleIcons: { + for (IDataSet set : chart.getData().getDataSets()) + set.setDrawIcons(!set.isDrawIconsEnabled()); + + chart.invalidate(); + break; + } + case R.id.actionToggleHole: { + if (chart.isDrawHoleEnabled()) + chart.setDrawHoleEnabled(false); + else + chart.setDrawHoleEnabled(true); + chart.invalidate(); + break; + } + case R.id.actionToggleMinAngles: { + if (chart.getMinAngleForSlices() == 0f) + chart.setMinAngleForSlices(36f); + else + chart.setMinAngleForSlices(0f); + chart.notifyDataSetChanged(); + chart.invalidate(); + break; + } + case R.id.actionToggleCurvedSlices: { + boolean toSet = !chart.isDrawRoundedSlicesEnabled() || !chart.isDrawHoleEnabled(); + chart.setDrawRoundedSlices(toSet); + if (toSet && !chart.isDrawHoleEnabled()) { + chart.setDrawHoleEnabled(true); + } + if (toSet && chart.isDrawSlicesUnderHoleEnabled()) { + chart.setDrawSlicesUnderHole(false); + } + chart.invalidate(); + break; + } + case R.id.actionDrawCenter: { + if (chart.isDrawCenterTextEnabled()) + chart.setDrawCenterText(false); + else + chart.setDrawCenterText(true); + chart.invalidate(); + break; + } + case R.id.actionToggleXValues: { + + chart.setDrawEntryLabels(!chart.isDrawEntryLabelsEnabled()); + chart.invalidate(); + break; + } + case R.id.actionTogglePercent: + chart.setUsePercentValues(!chart.isUsePercentValuesEnabled()); + chart.invalidate(); + break; + case R.id.animateX: { + chart.animateX(1400); + break; + } + case R.id.animateY: { + chart.animateY(1400); + break; + } + case R.id.animateXY: { + chart.animateXY(1400, 1400); + break; + } + case R.id.actionToggleSpin: { + chart.spin(1000, chart.getRotationAngle(), chart.getRotationAngle() + 360, Easing.EaseInOutCubic); + break; + } + case R.id.actionSave: { + if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { + saveToGallery(); + } else { + requestStoragePermission(chart); + } + break; + } + } + return true; + } + + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + + tvX.setText(String.valueOf(seekBarX.getProgress())); + tvY.setText(String.valueOf(seekBarY.getProgress())); + + setData(seekBarX.getProgress(), seekBarY.getProgress()); + } + + @Override + protected void saveToGallery() { + saveToGallery(chart, "PieChartActivity"); + } + + private SpannableString generateCenterSpannableText() { + + SpannableString s = new SpannableString("MPAndroidChart\ndeveloped by Philipp Jahoda"); + s.setSpan(new RelativeSizeSpan(1.7f), 0, 14, 0); + s.setSpan(new StyleSpan(Typeface.NORMAL), 14, s.length() - 15, 0); + s.setSpan(new ForegroundColorSpan(Color.GRAY), 14, s.length() - 15, 0); + s.setSpan(new RelativeSizeSpan(.8f), 14, s.length() - 15, 0); + s.setSpan(new StyleSpan(Typeface.ITALIC), s.length() - 14, s.length(), 0); + s.setSpan(new ForegroundColorSpan(ColorTemplate.getHoloBlue()), s.length() - 14, s.length(), 0); + return s; + } + + @Override + public void onValueSelected(Entry e, Highlight h) { + + if (e == null) + return; + Log.i("VAL SELECTED", + "Value: " + e.getY() + ", index: " + h.getX() + + ", DataSet index: " + h.getDataSetIndex()); + } + + @Override + public void onNothingSelected() { + Log.i("PieChart", "nothing selected"); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + + @Override + public void onStopTrackingTouch(SeekBar seekBar) {} +} diff --git a/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/notimportant/MainActivity.kt b/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/notimportant/MainActivity.kt index 602f5df198..2d9f2da5da 100644 --- a/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/notimportant/MainActivity.kt +++ b/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/notimportant/MainActivity.kt @@ -91,6 +91,7 @@ class MainActivity : AppCompatActivity(), OnItemClickListener { add(19, ContentItem("Pie Charts")) add(20, ContentItem("Basic", "Simple pie chart.", PieChartActivity::class.java)) + add(20, ContentItem("Basic", "Rounded pie chart.", PieChartRoundedActivity::class.java)) add(21, ContentItem("Value Lines", "Stylish lines drawn outward from slices.", PiePolylineChartActivity::class.java)) add(22, ContentItem("Half Pie", "180° (half) pie chart.", HalfPieChartActivity::class.java)) add(23, ContentItem("Specific positions", "This demonstrates how to pass a list of specific positions for lines and labels on x and y axis", SpecificPositionsLineChartActivity::class.java)) diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/PieChartRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/PieChartRenderer.java index b557b333dd..86b6247005 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/PieChartRenderer.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/PieChartRenderer.java @@ -45,6 +45,11 @@ public class PieChartRenderer extends DataRenderer { protected Paint mTransparentCirclePaint; protected Paint mValueLinePaint; + /** + * paint object used for drawing the rounded corner slice + */ + protected Paint mRoundedCornerPaint; + /** * paint object for the text that can be displayed in the center of the * chart @@ -68,6 +73,24 @@ public class PieChartRenderer extends DataRenderer { protected Canvas mBitmapCanvas; + /** + * Setter for the rounded corner slice paint object + */ + public void setRoundedCornerRadius(float radius){ + mRoundedCornerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mRoundedCornerPaint.setStyle(Style.STROKE); + mRoundedCornerPaint.setAntiAlias(true); + mRoundedCornerPaint.setStrokeWidth(radius); + + } + + /** + * Getter for the rounded corner slice paint object + */ + public float getRoundedCornerRadius(){ + return mRoundedCornerPaint.getStrokeWidth(); + } + public PieChartRenderer(PieChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler) { super(animator, viewPortHandler); @@ -245,6 +268,11 @@ protected void drawDataSet(Canvas c, IPieDataSet dataSet) { final float sliceSpace = visibleAngleCount <= 1 ? 0.f : getSliceSpace(dataSet); + if (getRoundedCornerRadius()>0) { + mRoundedCornerPaint.setStrokeCap(Paint.Cap.ROUND); + mRoundedCornerPaint.setStrokeJoin(Paint.Join.ROUND); + } + for (int j = 0; j < entryCount; j++) { float sliceAngle = drawAngles[j]; @@ -268,6 +296,9 @@ protected void drawDataSet(Canvas c, IPieDataSet dataSet) { mRenderPaint.setColor(dataSet.getColor(j)); + // Set current data set color to paint object + mRoundedCornerPaint.setColor(dataSet.getColor(j)); + final float sliceSpaceAngleOuter = visibleAngleCount == 1 ? 0.f : sliceSpace / (Utils.FDEG2RAD * radius); @@ -398,6 +429,11 @@ protected void drawDataSet(Canvas c, IPieDataSet dataSet) { mBitmapCanvas.drawPath(mPathBuffer, mRenderPaint); + // Draw rounded corner path with paint object slice with the given radius + if (getRoundedCornerRadius()>0) { + mBitmapCanvas.drawPath(mPathBuffer, mRoundedCornerPaint); + } + angle += sliceAngle * phaseX; } From e2c9f226db02874773b1828332556381a81a3247 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sat, 22 Jun 2024 08:02:53 +0200 Subject: [PATCH 5/6] Fix a crash --- .../mikephil/charting/renderer/PieChartRenderer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/PieChartRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/PieChartRenderer.java index 86b6247005..653eb4e296 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/PieChartRenderer.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/PieChartRenderer.java @@ -77,11 +77,7 @@ public class PieChartRenderer extends DataRenderer { * Setter for the rounded corner slice paint object */ public void setRoundedCornerRadius(float radius){ - mRoundedCornerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mRoundedCornerPaint.setStyle(Style.STROKE); - mRoundedCornerPaint.setAntiAlias(true); mRoundedCornerPaint.setStrokeWidth(radius); - } /** @@ -120,6 +116,10 @@ public PieChartRenderer(PieChart chart, ChartAnimator animator, mValueLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mValueLinePaint.setStyle(Style.STROKE); + + mRoundedCornerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mRoundedCornerPaint.setStyle(Style.STROKE); + mRoundedCornerPaint.setAntiAlias(true); } public Paint getPaintHole() { From 814de5e7c833749f694532c74aae79a661332194 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 23 Jun 2024 08:57:28 +0200 Subject: [PATCH 6/6] Accept new screenshots --- ...keTestStart-20-PieChartRoundedActivity.png | Bin 0 -> 30399 bytes ...est_smokeTestStart-39-PieChartActivity.png | Bin 0 -> 29125 bytes .../StartTest_smokeTestStart.png | Bin 27982 -> 27981 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 screenshotsToCompare9/StartTest_smokeTestStart-20-PieChartRoundedActivity.png create mode 100644 screenshotsToCompare9/StartTest_smokeTestStart-39-PieChartActivity.png diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-20-PieChartRoundedActivity.png b/screenshotsToCompare9/StartTest_smokeTestStart-20-PieChartRoundedActivity.png new file mode 100644 index 0000000000000000000000000000000000000000..336bb7e788ec6eca1bad006c01f523637128997f GIT binary patch literal 30399 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�KAJP7tWKEehc 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