-
-
Save xanscale/e971cc4f2f0712a8a3bcc35e85325c27 to your computer and use it in GitHub Desktop.
| <com.scarozza.RoundedBarChart | |
| android:id="@+id/chart" | |
| app:radius="4dp" | |
| android:layout_width="match_parent" | |
| android:layout_height="match_parent" /> |
| <?xml version="1.0" encoding="utf-8"?> | |
| <resources> | |
| <declare-styleable name="RoundedBarChart"> | |
| <attr name="radius" format="dimension" /> | |
| </declare-styleable> | |
| </resources> |
| package com.scarozza; | |
| import android.content.Context; | |
| import android.content.res.TypedArray; | |
| import android.graphics.Canvas; | |
| import android.graphics.LinearGradient; | |
| import android.graphics.RectF; | |
| import android.util.AttributeSet; | |
| import com.github.mikephil.charting.animation.ChartAnimator; | |
| import com.github.mikephil.charting.buffer.BarBuffer; | |
| import com.github.mikephil.charting.charts.BarChart; | |
| 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.model.GradientColor; | |
| import com.github.mikephil.charting.renderer.BarChartRenderer; | |
| import com.github.mikephil.charting.utils.Transformer; | |
| import com.github.mikephil.charting.utils.Utils; | |
| import com.github.mikephil.charting.utils.ViewPortHandler; | |
| public class RoundedBarChart extends BarChart { | |
| public RoundedBarChart(Context context) { | |
| super(context); | |
| } | |
| public RoundedBarChart(Context context, AttributeSet attrs) { | |
| super(context, attrs); | |
| readRadiusAttr(context, attrs); | |
| } | |
| public RoundedBarChart(Context context, AttributeSet attrs, int defStyle) { | |
| super(context, attrs, defStyle); | |
| readRadiusAttr(context, attrs); | |
| } | |
| private void readRadiusAttr(Context context, AttributeSet attrs){ | |
| TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RoundedBarChart, 0, 0); | |
| try { | |
| setRadius(a.getDimensionPixelSize(R.styleable.RoundedBarChart_radius, 0)); | |
| } finally { | |
| a.recycle(); | |
| } | |
| } | |
| public void setRadius(int radius) { | |
| setRenderer(new RoundedBarChartRenderer(this, getAnimator(), getViewPortHandler(), radius)); | |
| } | |
| private class RoundedBarChartRenderer extends BarChartRenderer { | |
| private int mRadius; | |
| private RectF mBarShadowRectBuffer = new RectF(); | |
| RoundedBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler, int mRadius) { | |
| super(chart, animator, viewPortHandler); | |
| this.mRadius = mRadius; | |
| } | |
| @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); | |
| c.drawRoundRect(mBarRect, mRadius, mRadius, mHighlightPaint); | |
| } | |
| } | |
| @Override | |
| protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { | |
| Transformer trans = mChart.getTransformer(dataSet.getAxisDependency()); | |
| mBarBorderPaint.setColor(dataSet.getBarBorderColor()); | |
| mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth())); | |
| final boolean drawBorder = dataSet.getBarBorderWidth() > 0.f; | |
| float phaseX = mAnimator.getPhaseX(); | |
| float phaseY = mAnimator.getPhaseY(); | |
| // draw the bar shadow before the values | |
| if (mChart.isDrawBarShadowEnabled()) { | |
| mShadowPaint.setColor(dataSet.getBarShadowColor()); | |
| BarData barData = mChart.getBarData(); | |
| final float barWidth = barData.getBarWidth(); | |
| final float barWidthHalf = barWidth / 2.0f; | |
| float x; | |
| for (int i = 0, count = Math.min((int) (Math.ceil((float) (dataSet.getEntryCount()) * phaseX)), dataSet.getEntryCount()); | |
| i < count; | |
| i++) { | |
| BarEntry e = dataSet.getEntryForIndex(i); | |
| x = e.getX(); | |
| mBarShadowRectBuffer.left = x - barWidthHalf; | |
| mBarShadowRectBuffer.right = x + barWidthHalf; | |
| trans.rectValueToPixel(mBarShadowRectBuffer); | |
| if (!mViewPortHandler.isInBoundsLeft(mBarShadowRectBuffer.right)) | |
| continue; | |
| if (!mViewPortHandler.isInBoundsRight(mBarShadowRectBuffer.left)) | |
| break; | |
| mBarShadowRectBuffer.top = mViewPortHandler.contentTop(); | |
| mBarShadowRectBuffer.bottom = mViewPortHandler.contentBottom(); | |
| c.drawRoundRect(mBarShadowRectBuffer, mRadius, mRadius, mShadowPaint); | |
| } | |
| } | |
| // initialize the 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); | |
| final boolean isSingleColor = dataSet.getColors().size() == 1; | |
| if (isSingleColor) { | |
| 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 (!isSingleColor) { | |
| // Set the color for the currently drawn value. If the index | |
| // is out of bounds, reuse colors. | |
| mRenderPaint.setColor(dataSet.getColor(j / 4)); | |
| } | |
| if (dataSet.getGradientColor() != null) { | |
| GradientColor gradientColor = dataSet.getGradientColor(); | |
| mRenderPaint.setShader( | |
| new LinearGradient( | |
| buffer.buffer[j], | |
| buffer.buffer[j + 3], | |
| buffer.buffer[j], | |
| buffer.buffer[j + 1], | |
| gradientColor.getStartColor(), | |
| gradientColor.getEndColor(), | |
| android.graphics.Shader.TileMode.MIRROR)); | |
| } | |
| if (dataSet.getGradientColors() != null) { | |
| mRenderPaint.setShader( | |
| new LinearGradient( | |
| buffer.buffer[j], | |
| buffer.buffer[j + 3], | |
| buffer.buffer[j], | |
| buffer.buffer[j + 1], | |
| dataSet.getGradientColor(j / 4).getStartColor(), | |
| dataSet.getGradientColor(j / 4).getEndColor(), | |
| android.graphics.Shader.TileMode.MIRROR)); | |
| } | |
| c.drawRoundRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], | |
| buffer.buffer[j + 3], mRadius, mRadius, mRenderPaint); | |
| if (drawBorder) { | |
| c.drawRoundRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], | |
| buffer.buffer[j + 3], mRadius, mRadius, mBarBorderPaint); | |
| } | |
| } | |
| } | |
| } | |
| } |
Thank you so much can you please create MR to MPAndroidChart this should come in library itself IMO
PhilJay/MPAndroidChart#2771 (comment)
yes, but the project seams abandoned
how about rounding from both ends?
how about rounding from both ends?
(Kotlin)
use chart.axisLeft.axisMinimum = 0f to make corner rounded from both end
Finally a working solution after almost 2 month of hustling to find the solution
Cannot resolve symbol 'radius'
great work thanks for the solution
greate work ,
how about HorizontalRoundedBarChart ?
greate work , how about HorizontalRoundedBarChart ?
solved , look https://github.com/mahditavakoli1312/mpchartandroid.git
u saved my time thankss
how to give only both top radius?
Hi you can add this code in this overridden method
void drawDataSet(Canvas c, IBarDataSet dataSet, int index)
float barLeft = buffer.buffer[j];
float barTop = buffer.buffer[j + 1];
float barRight = buffer.buffer[j + 2];
float barBottom = buffer.buffer[j + 3];
// Adjust rounded corners for top left and top right corners
float[] radii = new float[]{
mRadius, mRadius, mRadius, mRadius,
0f, 0f, 0f, 0f
};
// Draw the rounded rectangle with adjusted corners
Path path = new Path();
path.addRoundRect(new RectF(barLeft, barTop, barRight, barBottom), radii, Path.Direction.CW);
c.drawPath(path, mRenderPaint);
if (drawBorder) {
c.drawPath(path, mBarBorderPaint);
}
// comment this code
/*c.drawRoundRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
buffer.buffer[j + 3], mRadius, mRadius, mRenderPaint);
if (drawBorder) {
c.drawRoundRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
buffer.buffer[j + 3], mRadius, mRadius, mBarBorderPaint);
}*/
Amazing, great work!
greate work , how about HorizontalRoundedBarChart ?
solved , look https://github.com/mahditavakoli1312/mpchartandroid.git
https://github.com/AppDevNext/AndroidChart
There is active fork
great work, thanks