2015-06-10 88 views
5

我想创建一个如下图表,对于我的android应用程序使用MPAndroidChart。我无法弄清楚,如何使条形图的边缘变圆。它总是来自方形边缘。MPAndroidChart - 圆边条形图

enter image description here

所以,可以请你建议我应该怎么办?

提前感谢您的帮助。

回答

8

我已经实现了一个解决方案,直接实现库本身。

首先创建一个attrs.xml,添加一个新的属性以在您的图表视图中使用。事情是这样的:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="BarChart"> 
     <attr name="radius" format="integer" /> 
    </declare-styleable> 
</resources> 

然后编辑在BarChartRenderer称为drawDataSet方法:

protected void drawDataSet(Canvas c, BarDataSet dataSet, int index) { 

    Transformer trans = mChart.getTransformer(dataSet.getAxisDependency()); 

    mShadowPaint.setColor(dataSet.getBarShadowColor()); 

    float phaseX = mAnimator.getPhaseX(); 
    float phaseY = mAnimator.getPhaseY(); 

    List<BarEntry> entries = dataSet.getYVals(); 

    // initialize the buffer 
    BarBuffer buffer = mBarBuffers[index]; 
    buffer.setPhases(phaseX, phaseY); 
    buffer.setBarSpace(dataSet.getBarSpace()); 
    buffer.setDataSet(index); 
    buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency())); 

    buffer.feed(entries); 

    trans.pointValuesToPixel(buffer.buffer); 

    // if multiple colors 
    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 (mRadius > 0) 
        c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), 
          buffer.buffer[j + 2], 
          mViewPortHandler.contentBottom()), mRadius, mRadius, 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 
      // is 
      // out of bounds, reuse colors. 
      mRenderPaint.setColor(dataSet.getColor(j/4)); 
      if (mRadius > 0) 
       c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], 
         buffer.buffer[j + 3]), mRadius, mRadius, 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 (mRadius > 0) 
        c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), 
          buffer.buffer[j + 2], 
          mViewPortHandler.contentBottom()), mRadius, mRadius, mShadowPaint); 
       else 
        c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], 
          buffer.buffer[j + 3], mRenderPaint); 
      } 

      if (mRadius > 0) 
       c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], 
         buffer.buffer[j + 3]), mRadius, mRadius, mRenderPaint); 
      else 
       c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], 
         buffer.buffer[j + 3], mRenderPaint); 
     } 
    } 
} 

这样做,你会改变长方形而不是它的亮点,所以更改这段代码的drawHighlighted方法:

if (mRadius > 0) 
     c.drawRoundRect(mBarRect, mRadius, mRadius, mHighlightPaint); 
else 
     c.drawRect(mBarRect, mHighlightPaint); 

为了从XML文件中的属性在此呈现你需要添加一套方法,以及:

public void setRadius (int radius) { 
     mRadius = radius; 
} 

的BARCHART对象最后创建一个新的构造抢半径属性:

public BarChart(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     mRadius = attrs.getAttributeIntValue("http://schemas.android.com/apk/res-auto", "radius", 0); 
     ((BarChartRenderer)mRenderer).setRadius(mRadius); 
    } 

瞧!快乐编码:)

+0

是否有原因使用这种方法只有顶角四舍五入? –

+0

非常感谢你... –

0

上面的回答是正确的,但是如果图表有负值它不起作用。

我已经选择了圆角矩形代码形式this答案。

步骤

  1. 添加以下方法来BarChartRenderer

    /** 
    * @param rect rectangle to be rounded 
    * @param rx radius x 
    * @param ry radius y 
    * @param tl true - for rounding top-left corner 
    * @param tr true - for rounding top-right corner 
    * @param br true - for rounding bottom-right corner 
    * @param bl true - for rounding bottom-left corner 
    * @return path 
    */ 
    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();//Given close, last lineto can be removed. 
    
    return path; 
    } 
    
  2. drawDataSet(Canvas c, IBarDataSet dataSet, int index)方法,替换所有drawRoundRect方法用下面的代码

    Path path = roundRect(yourRect, yourRadius, yourRadius, true, true, false, false); 
           canvas.drawPath(path, yourPaint); 
    
0

为此,你需要custimze您BarchartRenderer类.... 步骤1: 创建自定义类(如果您不添加mpchart作为模块)复制粘贴BarchartRenderer类中的所有代码到乌尔定制类。 现在用我的ur定制类替换你的drawDataSet方法.....

之后setRender到你刚刚创建的自定义类。

设置渲染Java代码的Kotlin代码将有点不同。最终享受

topperChart.setRenderer(BarChartCustomRenderer(mDashBoardBinding.topperChart,mDashBoardBinding.topperChart.getAnimator(),mDashBoardBinding.topperChart.getViewPortHandler()))

保护无效drawDataSet(帆布C,IBarDataSet数据集,INT索引){

Transformer trans = mChart.getTransformer(dataSet.getAxisDependency()); 

    mShadowPaint.setColor(dataSet.getBarShadowColor()); 

    float phaseX = mAnimator.getPhaseX(); 
    float phaseY = mAnimator.getPhaseY(); 


    // initialize the buffer 
    BarBuffer buffer = mBarBuffers[index]; 
    buffer.setPhases(phaseX, phaseY); 
    buffer.setDataSet(index); 
    buffer.setBarWidth(mChart.getBarData().getBarWidth()); 
    buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency())); 

    buffer.feed(dataSet); 

    trans.pointValuesToPixel(buffer.buffer); 

    // if multiple colors 
    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 (mRadius > 0) 
        c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), 
          buffer.buffer[j + 2], 
          mViewPortHandler.contentBottom()), mRadius, mRadius, 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 
      // is 
      // out of bounds, reuse colors. 
      mRenderPaint.setColor(dataSet.getColor(j/4)); 
      if (mRadius > 0) 
       c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], 
         buffer.buffer[j + 3]), mRadius, mRadius, 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 (mRadius > 0) 
        c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), 
          buffer.buffer[j + 2], 
          mViewPortHandler.contentBottom()), mRadius, mRadius, mShadowPaint); 
       else 
        c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], 
          buffer.buffer[j + 3], mRenderPaint); 
      } 

      if (mRadius > 0) 
       c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], 
         buffer.buffer[j + 3]), mRadius, mRadius, mRenderPaint); 
      else 
       c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], 
         buffer.buffer[j + 3], mRenderPaint); 
     } 
    } 
} 
+0

你可以更多地格式化它吗? – Billa

+0

嗨,刚刚检查了你的评论... Lemme知道你是否还需要任何关于它的好处 –