Andriod雷达图简单实现

 最近又被毕设指导老师鄙视了一番,说我的方法不适用,表示毕设求过。

实习也快结束了,也没做出什么东西来,感觉很不好大哭

雷达图效果图


代码:

package com.fr.chart.render;

import android.content.Context;
import android.graphics.*;
import android.view.MotionEvent;
import android.view.View;
import com.fr.tools.MathTools;
import org.json.JSONObject;

/**
 * User: randost
 * Date: 2014/4/23
 * 雷达图
 */
public class RadarView extends View{
    private int count = 6;                //数据个数
    private float angle = 360/count;
    private int point_radius = 5;         //数据点的半径
    private int regionwidth = 30;         //点击选取区域大小
    private int valueRulingCount = 5;     //等分值线个数
    private int radius;                   //网格最大半径
    private int centerX;                  //中心X
    private int centerY;                  //中心Y
    private String[] titles = {"a","b","c","d","e","f"};

    private Point[] pts;                    //维度端点
    private Region[] regions;               //打分点区域
    private float[] regionValues;           //打分点分数
    private Path valuePath;
    private double[] data = {8,6,6,6,4,5}; //各维度分值
    private float maxValue = 100;             //数据最大值
    private Point[] value_pts;              //维度端点
    private Paint mainPaint;                //雷达区画笔
    private Paint valuePaint;               //数据区画笔
    private Paint textPaint;                //文本画笔    

    //构造函数
    public RadarView(Context context, org.mozilla.javascript.Context jsCx, JSONObject options) {
        super(context);
    }

    public RadarView(Context context, double[] data, String[] titles) {
        super(context);
        setData(data);
        setTitles(titles);
        init();
    }

    //初始化
    private void init() {
        if (data.length == titles.length) {
            count = data.length;
        }
        maxValue = (float) MathTools.roundUp(MathTools.max(data));

        mainPaint = new Paint();
        mainPaint.setAntiAlias(true);
        mainPaint.setColor(Color.GRAY);
        mainPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        valuePaint = new Paint();
        valuePaint.setAntiAlias(true);
        valuePaint.setColor(Color.BLUE);
        valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);

        textPaint = new Paint();
        textPaint.setTextSize(20);
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setColor(Color.BLACK);


        pts = new Point[count];
        value_pts = new Point[count];
        valuePath = new Path();
        for(int i=0; i<count; i++) {
            pts[i] = new Point();
            value_pts[i] = new Point();
        }
        regionValues = new float[count*valueRulingCount*2];
        regions = new Region[count*valueRulingCount*2];
        for(int i=0; i<regions.length; i++) {
            regions[i] = new Region();
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        radius = Math.min(h, w)/2 - 50;
        centerX = w/2;
        centerY = h/2;

        for(int i=0; i<count; i++)
        {
            pts[i].x = centerX+(int)(radius*Math.cos(Math.toRadians(angle*i)));
            pts[i].y = centerY-(int)(radius*Math.sin(Math.toRadians(angle*i)));           //逆时针-

            for(int j=1; j<=valueRulingCount*2; j++)
            {
                int x = centerX + (pts[i].x-centerX)/(valueRulingCount*2)*j;
                int y = centerY + (pts[i].y-centerY)/(valueRulingCount*2)*j;
                regions[i*valueRulingCount*2+j-1].set(x-regionwidth/2, y-regionwidth/2, x+regionwidth/2, y+regionwidth/2);
                regionValues[i*valueRulingCount*2+j-1] = j * maxValue / valueRulingCount / 2;
            }
        }
        postInvalidate();
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        float x = event.getX();
        float y = event.getY();

        switch(action)
        {
            case MotionEvent.ACTION_DOWN:
                for(int i = 0; i<regions.length; i++)
                {
                    if (regions[i].contains((int)x, (int)y))
                    {
                        data[(i/(valueRulingCount*2))] = regionValues[i];
                        break;
                    }
                }
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:

                break;
            case MotionEvent.ACTION_UP:

                break;
        }
        return super.onTouchEvent(event);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.WHITE);

        //绘制雷达网格

        for(int i=0; i<count; i++)
        {
            int end = i+1 == count? 0:i+1;

            for(int j=1; j<=valueRulingCount; j++)
            {
                canvas.drawLine(centerX+(pts[i].x-centerX)*j/valueRulingCount, centerY+(pts[i].y-centerY)*j/valueRulingCount,
                        centerX+(pts[end].x-centerX)*j/valueRulingCount, centerY+(pts[end].y-centerY)*j/valueRulingCount, mainPaint);
            }
            canvas.drawLine(centerX, centerY, pts[i].x, pts[i].y, mainPaint);
        }

        //绘制四周文本
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float fontHeight = fontMetrics.ascent;
        for(int i=0; i<count; i++)
        {
            if ((angle * i == 90.0) || (angle * i == 270.0))
                textPaint.setTextAlign(Paint.Align.CENTER);
            else if ((angle * i < 90) || (angle * i > 270))
                textPaint.setTextAlign(Paint.Align.LEFT);
            else if ((angle * i > 90) || (angle * i < 270))
                textPaint.setTextAlign(Paint.Align.RIGHT);

            if (angle * i > 225 && angle * i < 315)
                canvas.drawText(titles[i], pts[i].x, pts[i].y-fontHeight, textPaint);
            else
                canvas.drawText(titles[i], pts[i].x, pts[i].y, textPaint);
        }

        for(int i=0; i<count; i++)
        {
            value_pts[i].x = (int)(centerX + (pts[i].x-centerX) * data[i]/maxValue);
            value_pts[i].y = (int)(centerY + (pts[i].y-centerY) * data[i]/maxValue);
        }

        //绘制数据图
        valuePath.reset();
        for(int i = 0; i< pts.length; i++)
        {
            if (i == 0)
                valuePath.moveTo(value_pts[i].x, value_pts[i].y);
            else
                valuePath.lineTo(value_pts[i].x, value_pts[i].y);
            canvas.drawCircle(value_pts[i].x, value_pts[i].y, point_radius, valuePaint);
        }
        valuePaint.setAlpha(150);
        canvas.drawPath(valuePath, valuePaint);
    }

    public void setTitles(String[] titles) {
        this.titles = titles;
    }

    public void setData(double[] data) {
        this.data = data;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值