Android雷達圖(蜘蛛網圖)繪制
簡介
最近因為項目需求,要實現一款雷達圖來表示用戶的各種成就值
雷達圖的繪制很簡單,只要思路清晰按部就班的繪制就可以了,其中使用得最多,是路徑path類的使用,使用這個類可以讓我們更加方便地繪制出正多邊形等效果。
效果圖如下:

使用方式
使用方式很簡單,只要在布局文件里面,直接使用這個控件就好了,記得給它設置一個合適的具體的大小。
另外可以控制繪制的是多少邊形,通過提供的一些public方法,可以設置畫筆顏色等。
當然大家也可以按照自己的需求去修改啦。
//設置標題
public void setTitles(String[] titles) {
this.titles = titles;
}
//設置數值
public void setData(double[] data) {
this.data = data;
}
//設置最大數值
public void setMaxValue(float maxValue) {
this.maxValue = maxValue;
}
//設置蜘蛛網顏色
public void setMainPaintColor(int color){
mainPaint.setColor(color);
}
//設置標題顏色
public void setTextPaintColor(int color){
textPaint.setColor(color);
}
//設置覆蓋局域顏色
public void setValuePaintColor(int color){
valuePaint.setColor(color);
} 具體實現
1、獲得布局中心
我們在onSizeChanged(int w, int h, int oldw, int oldh)方法里面,根據View的長寬,獲取整個布局的中心坐標,因為整個雷達都是以整個中心開始繪制的。
public class RadarView extends View {
private int count = 6; //數據個數
private float angle = (float) (Math.PI*2/count);
private float radius; //網格最大半徑
private int centerX; //中心X
private int centerY; //中心Y
private String[] titles = {"a","b","c","d","e","f"};
private double[] data = {100,60,60,60,100,50,10,20}; //各維度分值
private float maxValue = 100; //數據最大值
private Paint mainPaint; //雷達區畫筆
private Paint valuePaint; //數據區畫筆
private Paint textPaint; //文本畫筆
...
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
radius = Math.min(h, w)/2*0.9f;
//中心坐標
centerX = w/2;
centerY = h/2;
postInvalidate();
super.onSizeChanged(w, h, oldw, oldh);
}
...
} 2、繪制蜘蛛網絡
/**
* 繪制正多邊形
*/
private void drawPolygon(Canvas canvas){
Path path = new Path();
float r = radius/(count-1);//r是蜘蛛絲之間的間距
for(int i=1;i<count;i++){//中心點不用繪制
float curR = r*i;//當前半徑
path.reset();
for(int j=0;j<count;j++){
if(j==0){
path.moveTo(centerX+curR,centerY);
}else{
//根據半徑,計算出蜘蛛絲上每個點的坐標
float x = (float) (centerX+curR*Math.cos(angle*j));
float y = (float) (centerY+curR*Math.sin(angle*j));
path.lineTo(x,y);
}
}
path.close();//閉合路徑
canvas.drawPath(path, mainPaint);
}
} 
3、繪制從中心到末端的直線
同樣根據半徑,計算出每個末端坐標
/**
* 繪制直線
*/
private void drawLines(Canvas canvas){
Path path = new Path();
for(int i=0;i<count;i++){
path.reset();
path.moveTo(centerX, centerY);
float x = (float) (centerX+radius*Math.cos(angle*i));
float y = (float) (centerY+radius*Math.sin(angle*i));
path.lineTo(x, y);
canvas.drawPath(path, mainPaint);
}
} 
4、繪制文本
對于文本的繪制,首先要找到末端的坐標,由于末端和文本有一定距離,給每個末端加上這個距離以后,再繪制文本。
另外,當文本在左邊時,由于不希望文本和蜘蛛網交叉,我們可以先計算出文本的長度,然后使起始繪制坐標向左偏移這個長度。
/**
* 繪制文字
* @param canvas
*/
private void drawText(Canvas canvas){
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float fontHeight = fontMetrics.descent - fontMetrics.ascent;
for(int i=0;i<count;i++){
float x = (float) (centerX+(radius+fontHeight/2)*Math.cos(angle*i));
float y = (float) (centerY+(radius+fontHeight/2)*Math.sin(angle*i));
if(angle*i>=0&&angle*i<=Math.PI/2){//第4象限
canvas.drawText(titles[i], x,y,textPaint);
}else if(angle*i>=3*Math.PI/2&&angle*i<=Math.PI*2){//第3象限
canvas.drawText(titles[i], x,y,textPaint);
}else if(angle*i>Math.PI/2&&angle*i<=Math.PI){//第2象限
float dis = textPaint.measureText(titles[i]);//文本長度
canvas.drawText(titles[i], x-dis,y,textPaint);
}else if(angle*i>=Math.PI&&angle*i<3*Math.PI/2){//第1象限
float dis = textPaint.measureText(titles[i]);//文本長度
canvas.drawText(titles[i], x-dis,y,textPaint);
}
}
} 
5、繪制覆蓋區域
覆蓋區域,只要使用path記錄下坐標點,然后設
valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);
使path包圍區域被填充
/**
* 繪制區域
* @param canvas
*/
private void drawRegion(Canvas canvas){
Path path = new Path();
valuePaint.setAlpha(255);
for(int i=0;i<count;i++){
double percent = data[i]/maxValue;
float x = (float) (centerX+radius*Math.cos(angle*i)*percent);
float y = (float) (centerY+radius*Math.sin(angle*i)*percent);
if(i==0){
path.moveTo(x, centerY);
}else{
path.lineTo(x,y);
}
//繪制小圓點
canvas.drawCircle(x,y,10,valuePaint);
}
valuePaint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, valuePaint);
valuePaint.setAlpha(127);
//繪制填充區域
valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawPath(path, valuePaint);
} 
寫在最后
控件很簡單,有需要的朋友可以下載源碼直接使用或者修改
本篇文章主要是path類的使用
另外這個控件沒有做較好的屏幕適配,大家可以根據自己的需要修改
原文出處:http://blog.csdn.net/crazy__chen/article/details/50163693
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!