关于MpAndroidChart修改background为自定义图像

    菜鸟一位,之前还在纠结项目不能导入n多个 github上下载或者自己建立的库文件,当修改完mpchart源码之后,发现不能导入,半天的时光耗费,发现了一个好的方法,将修改完源码的库打成jar包,导入到自己项目中。

 可能大牛们都已经知道了,但是对于新手来讲确实眼前一亮。

具体jar包位置在库目录   比如  Xutils\build\intermediates\bundles\release\class.jar

记得先build一下生成class.jar 然后自己把文件copy出来改个名字当作jar包导入。

言归正传,产品给了一个新的UI,效果图如下


这在普通的mpchart来说确实很难实现,只能去研究源码了,这里非常感谢http://blog.csdn.net/baidu_34934230/article/details/52386592此文的作者。助我找到了源码需要修改的地方,发现mpchart也是分层去绘制,参考此文的介绍找到 2个类 IBarDataSet类和它的实现类BarDataSet,发现IBarDataSet类中定义了几个接口即:

public interface IBarDataSet extends IBarLineScatterCandleBubbleDataSet<BarEntry> {

    /**
     * Returns the space between bars as the actual value (0 - 1.0f)
     *
     * @return
     */
    float getBarSpace();

    /**
     * Returns true if this DataSet is stacked (stacksize > 1) or not.
     *
     * @return
     */
    boolean isStacked();

    /**
     * Returns the maximum number of bars that can be stacked upon another in
     * this DataSet. This should return 1 for non stacked bars, and > 1 for stacked bars.
     *
     * @return
     */
    int getStackSize();

    /**
     * Returns the color used for drawing the bar-shadows. The bar shadows is a
     * surface behind the bar that indicates the maximum value.
     *
     * @return
     */
    int getBarShadowColor();

    /**
     * Returns the alpha value (transparency) that is used for drawing the
     * highlight indicator.
     *
     * @return
     */
    int getHighLightAlpha();


    /**
     * Returns the labels used for the different value-stacks in the legend.
     * This is only relevant for stacked bar entries.
     *
     * @return
     */
    String[] getStackLabels();

    Drawable getBarBitmapBackGround();
}
最后面的getBarBitmapBackGround是我后来自己添加的方法,这里命名不太规范,应该改为getBitmapBackGround();

然后找到IBardataSet的实现类,去实现他的方法,这里有2个实现类,另外一个我就不贴代码了,因为我们只用到了BarDataSet类,

package com.github.mikephil.charting.data;

import android.graphics.Color;
import android.graphics.drawable.Drawable;

import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;

import java.util.ArrayList;
import java.util.List;

public class BarDataSet extends BarLineScatterCandleBubbleDataSet<BarEntry> implements IBarDataSet {

    /**
     * bar background
     */
    private Drawable mBitmapBarBakcground;
    public void setmBitmapBarBakcground(Drawable mBitmapBarBakcground) {
        this.mBitmapBarBakcground = mBitmapBarBakcground;
    }
    @Override
    public Drawable getBarBitmapBackGround() {
        return mBitmapBarBakcground;
    }
/** * the color used for drawing the bar shadows */  
private int mBarShadowColor = Color.rgb(215, 215, 215);   
 @Override   
 public DataSet<BarEntry> copy() {
        List<BarEntry> yVals = new ArrayList<BarEntry>();
        for (int i = 0; i < mYVals.size(); i++) { 
           yVals.add(((BarEntry) mYVals.get(i)).copy());
        
       BarDataSet copied = new BarDataSet(yVals, getLabel()); 
       copied.mColors = mColors;      
  copied.mStackSize = mStackSize;   
     copied.mBarSpace = mBarSpace;  
      copied.mBarShadowColor = mBarShadowColor;    
    copied.mStackLabels = mStackLabels;     
   copied.mHighLightColor = mHighLightColor;  
      copied.mHighLightAlpha = mHighLightAlpha; 
       copied.mBitmapBarBakcground=mBitmapBarBakcground;       
 return copied;   
 }    
/**     * Sets the color used for drawing the bar-shadows. The bar shadows is a     * surface behind the bar that indicates the maximum value. Don't for get to     * use getResources().getColor(...) to set this. Or Color.rgb(...). 
    *    
 * @param color     
*/    public void setBarShadowColor(int color) {       
 mBarShadowColor = color;   
 }   
 @Override    public int getBarShadowColor() {    
    return mBarShadowColor;   
 }    
}
这里我只粘贴了几段有代表性的代码, mBitmapBarBakcground 

是我 自定义的一个属性当然改为mBitmapBackground更好一点,这里就靠大家自己去修改了,

做到这里,已然将我们自己自定义的属性搭配好,下面就开始去找绘图的源码了。借助http://blog.csdn.net/baidu_34934230/article/details/52386592

作者的分析我们找到了绘图的源码。即:

public class BarChartRenderer extends DataRenderer {

    protected BarDataProvider mChart;

    /**
     * the rect object that is used for drawing the bars
     */
    protected RectF mBarRect = new RectF();

    protected BarBuffer[] mBarBuffers;

    protected Paint mShadowPaint;
    private Drawable mBitmapBarBakcground;//......................................

    @Override
    public void drawData(Canvas c) {

        BarData barData = mChart.getBarData();

        for (int i = 0; i < barData.getDataSetCount(); i++) {

            IBarDataSet set = barData.getDataSetByIndex(i);

            if (set.isVisible() && set.getEntryCount() > 0) {
                drawDataSet(c, set, i);
            }
        }
    }

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

        Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
        mShadowPaint.setColor(dataSet.getBarShadowColor());
        mBitmapBarBakcground = dataSet.getBarBitmapBackGround();//................
        float phaseX = mAnimator.getPhaseX();
        float phaseY = mAnimator.getPhaseY();

        // 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(dataSet);

        trans.pointValuesToPixel(buffer.buffer);

        // draw the bar shadow before the values
        if (mChart.isDrawBarShadowEnabled()) {

            for (int j = 0; j < buffer.size(); j += 4) {

                if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2]))
                    continue;

                if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))
                    break;
                Rect r=new Rect((int)(buffer.buffer[j])
			(int)mViewPortHandler.contentTop(),
                        (int)buffer.buffer[j + 2],
			(int)mViewPortHandler.contentBottom());
                c.drawRect(r,mShadowPaint);
//                if (mBitmapBarBakcground != null) {
//                    Log.i("chatUtil","0back!=null");
//                    Bitmap bitmap=((BitmapDrawable)mBitmapBarBakcground).getBitmap();
//                    c.drawBitmap(bitmap, r, r, mRenderPaint);
//                } else {
//                    Log.i("chatUtil","0back==null");
//                    c.drawRect(r, mRenderPaint);
//                }
            }
        }

        // 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;

                // Set the color for the currently drawn value. If the index
                // is
                // out of bounds, reuse colors.
                if(mBitmapBarBakcground==null){//....................................
                mRenderPaint.setColor(dataSet.getColor(j / 4));
                }else {
                    mRenderPaint.setFilterBitmap(true);
                    mRenderPaint.setDither(true);
                }
//                c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
//                        buffer.buffer[j + 3], mRenderPaint);

                Rect r=new Rect((int)buffer.buffer[j], (int)buffer.buffer[j + 1], 
		(int)buffer.buffer[j + 2],
(int)buffer.buffer[j + 3]);
                if (mBitmapBarBakcground != null) {//.......................................                    Log.i("chartUtil","1back!=null"); 
                   Bitmap bitmap=((BitmapDrawable)mBitmapBarBakcground)
                    .getBitmap();
c.drawBitmap(bitmap, r, r, mRenderPaint);
                } else 
                   Log.i("chartUtil","1back==null"); 
                   c.drawRect(r, mRenderPaint);  
              
       } else 
           if(mBitmapBarBakcground==null){//..........................................            mRenderPaint.setColor(dataSet.getColor());
            }else 
               mRenderPaint.setFilterBitmap(true); 
               mRenderPaint.setDither(true); 
           }   
         for (int j = 0; j < buffer.size(); j += 4) {  
              if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2]))                    continue;  
              if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))                    			break;
//                c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], 
//			buffer.buffer[j + 2],
//                        buffer.buffer[j + 3], mRenderPaint);  
              Rect r = new Rect((int) buffer.buffer[j], (int) buffer.          
		buffer[j + 1], (int) buffer.buffer[j + 2],
(int) buffer.buffer[j + 3]); 
               if (mBitmapBarBakcground != null) {//...................................                    
		Log.i("chartUtil","2back!=null");
                    mBitmapBarBakcground.setBounds(r); 
                   mBitmapBarBakcground.draw(c);
                } else 
                   Log.i("chatrUtil","2back==null"); 
                   c.drawRect(r, mRenderPaint);
                
       }
    }
}
找到drawdata方法 然后看到一个循环,我想到的是每条柱子的绘制,然后找到drawDataSet方法,跟进去,简单修改了源码,

由于没想配置太多,只简单的做了一个设置方法,后期读者可以添加各种drawBackGroundBitmap(boolean canable)类似的,就

由读者自行去使用了,到此位置,简单实现了UI要求。介于此有一些疑点


 

为什么将方法加到IbarDataSet里面是因为 mp3.0后BarChart的Bardata初始化方法有了调整

barDataSet.setBarSpacePercent(space);//柱状图之间宽度
barDataSet.setmBitmapBarBakcground(context.getDrawable(R.drawable.barbg));//具体使用
barDataSet.setHighLightAlpha(00);
ArrayList<IBarDataSet> barSets = new ArrayList<IBarDataSet>();
barSets.add(barDataSet);
BarData barData = new BarData(xTittles, barSets);

这里使用的是IbardataSet,当然可以将方法只添加到BardataSet里面。看个人需求了。


本人菜鸟一枚,如果有问题欢迎一起讨论

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值