2016-12-27 2 views
5

Я использую MPAndroidChart и я хочу, чтобы показать пользовательские рисуем внутри этого CombinedChart, как в изображении ниже:MPAndroidChart: добавить пользовательское изображение в барах

a bar chart with star images inside the bars

Если значение бар> = значение цели, скажем, , 50, то я хотел бы добавить изображение звезды внутри панели.

Может ли кто-нибудь помочь мне настроить BarChart?

ответ

4

Чтобы получить изображение звезды внутри наших баров, нам нужно создать собственный рендер. Поскольку наша гистограмма использует BarChartRenderer мы подклассы это первое и добавить параметр для нашего изображения:

public class ImageBarChartRenderer extends BarChartRenderer { 

    private final Bitmap barImage; 

    public ImageBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler, Bitmap barImage) { 
     super(chart, animator, viewPortHandler); 
     this.barImage = barImage; 
    } 

Если мы исследуем источник для BarChartRenderer мы можем видеть, что он вызывает метод, называемый drawData, а затем перебирает DataSet и звонки drawDataSet. drawDataSet - это место, где происходит действие: оно рисует тени и бары. Это подходящее место, чтобы добавить логику, чтобы привлечь дополнительный, например, изображений, так что давайте добавим вызов метода сделать наши изображения есть:

@Override 
    protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { 
     super.drawDataSet(c, dataSet, index); 
     drawBarImages(c, dataSet, index); 
    } 

теперь нужен метод, который будет перебирать через DataSet и нарисовать звезду изображений. Соответствующим методом, который будет служить шаблоном, является drawValues, поэтому давайте его скопируем и изменим так, чтобы рисовать изображение, а не текст. Ключом к пониманию этого является то, как работает BarBuffer. BarBuffer держит экранные (пиксельные) координаты для бара для данного входа в j, j + 1, j + 2, j + 3.

Для уточнения, j - координата слева x, j + 1 - это верхняя координата y и т. Д., Которая направляется вправо по координате x по адресу j + 3. Мы будем извлекать их для переменных, чтобы сделать его легче понять:

protected void drawBarImages(Canvas c, IBarDataSet dataSet, int index) { 
     BarBuffer buffer = mBarBuffers[index]; 

     float left; //avoid allocation inside loop 
     float right; 
     float top; 
     float bottom; 

     for (int j = 0; j < buffer.buffer.length * mAnimator.getPhaseX(); j += 4) { 
      left = buffer.buffer[j]; 
      right = buffer.buffer[j + 2]; 
      top = buffer.buffer[j + 1]; 
      bottom = buffer.buffer[j + 3]; 

      float x = (left + right)/2f; 

      if (!mViewPortHandler.isInBoundsRight(x)) 
       break; 

      if (!mViewPortHandler.isInBoundsY(top) 
        || !mViewPortHandler.isInBoundsLeft(x)) 
       continue; 

      BarEntry entry = dataSet.getEntryForIndex(j/4); 
      float val = entry.getY(); 

      if (val > 50) { 
       drawStar(c, barImage, x, top); 
      } 
     } 
    } 

Вот как использовать визуализатор:

Bitmap starBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.star); 
    mChart.setRenderer(new ImageBarChartRenderer(mChart, mChart.getAnimator(), mChart.getViewPortHandler(), starBitmap)); 

Последний шаг к визуализатору, чтобы добавить логику для масштабирования растрового изображения и положите его правильно. Вот окончательное доказательство правильности концепции пользовательского рендера:

package com.xxmassdeveloper.mpchartexample; 

import android.graphics.Bitmap; 
import android.graphics.Canvas; 

import com.github.mikephil.charting.animation.ChartAnimator; 
import com.github.mikephil.charting.buffer.BarBuffer; 
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.renderer.BarChartRenderer; 
import com.github.mikephil.charting.utils.ViewPortHandler; 

/** 
* Created by David on 29/12/2016. 
*/ 

public class ImageBarChartRenderer extends BarChartRenderer { 

    private final Bitmap barImage; 

    public ImageBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler, Bitmap barImage) { 
     super(chart, animator, viewPortHandler); 
     this.barImage = barImage; 
    } 

    @Override 
    public void drawData(Canvas c) { 
     super.drawData(c); 
    } 

    @Override 
    protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { 
     super.drawDataSet(c, dataSet, index); 
     drawBarImages(c, dataSet, index); 
    } 

    protected void drawBarImages(Canvas c, IBarDataSet dataSet, int index) { 
     BarBuffer buffer = mBarBuffers[index]; 

     float left; //avoid allocation inside loop 
     float right; 
     float top; 
     float bottom; 

     final Bitmap scaledBarImage = scaleBarImage(buffer); 

     int starWidth = scaledBarImage.getWidth(); 
     int starOffset = starWidth/2; 

     for (int j = 0; j < buffer.buffer.length * mAnimator.getPhaseX(); j += 4) { 
      left = buffer.buffer[j]; 
      right = buffer.buffer[j + 2]; 
      top = buffer.buffer[j + 1]; 
      bottom = buffer.buffer[j + 3]; 

      float x = (left + right)/2f; 

      if (!mViewPortHandler.isInBoundsRight(x)) 
       break; 

      if (!mViewPortHandler.isInBoundsY(top) 
        || !mViewPortHandler.isInBoundsLeft(x)) 
       continue; 

      BarEntry entry = dataSet.getEntryForIndex(j/4); 
      float val = entry.getY(); 

      if (val > 50) { 
       drawImage(c, scaledBarImage, x - starOffset, top); 
      } 
     } 
    } 

    private Bitmap scaleBarImage(BarBuffer buffer) { 
     float firstLeft = buffer.buffer[0]; 
     float firstRight = buffer.buffer[2]; 
     int firstWidth = (int) Math.ceil(firstRight - firstLeft); 
     return Bitmap.createScaledBitmap(barImage, firstWidth, firstWidth, false); 
    } 

    protected void drawImage(Canvas c, Bitmap image, float x, float y) { 
     if (image != null) { 
      c.drawBitmap(image, x, y, null); 
     } 
    } 
} 

Вот снимок экрана - вы можете увидеть, что значения более 50 имеют звезды:

bar chart with custom image inside bars

+0

Спасибо за ответ. –

+0

Добро пожаловать. –

+0

Какую версию mpandroid chart вы использовали здесь? – Amalo

Смежные вопросы