雷达图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哇,分享所有的成果哇。。。。。。(*^__^*) 洗洗……