自定义View绘制雷达图

来源:互联网 发布:java毕业论文任务书 编辑:程序博客网 时间:2024/04/29 21:38
就直接上代码啦,注释都写的很详细了的
package com.mvp.viewdemo;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.util.AttributeSet;import android.view.View;/** * <h3>Description</h3> * <p> * 雷达图 * <p> * <h3>Author</h3> cgc * <h3>Date</h3> 2016/11/17 13:53 * <h3>Copyright</h3> Copyright (c)2016 Shenzhen JJshome Technology Co., Ltd. Inc. All rights reserved. */public class RadarView extends View {    public RadarView(Context context) {        this(context, null);    }    public RadarView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public RadarView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    /** 绘制连线画笔 */    private Paint mLienPaint;    /** 绘制数据点画笔 */    private Paint mDataPaint;    /** 绘制文本画笔 */    private Paint mTextPaint;    /** 中心点 x */    private int centreX;    /** 中心点y */    private int centreY;    /** 半径 */    private float radius = 0;    /** 数据点半径 */    private float dataRadius = 10;    /** 数据区透明值 最大255 不透明 */    private int dataAlpha = 127;    /** 字体大小 */    private int textSize = 38;    /** 连线颜色 */    private int lienColor = Color.GRAY;    /** 数据点颜色 */    private int dataColor = Color.GREEN;    /** 数据区颜色 */    private int dataAreaColor = Color.YELLOW;    /** 数据点之间的连线颜色 */    private int dataPointLienColor = Color.RED;    /** 文本颜色 */    private int textColor = Color.BLACK;    /** 雷达图占界面的比例 默认0.8 */    private float occupyRatio = 0.8f;    /** 根据数据设置纬度 */    private boolean isValuesToCount = false;    /** 纬度数 */    private int count = 8;    /** 计算角度 */    private float angle = (float) (Math.PI * 2 / count);    /** 最大值 */    private int maxValue = 100;    /** 数值 */    private double[] values = null;    private void init() {        //初始化绘制连接的画笔        mLienPaint = new Paint();        mLienPaint.setAntiAlias(true);        mLienPaint.setStyle(Paint.Style.STROKE);        mLienPaint.setColor(lienColor);        //初始化绘制数据的画笔        mDataPaint = new Paint();        mDataPaint.setAntiAlias(true);        mDataPaint.setStyle(Paint.Style.STROKE);        mDataPaint.setColor(dataColor);        //初始化绘制文字的画笔        mTextPaint = new Paint();        mTextPaint.setAntiAlias(true);        mTextPaint.setStyle(Paint.Style.STROKE);        mTextPaint.setColor(textColor);        mTextPaint.setTextSize(textSize);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        radius = Math.min(w, h) / 2 * occupyRatio;        centreX = w / 2;        centreY = h / 2;//        postInvalidate();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        drawLien(canvas);        drawToLien(canvas);        drawText(canvas);        if (values != null && values.length > 0) {            drawValue(canvas);        }    }    /**     * 绘制数据区     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,16:40     * <h3>UpdateTime</h3> 2016/11/17,16:40     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param canvas     */    private void drawValue(Canvas canvas) {        Path path = new Path();        for (int i = 0; i < count; i++) {            //计算数据值所占的比例            double percent = values[i] / maxValue;            //计算坐标            float x = (float) (centreX + radius * Math.cos(angle * i) * percent);            float y = (float) (centreY + radius * Math.sin(angle * i) * percent);            if (i == 0) {//设置起点                path.moveTo(x, centreY);            } else {                //记录数据点                if (values[i] != 0) {                    path.lineTo(x, y);                }            }            //绘制数据点            if (values[i] != 0) {                mDataPaint.setStyle(Paint.Style.FILL);                mDataPaint.setColor(dataColor);                canvas.drawCircle(x, y, dataRadius, mDataPaint);            }        }        //闭合路径,连接数据点        path.close();        mDataPaint.setColor(dataPointLienColor);        mDataPaint.setStyle(Paint.Style.STROKE);        canvas.drawPath(path, mDataPaint);        //绘制数据点之间区域的面积        mDataPaint.setColor(dataAreaColor);        mDataPaint.setAlpha(dataAlpha);        mDataPaint.setStyle(Paint.Style.FILL_AND_STROKE);        canvas.drawPath(path, mDataPaint);    }    /**     * 数据点的半径     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,16:56     * <h3>UpdateTime</h3> 2016/11/17,16:56     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param dataRadius     */    public void setDataRadius(float dataRadius) {        this.dataRadius = dataRadius;    }    /**     * 数据区域的透明值     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,16:56     * <h3>UpdateTime</h3> 2016/11/17,16:56     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param dataAlpha 1-255 1为全透明,255未透明     */    public void setDataAlpha(int dataAlpha) {        this.dataAlpha = dataAlpha;    }    /**     * 设置字体大小     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:32     * <h3>UpdateTime</h3> 2016/11/17,17:32     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param textSize     */    public void setTextSize(int textSize) {        this.textSize = textSize;    }    /**     * 设置雷达图连接颜色     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:33     * <h3>UpdateTime</h3> 2016/11/17,17:33     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param lienColor     */    public void setLienColor(int lienColor) {        mLienPaint.setColor(lienColor);    }    /**     * 设置数据点颜色     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:33     * <h3>UpdateTime</h3> 2016/11/17,17:33     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param dataColor     */    public void setDataColor(int dataColor) {        this.dataColor = dataColor;    }    /**     * 设置数据区颜色     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:34     * <h3>UpdateTime</h3> 2016/11/17,17:34     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param dataAreaColor     */    public void setDataAreaColor(int dataAreaColor) {        this.dataAreaColor = dataAreaColor;    }    /**     * 设置数据点颜色     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:34     * <h3>UpdateTime</h3> 2016/11/17,17:34     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param dataPointLienColor     */    public void setDataPointLienColor(int dataPointLienColor) {        this.dataPointLienColor = dataPointLienColor;    }    /**     * 设置字体颜色     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:34     * <h3>UpdateTime</h3> 2016/11/17,17:34     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param textColor     */    public void setTextColor(int textColor) {        this.textColor = textColor;    }    /**     * 雷达图占界面的比例 默认0.8     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:34     * <h3>UpdateTime</h3> 2016/11/17,17:34     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param occupyRatio     */    public void setOccupyRatio(float occupyRatio) {        this.occupyRatio = occupyRatio;    }    /**     * 设置纬度值     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:35     * <h3>UpdateTime</h3> 2016/11/17,17:35     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param count     */    public void setCount(int count) {        if (!isValuesToCount) {            this.count = count;        }    }    /**     * 设置最大值     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:35     * <h3>UpdateTime</h3> 2016/11/17,17:35     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param maxValue     */    public void setMaxValue(int maxValue) {        this.maxValue = maxValue;    }    /**     * 数值     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:35     * <h3>UpdateTime</h3> 2016/11/17,17:35     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param values     */    public void setValues(double[] values) {        this.values = values;        this.count = values.length;    }    /**     * 是否根据数值设置纬度     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:39     * <h3>UpdateTime</h3> 2016/11/17,17:39     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param values          数据值     * @param isValuesToCount 是否根据数据值数量设置纬度数 true(如果是true setCount 设置纬度将失效) false 不是     */    public void setValues(double[] values, boolean isValuesToCount) {        this.values = values;        if (isValuesToCount) {            this.count = values.length;        }        this.isValuesToCount = isValuesToCount;    }    /**     * 绘制雷达图     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,17:36     * <h3>UpdateTime</h3> 2016/11/17,17:36     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     */    public void startInvalidate() {        angle = (float) (Math.PI * 2 / count);        invalidate();    }    /**     * 绘制文本     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,16:42     * <h3>UpdateTime</h3> 2016/11/17,16:42     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param canvas     */    private void drawText(Canvas canvas) {        //获取画笔的适量        Paint.FontMetrics fm = mTextPaint.getFontMetrics();        //计算文本的高度        float fontHeight = fm.descent - fm.ascent;        for (int i = 0; i < count; i++) {            //计算坐标            float x = (float) (centreX + (radius + fontHeight / 2) * Math.cos(angle * i));            float y = (float) (centreY + (radius + fontHeight / 2) * Math.sin(angle * i));            if (i == 0) {//绘制第一项                canvas.drawText(i + "", x, y + (fontHeight / 2) / 2, mTextPaint);            } else if (i == 3) {//绘制第三项                canvas.drawText(i + "", x - 20, y + (fontHeight / 2) / 2, mTextPaint);            } else if (i == 2 || i == 1) {//绘制第二,一项                canvas.drawText(i + "", x, y + (fontHeight / 2), mTextPaint);            } else {                canvas.drawText(i + "", x, y, mTextPaint);            }        }    }    /**     * 绘制雷达图的层次     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,16:44     * <h3>UpdateTime</h3> 2016/11/17,16:44     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param canvas     */    private void drawLien(Canvas canvas) {        //层次之间的距离        float r = radius / (count - 1);        //绘制路径        Path path = new Path();        for (int i = 1; i < count; i++) {            //层次的半径            float newRadius = r * i;            path.reset();            for (int j = 0; j < count; j++) {                if (j == 0) {//绘制起点                    path.moveTo(centreX + newRadius, centreY);                } else {                    //计算角度的坐标                    float x = (float) (centreX + newRadius * Math.cos(angle * j));                    float y = (float) (centreY + newRadius * Math.sin(angle * j));                    //进行连线                    path.lineTo(x, y);                }            }            //闭合路径            path.close();            canvas.drawPath(path, mLienPaint);        }    }    /**     * 绘制中心点到纬度点的连接     * <p>     * <h3>Version</h3> 1.0     * <h3>CreateTime</h3> 2016/11/17,16:44     * <h3>UpdateTime</h3> 2016/11/17,16:44     * <h3>CreateAuthor</h3> cgc     * <h3>UpdateAuthor</h3> cgc     * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.)     *     * @param canvas     */    private void drawToLien(Canvas canvas) {        Path path = new Path();        for (int i = 0; i < count; i++) {            path.reset();            path.moveTo(centreX, centreY);            float x = (float) (centreX + radius * Math.cos(angle * i));            float y = (float) (centreY + radius * Math.sin(angle * i));            path.lineTo(x, y);            path.close();            canvas.drawPath(path, mLienPaint);        }    }}

0 0
原创粉丝点击