2015-06-10 21 views
5

Sto cercando di creare un grafico come di seguito, Per la mia applicazione Android utilizzando MPAndroidChart. Non riesco a capire come rendere i bordi del grafico a barre arrotondati. Viene sempre come bordo quadrato.MPAndroidChart - Grafico a barre con bordi arrotondati

enter image description here

così si può per favore mi suggeriscono cosa devo fare?

In anticipo grazie per il vostro aiuto.

risposta

8

Ho implementato una soluzione per ottenerlo direttamente nella libreria stessa.

Innanzitutto creare un attrs.xml aggiungendo un nuovo attributo da utilizzare nella vista del grafico. Qualcosa di simile a questo:

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

quindi modificare il metodo chiamato drawDataSet sul 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); 
     } 
    } 
} 

In questo modo si sta modificando il rettangolo, ma non il suo punto forte, in modo da cambiare questo pezzo di codice sul metodo drawHighlighted:

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

per ottenere l'attributo dal file XML su questo rendering è necessario aggiungere un metodo set così:

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

creare infine un nuovo costruttore sull'oggetto DiagrammaBarre per afferrare l'attributo Raggio:

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

E voilà! Felice codifica :)

+0

C'è un motivo per cui utilizzando questo metodo solo gli angoli superiori sono arrotondati? –

+0

Grazie mille ... –

0

La risposta sopra è giusta ma non funziona se il grafico ha valori negativi.

Ho scelto il modulo di codice rettangolo arrotondato this risposta.

Passi

  1. aggiungere il seguente metodo alla classe 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. In drawDataSet(Canvas c, IBarDataSet dataSet, int index) metodo, sostituire tutti i drawRoundRect metodi con il seguente codice

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

A tale scopo è necessario custimze la classe BarchartRenderer .... Fase 1: Fai una classe personalizzata (se non si aggiunge mpchart come modulo) Copia Incolla tutto il codice dalla classe BarchartRenderer in ur personalizzati classe. Ora sostituisci il tuo metodo drawDataSet con il mio nella tua classe personalizzata .....

Dopo quel setRender alle classi personalizzate che hai appena creato.

Codice Kotlin per l'impostazione del rendering Il codice Java sarà simile. Alla fine godere

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

protected void drawDataSet (Tela c, IBarDataSet dataset, int indice) {

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

Puoi formattarlo un po 'di più. – Billa

+0

Ciao ho appena controllato il tuo commento ... Fammi sapere se hai ancora bisogno di favore –

Problemi correlati