因为一直喜欢琢磨界面,所以总爱翻跟界面有关的文章。之前在HenCoder上看到自定义View的教学,就跟着敲出了饼图和柱状图:
一、饼图
1、数据初始化
饼图绘制的关键是角度,获取数据后将各个数据在总数中的占比转化成角度进行绘制。
/*数据总和*/
sum = 0;
/*饼图每部分开始绘制的角度*/
startAngle = 0;
/*饼图每部分结束绘制的角度*/
endAngle = 0;
/*获取数值总和,最大数值及其下标*/
for (int i=0;i=maxValue){
maxValue = values[i];
maxIndex = i;
Log.d(TAG,"maxValue:"+maxValue);
Log.d(TAG,"maxIndex:"+maxIndex);
}
}
Log.d(TAG,"sum:"+sum);
textPaint = new Paint();
paint = new Paint();
path = new Path();
paint.setAntiAlias(true);/*开启抗锯齿*/
2、绘制数值
获取画布的宽高,设置恰当的半径,开始绘制。
if(values.length>0&&values.length==datas.length){
init();
int width = getWidth();
int height = getHeight();
int r = Math.min(width,height)/2;
paint.setStyle(Paint.Style.STROKE);
paint.setColor(textColor);
paint.setStrokeWidth(strokeWidth);
textPaint.setTextSize(percentSize);
/*圆的半径*/
int R = (int)(r- r*0.15f);
/*绘制数值*/
for (int i=0; i90&&startAngle+angle/2<270){
path.rLineTo(-stripValue,0);
textPaint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText(String.format("%.2f", percent*100)+"%",
width/2+x-text2strip+xOffset+xMaxOffset,height/2+y+yOffset+yMaxOffset,textPaint);
}else {
path.rLineTo(stripValue,0);
textPaint.setTextAlign(Paint.Align.LEFT);
canvas.drawText((String.format("%.2f", percent*100))+"%",
width/2+x+text2strip+xOffset+xMaxOffset,height/2+y+yOffset+yMaxOffset,textPaint);
}
canvas.drawPath(path,paint);
}
3、绘制饼图和文字
衔接上面的代码开始绘制饼图和文字
/*绘制饼图*/
startAngle=endAngle=angle=0;
paint.setStyle(Paint.Style.FILL);
RectF oval=new RectF(); //RectF对象
for (int i=0; i
二、柱状图
柱状图就是绘制矩形和xy轴,难点是沿着y轴绘制y轴坐标名称,解决的办法是沿折线绘制文字。
1、数据初始化
/*获取最大数值*/
for (float value : values) {
if(value >= max){
max = value;
}
}
/*画布宽高*/
width = getWidth();
height = getHeight();
/*每个柱子间的间隙*/
spacing = (width-2*marginLeft)*0.3f/(values.length+1);
/*柱子的宽度*/
bgWidth = (width-2*marginLeft)*0.7f/(values.length);
/*柱子的最高高度*/
maxHeight = height-5*marginBottom;
/*y轴距左边缘的偏移值*/
leftOffset = (unit!=""&&Yname!="") ? DensityUtil.dip2px(getContext(),10):0;
2、绘制xy轴与y轴坐标名称
/*绘制xy轴*/
path = new Path();
paint = new Paint();
textPaint = new Paint();
textPaint.setTextSize(textSize);
textPaint.setTextAlign(Paint.Align.CENTER);
paint.setStyle(Paint.Style.STROKE);
path.moveTo(marginLeft+leftOffset,marginBottom);
path.rLineTo(0,height-3*marginBottom);
canvas.drawPath(path,paint);
/*绘制y轴坐标名称*/
if(unit!=""&&Yname!=null){
canvas.drawTextOnPath(Yname+"/"+unit,path,-(height-10*marginBottom)/2,textSize*3/2,textPaint);
}
path.rLineTo(width-2*marginLeft,0);
canvas.drawPath(path,paint);
3、绘制柱子和数据
/*绘制柱子和文字*/
startXposition = marginLeft+spacing+leftOffset;
startYposition = marginBottom+height-3*marginBottom;
paint.setStyle(Paint.Style.FILL);
paint.setColor(ChartColor.VIOLETRED);
/*柱子的左上角与右下角*/
float left = 0;
float top = 0;
float right = 0;
float bottom = 0;
int i = 0;
for (float value : values) {
left = startXposition;
top = startYposition - value/max * maxHeight;
right = startXposition + bgWidth;
bottom = startYposition;
canvas.drawRect(left,top,right,bottom,paint);
canvas.drawText(String.valueOf(value),startXposition+bgWidth/2,top-marginBottom/2,textPaint);
canvas.drawText(datas[i],startXposition+bgWidth/2,startYposition+marginBottom*3/2,textPaint);
startXposition = startXposition + spacing + bgWidth;
i++;
}
三、使用
1、添加依赖
2.饼图
在xml里添加布局
添加数据与数据名称
float[] values = new float[]{5,2,7,25,40,20,30,10,10,4,10,4};
String[] datas = new String[]{"语文","数学","英语","文综","理综","数学","英语","文综","理综","理综","文综","理综"};
pcView.setValues(values);
pcView.setDatas(datas);
设置文字与数值字体大小,默认为10dp
pcView.setPercentSize(10f);
pcView.setTextSize(10f);
3、柱状图
在xml里添加布局
添加数据与数据名称
float[] values = new float[]{5,2,7,25,40,20,30,10,10,4,10,4};
String[] datas = new String[]{"语文","数学","英语","文综","理综","数学","英语","文综","理综","理综","文综","理综"};
bgView.setValues(values);
bgView.setData(datas);
添加y轴坐标单位与名称
bgView.setYaxis("分","分数");
设置柱状图颜色
bgView.setChartColor(ChartColor.ORANGEYELLOW);
END
github地址:https://github.com/Mils-liu/MyChart
HenCoder教程地址:https://hencoder.com/activity-mock-2/