2015-06-10 26 views
5

Tôi đang cố gắng tạo biểu đồ như dưới đây, Đối với ứng dụng Android của tôi sử dụng MPAndroidChart. Tôi không thể tìm ra, làm thế nào để làm cho các cạnh của biểu đồ thanh như hình tròn. Nó luôn luôn là cạnh vuông.MPAndroidChart - Biểu đồ thanh tròn tròn

enter image description here

Vì vậy, bạn có thể đề nghị tôi nên làm gì?

Xin cảm ơn sự giúp đỡ của bạn trước.

Trả lời

8

Tôi đã triển khai giải pháp để đạt được điều đó ngay trên chính thư viện.

Trước hết hãy tạo attrs.xml thêm thuộc tính mới để sử dụng trên chế độ xem biểu đồ của bạn. Một cái gì đó như thế này:

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

Sau đó chỉnh sửa các phương pháp gọi là drawDataSet trên BarChartRenderer:

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); 
     } 
    } 
} 

Bằng cách này bạn đang thay đổi hình chữ nhật nhưng không nổi bật của nó, vì vậy thay đổi chút mã này trên phương pháp drawHighlighted:

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

để có được thuộc tính từ file xml vào này khiến bạn cần phải thêm một phương pháp thiết lập cũng như:

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

Cuối cùng tạo một constructor mới trên đối tượng BarChart để lấy các thuộc tính radius:

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); 
    } 

Và thì đấy! Happy coding :)

+0

Có lý do gì để sử dụng phương pháp này chỉ các góc trên cùng được làm tròn không? –

+0

Cảm ơn bạn rất nhiều ... –

0

Câu trả lời ở trên là đúng nhưng nó không hoạt động nếu biểu đồ có giá trị âm.

Tôi đã chọn hình thức mã hình chữ nhật tròn this câu trả lời.

bước

  1. Thêm phương pháp sau đây để BarChartRenderer lớp

    /** 
    * @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. Trong drawDataSet(Canvas c, IBarDataSet dataSet, int index) phương pháp, thay thế tất cả drawRoundRect phương pháp với đoạn mã sau

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

Đối với mục đích này, bạn cần phải custimze lớp BarchartRenderer của bạn .... Bước 1: Tạo một lớp tùy chỉnh (nếu bạn không thêm mpchart như mô-đun) Sao chép dán tất cả các mã từ lớp BarchartRenderer vào ur tùy chỉnh lớp học. Bây giờ hãy thay thế phương thức drawDataSet của bạn bằng tôi trong lớp tùy chỉnh ur .....

Sau đó setRender cho lớp tùy chỉnh bạn vừa tạo.

Mã Kotlin để thiết lập hiển thị Mã Java sẽ giống nhau. Cuối cùng thưởng thức

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

protected void drawDataSet (Canvas c, IBarDataSet DataSet, int chỉ số) {

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

Bạn có thể định dạng nó nhiều hơn một chút không. – Billa

+0

Xin chào, bạn chỉ cần kiểm tra nhận xét của mình ... Hãy cho biết nếu bạn vẫn cần bất kỳ ưu tiên nào liên quan đến nó –

Các vấn đề liên quan