zoukankan      html  css  js  c++  java
  • 雷达图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哇,分享所有的成果哇。。。。。。(*^__^*) 洗洗……

  • 相关阅读:
    车牌定位与畸变校正(python3.7,opencv4.0)
    TensorFlow 2.0 Alpha/Beta pip安装指令
    pandas 获取数据帧DataFrame的行、列数
    pandas 对数据帧DataFrame中数据的增删、补全及转换操作
    pandas 对数据帧DataFrame中数据的索引及切片操作
    Exception: Exception caught in workbook destructor. Explicit close() may be required for workbook. 错误解决办法
    pandas对Excel文件的读写操作
    第一个WPF程序(串口调试)
    [C#]AdvPropertyGrid的使用示例(第三方控件:DevComponents.DotNetBar2.dll)
    C# 获得本地通用网卡信息
  • 原文地址:https://www.cnblogs.com/jinglingJuly/p/2982111.html
Copyright © 2011-2022 走看看