雷达图demo啦!各位水友支持一下啦。。。

  1 import java.util.ArrayList;
  2 import java.util.List;
  3 
  4 import android.content.Context;
  5 import android.graphics.Canvas;
  6 import android.graphics.Paint;
  7 import android.graphics.Path;
  8 import android.graphics.Point;
  9 import android.graphics.RectF;
 10 import android.graphics.Paint.Style;
 11 import android.util.AttributeSet;
 12 import android.util.Log;
 13 import android.view.View;
 14 
 15 /**
 16 Integer[] arr = {150, 80, 70, 120, 133, 110, 99, 88, 66} ;
 17 int colorArr = 0xFFFF0000 ;
 18 Integer[] arr1 = {40, 45, 100, 32, 55, 44, 33, 44, 80} ;
 19 int colorArr1 = 0xFF00FF00 ;
 20 
 21 String[] introStr = {"仅仅", "仅仅", "仅仅", "仅仅", "仅仅", "仅仅", "仅仅", "仅仅", "仅仅"} ;
 22 
 23 radarImage = (RadarImage) v.findViewById(R.id.radarImage1) ;
 24 radarImage.setBlock(9) ;
 25 radarImage.setIntroStr(introStr) ;
 26 radarImage.setSize(300) ;
 27 radarImage.setNumList(arr, colorArr) ;
 28 radarImage.setNumList(arr1, colorArr1) ;
 29 radarImage.invalidate() ;
 30 */
 31 public class RadarImage extends View {
 32     
 33     public RadarImage(Context context, AttributeSet attrs) {
 34         super(context, attrs);
 35         // TODO Auto-generated constructor stub
 36     }
 37 
 38     
 39     private int imageWidth = 480 ; // 图像总宽高
 40     private int extraWidth ; // 雷达图外边框说明文字占的空间大小,总图像的1/6,initData()中实例化
 41     private int radarWidth ; // 雷达图,图的宽高
 42     private int centerX ; // 图形中点X坐标
 43     private int centerY ; // 图像中点Y坐标
 44     
 45     private int block ; // 多少条边
 46     private float blockAngle ; // 角度大小
 47     
 48     private String[] introStr ; // 边的说明文字
 49     
 50     private List<Integer[]> dataList = new ArrayList<Integer[]>() ;
 51     private List<Integer> colorList = new ArrayList<Integer>() ;
 52     
 53     /**
 54      * 假如发现有小于0的,直接画出“数据错误”
 55      * 假如发现有大于雷达图总大小的数据,(用数据的值与雷达图的1/2宽度比,)
 56      * 将数据进行转换,最大值是雷达图的总大小
 57      */
 58     private boolean dataError = false ;
 59 
 60     @Override
 61     protected void onDraw(Canvas canvas) {
 62 //        super.onDraw(canvas);
 63         
 64         /**
 65          * 初始化数据
 66          */
 67         initData() ;
 68         
 69         /**
 70          * 假如数据错误为true
 71          * 直接return
 72          */
 73         if(dataError) return ;
 74         
 75         /**
 76          * 先画背景
 77          */
 78         drawBg(canvas) ;
 79         
 80         /**
 81          * 画数据
 82          */
 83         drawData(canvas);
 84     }
 85     
 86     /**
 87      * 初始化数据
 88      */
 89     private void initData() {
 90         extraWidth = imageWidth / 12 ;
 91         radarWidth = imageWidth / 2 - extraWidth ;
 92         blockAngle = (float) (360.0 / block) ;
 93         centerX = imageWidth / 2 ;
 94         centerY = imageWidth / 2 ;
 95         
 96         Log.e(String.valueOf("centerX,centerY"), String.valueOf(centerX) + "," + String.valueOf(centerY)) ;
 97         
 98         int max ; // 一组数据的最大值
 99         float ratio ; // 比值 ;
100         int tempData ; // 
101         out:
102         for (int j = 0; j < dataList.size(); j++) {
103             max = 0 ;
104             ratio = 0 ;
105             in:
106             for (int i = 0; i < dataList.get(j).length; i++) {
107                 // 发现小于0的数据,直接break
108                 if(dataList.get(j)[i] < 0) {
109                     dataError = true ;
110                     break out ;
111                 }
112                 // 找出一组数的最大的一个
113                 if(max < dataList.get(j)[i]) {
114                     max = dataList.get(j)[i] ;
115                 }
116             }
117             ratio = (float) radarWidth / (float) max ;
118             for (int i = 0; i < dataList.get(j).length; i++) {
119                 tempData = dataList.get(j)[i] ;
120                 dataList.get(j)[i] = (int) (tempData * ratio) ;
121             }
122         }
123     }
124     
125     /**
126      * 画数据
127      * @param canvas
128      */
129     private void drawData(Canvas canvas) {
130         RectF rectAngle ; // 小正方形的位置
131         
132         for (int j = 0; j < dataList.size(); j++) {
133             
134             Paint dataPaint = new Paint() ; // 数据paint
135             dataPaint.setColor(colorList.get(j)) ; // 数据color
136             dataPaint.setAntiAlias(true) ; // 无锯齿
137             
138             Path bgPath = new Path() ; // 数据路径
139             
140             List<Point> datapl = getPointList(dataList.get(j), blockAngle, centerX, centerY) ;
141             
142             int bggX ; // 当前点X坐标
143             int bggY ; // 当前点Y坐标
144             for (int i = 0; i < datapl.size(); i++) {
145                 bggX = datapl.get(i).x ;
146                 bggY = datapl.get(i).y ;
147                 if(i == 0) {
148                     bgPath.moveTo(bggX, bggY) ;
149                 }else {
150                     bgPath.lineTo(bggX, bggY) ;
151                 }
152                 // 画小正方形
153                 rectAngle = new RectF(bggX-3, bggY-3, bggX+3, bggY+3) ;
154                 canvas.drawRect(rectAngle, dataPaint) ;
155             }
156             bgPath.close() ;
157             dataPaint.setStyle(Style.STROKE) ; // 设置空心
158             // 画路径
159             canvas.drawPath(bgPath, dataPaint) ;
160         }
161     }
162     
163     
164     
165     /**
166      * 画雷达图背景
167      */
168     private void drawBg(Canvas canvas) {
169         Integer[] bgArr = new Integer[block] ;
170         for (int i = 0; i < bgArr.length; i++) {
171             bgArr[i] = radarWidth ;
172         }
173         List<Point> bgPl = getPointList(bgArr, blockAngle, centerX, centerY) ;
174         
175         RectF rectAngle ; // 小正方形的位置
176         Path bgPath = new Path() ; // 背景path
177         Paint bgPaint = new Paint() ; // 画背景paint
178         
179         bgPaint.setColor(0xCCCCCCCC) ; // 背景颜色
180         bgPaint.setAntiAlias(true) ; // 没有锯齿
181         
182         int bggX ; // 当前点X坐标
183         int bggY ; // 当前点Y坐标
184         for (int i = 0; i < bgPl.size(); i++) {
185             bggX = bgPl.get(i).x ;
186             bggY = bgPl.get(i).y ;
187             if(i == 0) {
188                 bgPath.moveTo(bggX, bggY) ;
189             }else {
190                 bgPath.lineTo(bggX, bggY) ;
191             }
192             // 设置小正方形绝对坐标
193             rectAngle = new RectF(bggX-2, bggY-2, bggX+2, bggY+2) ;
194             // 画小正方形
195             canvas.drawRect(rectAngle, bgPaint) ;
196             // 当前点到图像中心画线
197             canvas.drawLine(bggX, bggY, centerX, centerY, bgPaint) ;
198             
199             if(blockAngle*i < 90) {
200                 canvas.drawText(introStr[i], bggX+10, bggY + 10, bgPaint) ;
201             }else if(blockAngle*i >= 90 && blockAngle*i < 180) {
202                 canvas.drawText(introStr[i], bggX-40, bggY + 20, bgPaint) ;
203             }else if(blockAngle*i >= 180 && blockAngle*i < 270) {
204                 canvas.drawText(introStr[i], bggX-40, bggY - 10, bgPaint) ;
205             }else if(blockAngle*i >= 270) {
206                 canvas.drawText(introStr[i], bggX+10, bggY - 10, bgPaint) ;
207             }
208         }
209         bgPath.close() ; // 关闭路径
210         bgPaint.setStyle(Style.STROKE) ; // 设置背景空心
211         canvas.drawPath(bgPath, bgPaint) ; // 画路径
212     }
213     
214     /**
215      * 获取各个点在图的绝对坐标
216      * @param arr1 点长度数组
217      * @param blockAngle 角的大小
218      * @param centerX 雷达图中心点X坐标
219      * @param centerY 雷达图中心点Y坐标
220      * @return ist<Point> 点的绝对坐标List
221      */
222     private List<Point> getPointList(Integer[] arr1, float blockAngle, int centerX, int centerY) {
223         List<Point> tempPointList = new ArrayList<Point>() ;
224         
225         float curAngle ; // 当前计算角度
226         float tanRatio ; // tan比值
227         float sinRatio ; // sin比值
228         float tanX ; // 当前相对X坐标
229         float tanY ; // 当前相对Y坐标
230         float absoX = 0 ; // 当前点X绝对坐标
231         float absoY = 0 ; // 当前点Y绝对坐标
232         Point tempPoint ; //
233         
234         for (int i = 0; i < arr1.length; i++) {
235             curAngle = i * blockAngle ;
236             
237             if(curAngle == 0) {
238                 absoX = centerX + arr1[i] ;
239                 absoY = centerY ;
240             }else if(curAngle == 90) {
241                 absoX = centerX ;
242                 absoY = centerY + arr1[i] ;
243             }else if(curAngle == 180) {
244                 absoX = centerX - arr1[i] ;
245                 absoY = centerY ;
246             }else if(curAngle == 270) {
247                 absoX = centerX ;
248                 absoY = centerY - arr1[i] ;
249             }else {
250                 if(curAngle > 0 && curAngle < 90) {
251                     tanRatio = (float) Math.tan(Math.PI / (180.0 / curAngle)) ;
252                     sinRatio = (float) Math.sin(Math.PI / (180.0 / curAngle)) ;
253                     tanY = sinRatio * arr1[i] ;
254                     tanX = tanY / tanRatio ;
255                     
256                     absoX = centerX + tanX ;
257                     absoY = centerY + tanY ;
258                 }else if(curAngle > 90 && curAngle < 180) {
259                     curAngle = 180 - curAngle ;
260                     tanRatio = (float) Math.tan(Math.PI / (180.0 / curAngle)) ;
261                     sinRatio = (float) Math.sin(Math.PI / (180.0 / curAngle)) ;
262                     tanY = sinRatio * arr1[i] ;
263                     tanX = tanY / tanRatio ;
264                     
265                     absoX = centerX - tanX ;
266                     absoY = centerY + tanY ;
267                 }else if(curAngle > 180 && curAngle < 270) {
268                     curAngle = curAngle - 180 ;
269                     tanRatio = (float) Math.tan(Math.PI / (180.0 / curAngle)) ;
270                     sinRatio = (float) Math.sin(Math.PI / (180.0 / curAngle)) ;
271                     tanY = sinRatio * arr1[i] ;
272                     tanX = tanY / tanRatio ;
273                     
274                     absoX = centerX - tanX ;
275                     absoY = centerY - tanY ;
276                 }else if(curAngle > 270 && curAngle < 360) {
277                     curAngle = 360 - curAngle ;
278                     tanRatio = (float) Math.tan(Math.PI / (180.0 / curAngle)) ;
279                     sinRatio = (float) Math.sin(Math.PI / (180.0 / curAngle)) ;
280                     tanY = sinRatio * arr1[i] ;
281                     tanX = tanY / tanRatio ;
282                     
283                     absoX = centerX + tanX ;
284                     absoY = centerY - tanY ;
285                 }
286             }
287             tempPoint = new Point((int)absoX, (int)absoY) ;
288             tempPointList.add(tempPoint) ;
289             
290         }
291         
292         return tempPointList ;
293     }
294     
295 
296     /**
297      * 设置要画图的数据
298      * @param numList
299      * @param color
300      */
301     public void setNumList(Integer[] numList, Integer color) {
302         this.dataList.add(numList);
303         this.colorList.add(color) ;
304     }
305     
306     /**
307      * 设置雷达图的大小
308      * @param imageWidth
309      */
310     public void setSize(int imageWidth) {
311         this.imageWidth = imageWidth ;
312     }
313 
314     /**
315      * 设置有多少块
316      * @param block
317      */
318     public void setBlock(int block) {
319         this.block = block;
320     }
321 
322     /**
323      * 设置每条边的说明文字
324      * @param introStr
325      */
326     public void setIntroStr(String[] introStr) {
327         this.introStr = introStr;
328     }
329     
330     
331     
332     
333 
334 }

 

水友记住啦!我是精灵July哇,分享所有的成果哇。。。。。。(*^__^*) 洗洗……

 

 

posted on 2013-03-26 11:06  精灵July  阅读(1431)  评论(3编辑  收藏  举报

导航