/** * 雷达view * @version 1.0 * @author DEV-81 */ public class RadarView extends View{ private int centerX; //中心X private int centerY; //中心Y private float radius; //网格最大半径 private Paint mainPaint; //雷达区画笔 private Paint textPaint; //文本画笔 private Paint valuePaint; //数据区画笔 private int count = 6; //数据个数 private float angle = (float) (Math.PI*2/count); private String[] titles = {"a","b","c","d","e","f"}; private double[] data = {100,60,60,60,100,50,10,20}; //各维度分值 private float maxValue = 100; //数据最大值 public RadarView(Context context) { this(context,null); } public RadarView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } /** * 初始化画笔 * */ private void init() { mainPaint=new Paint(); mainPaint.setColor(Color.BLACK); mainPaint.setAntiAlias(true); mainPaint.setStrokeWidth(1); mainPaint.setStyle(Paint.Style.STROKE); textPaint=new Paint(); textPaint.setColor(Color.RED); textPaint.setAntiAlias(true); textPaint.setTextSize(32); textPaint.setStyle(Paint.Style.STROKE); valuePaint=new Paint(); // 覆盖区域,只要使用path记录下坐标点,然后设 valuePaint.setStyle(Paint.Style.FILL_AND_STROKE); valuePaint.setColor(Color.BLUE); valuePaint.setAntiAlias(true); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { centerX=w/2; centerY=h/2; radius = Math.min(h, w)/2*0.8f; Log.d("===onSizeChanged======",Thread.currentThread().getName()); //一旦size发生改变,重新绘制(onDraw) // postInvalidate(); //工作在子线程 invalidate(); // 工作在ui线程 super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawPolygon(canvas); drawLines(canvas); drawText(canvas); drawRegion(canvas); } /** * 绘制正多边形 */ 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); } } /** * 绘制直线 * 绘制从中心到末端的直线 * 同样根据半径,计算出每个末端坐标 */ 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); } } /** * 绘制文字 * @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); } } } /** * 绘制区域 * @param canvas *使path包围区域被填充 * */ 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); } }
android自定义雷达图
猜你喜欢
转载自blog.csdn.net/oneblue123/article/details/80745552
今日推荐
周排行