Android 自定义View 条形图

来源:互联网 发布:n反斜杠百分之d c语言 编辑:程序博客网 时间:2024/05/16 07:30

像咱们这种工作性质,我觉得有时候真的不能不懂装懂,实事求是,踏踏实实,才能走的长远。。。。(跑题了)

上一篇中我们用自定义View画了一个饼图,今天我就用自定义View画一个条形图。


咱们在画饼图的时候,始终以屏幕的左上角为原点,我觉得这样计算起来有点麻烦,所以今天画条形图的时候,我们来移动原点坐标:

canvas.translate(mScreenWidth*0.07f, mScreenHeight*0.75f);

这样就把坐标原点移动到了左下方的位置

1. 画横纵坐标轴,哎,好头疼,这玩意没什么难度,但就是好烦。。。。

//绘制横坐标轴canvas.drawLine(0, 0, mScreenWidth*0.8f, 0, mChatPaint);//绘制箭头的下半部分canvas.drawLine(        mScreenWidth*0.8f,        0,        mScreenWidth*0.8f-40*(float)Math.cos(30*(Math.PI/180)),        (float) Math.sin(30*(Math.PI/180))*40,        mChatPaint);//绘制箭头的上半部分canvas.drawLine(        mScreenWidth*0.8f,        0,        mScreenWidth*0.8f-40*(float)Math.cos(30*(Math.PI/180)),        -(float) Math.sin(30*(Math.PI/180))*40,        mChatPaint);//绘制纵坐标轴canvas.drawLine(        0,        0,        0,        -mScreenHeight*0.7f,        mChatPaint);//绘制箭头的左边部分canvas.drawLine(        0,        -mScreenHeight*0.7f,        -((float) Math.sin(30*(Math.PI/180))*40),        -mScreenHeight*0.7f+((float)Math.cos(30*(Math.PI/180))*40),        mChatPaint);//绘制箭头的右边部分canvas.drawLine(        0,        -mScreenHeight*0.7f,        (float) Math.sin(30*(Math.PI/180))*40,        -mScreenHeight*0.7f+((float)Math.cos(30*(Math.PI/180))*40),        mChatPaint);

2. 在Y轴上找出一段距离,用于标记数值

//纵坐标数据存放的长度(总的Y坐标轴长度 - 顶端箭头纵坐标的长度*2)mDataHeight = mScreenHeight*0.7f - (float)Math.cos(30*(Math.PI/180))*40*2;
我这里直接用Y轴的长度减去箭头的Y坐标的二倍,当然这里可以自己定

//每个刻度之间的数据间隔int mIntevalDataY = (int) Math.ceil((double) mDatamax/(double) INTERVAL_NUM);
根据外部传过来的map,根据数据总数除以我们定义的Y轴的份数,就能得到每一份的数值大小

3. 在Y轴上画刻度了

//每个刻度所占的Y轴高度float mEveryHeight = mDataHeight/INTERVAL_NUM;for (int j = 0; j <= INTERVAL_NUM; j++) {    if(j != 0) {        //绘制Y轴刻度        canvas.drawLine(0, -mEveryHeight * j, 10, -mEveryHeight * j, mChatPaint);    }    //计算文字Y在刻度点正中间的Y坐标    float baseY = mEveryHeight*j + ((mTextPaint.descent() + mTextPaint.ascent())/2);    canvas.drawText(String.valueOf(mIntevalDataY*j), -5, -baseY, mTextPaint);}
每个刻度所占的高度我们知道,数据中的最大值我们也可以计算得到,很轻松就可以画出来了,这块有个小细节,就是绘制文字的时候,需要得到descent和ascent,来使文字垂直居中,什么?不知道这两个变量是啥?自己查去。。。。

4. 绘制X轴上条形图的一些准备工作

//Y轴顶端刻度的最大值int mDataYMax = mIntevalDataY*INTERVAL_NUM;//每个数据点所占的Y轴高度float mEveryDataSize = mDataHeight/mDataYMax;//横坐标数据存放的长度(总的x坐标轴长度 - 顶端箭头横坐标的长度)float mDataWidth = mScreenWidth*0.8f - 40*(float)Math.cos(30*(Math.PI/180)) - 20;//每个数据横坐标所占的宽度float mEveryDataWidth = mDataWidth/mDataMap.size();//每个柱状图横轴所占宽度float mDataW = mEveryDataWidth*0.75f;//每个柱状图之间的间隔float mDataIntervalW = mEveryDataWidth*0.25f;//柱状图绘制X轴起始位置float mStartPosition;//柱状图绘制X轴结束位置float mEndPosition;//柱状图高度float mEveryDataHeight;
我就不一一解释了哈,注释写的很明白

5. 开始画矩形,

Iterator<Map.Entry<String, Integer>> entries = mDataMap.entrySet().iterator();//记录画到第几个柱状图了int index = 1;while (entries.hasNext()){    Map.Entry<String, Integer> entry = entries.next();    String mKey = entry.getKey();    Integer mValue = entry.getValue();    //计算文字x坐标起始点    mStartPosition = mDataIntervalW*index + mDataW*(index-1);    //计算文字y坐标起始点源码    mEndPosition = mDataIntervalW*index + mDataW*index;    //设置增量值,添加动画    mEveryDataHeight = Math.min(mEveryDataSize*mValue, mAnimationUpdate);    //设置画笔颜色    mChatPaint.setColor(mColorList.get(index - 1));    canvas.drawRect(mStartPosition, -mEveryDataHeight, mEndPosition, 0, mChatPaint);    //计算绘制文字的起始点X坐标    mPaintXText.setTextAlign(Paint.Align.CENTER);    float mTextCenterX = mEndPosition - mDataW*0.5f;    canvas.drawText(mKey, mTextCenterX, mPaintXText.descent()-mPaintXText.ascent(), mPaintXText);    index++;}
好像也没啥好说的,那就不说了。。。。。。。

最后,我觉得条形图比饼图要好画很多,按部就班的绘制就可以了。。。。。

源码


0 0
原创粉丝点击