最近做雷达图,根据网上的资料自己整理了一个。可以根据个人需求,自定义雷达的形状和多边形的边的数目,也可以空值雷达图的旋转。效果图如下:
完整代码如下:
`public class RadarView extends View {
/* 默认宽度为300x00/
private int WRAP_WIDTH;
private int WRAP_HEIGHT;
/* 绘制多边形的画笔 /
private Paint mPaintPolygon;
/* 绘制直线的画笔 /
private Paint mPaintLine;
/* 绘制分值区的画笔 /
private Paint mPaintRegion;
/**
* 雷达的边数
*/
private static final int NUM_OF_SIDES = 5;
/** 角度 */
private float mAngel = (float) (2 * Math.PI / NUM_OF_SIDES);
/** 多边形的绘制路径 */
private Path mPathPolygon;
/** 多边形的起始半径 */
private float mStartRadius;
/** 直线的绘制路径 */
private Path mPathLine;
/** 分值区的绘制路径 */
private Path mPathRegion;
/** 中心点 x 轴坐标*/
private int mCenterX;
/** 中心点 y 轴坐标 */
private int mCenterY;
/** 分值区*/
float[] percents = new float[3];
public RadarView(Context context) {
this(context, null);
}
public RadarView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
//1、获取Preferences
SharedPreferences width = context.getSharedPreferences("width", 0);
//2、取出数据
int w = width.getInt("width",370);
WRAP_WIDTH = w*3/5;
WRAP_HEIGHT = WRAP_WIDTH;
mStartRadius = WRAP_WIDTH/10;
Log.d("----", "init: " + w);
mPaintPolygon = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintPolygon.setStyle(Paint.Style.STROKE);
mPaintPolygon.setColor(Color.BLACK);
mPaintPolygon.setStrokeWidth(1F);
mPaintLine = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintLine.setStyle(Paint.Style.STROKE);
mPaintLine.setColor(Color.GRAY);
mPaintLine.setStrokeWidth(1F);
mPaintRegion = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintRegion.setStyle(Paint.Style.FILL_AND_STROKE);
mPaintRegion.setColor(Color.parseColor("#7f33b5e5"));
mPaintRegion.setStrokeWidth(1F);
mPathPolygon = new Path();
mPathLine = new Path();
mPathRegion = new Path();
}
@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh) {
mCenterX = w / 2;
mCenterY = h / 2;
}
@Override
protected void onDraw(Canvas canvas) {
/**调整图像偏转*/
canvas.rotate(30,mCenterX,mCenterY);
drawPolygon(canvas);
drawLine(canvas);
drawRegion(canvas);
}
/**
* 调整view的宽高
* */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(WRAP_WIDTH, WRAP_HEIGHT);
} else if (widthMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(WRAP_WIDTH, height);
} else if (heightMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(width, WRAP_HEIGHT);
}
}
/**
* 分值区的大小
* */
public void setRegionValue(float health,float protection,float nutrition) {
percents[0] = health;
percents[1] = protection;
percents[2] = nutrition;
}
/**
* 绘制分值区
*/
private void drawRegion(Canvas canvas) {
float radius = mStartRadius * 5;
for (int i = 0; i < NUM_OF_SIDES; i++) {
float x = (float) (Math.cos(mAngel * i) * radius * percents[0]);
float y = (float) (Math.sin(mAngel * i) * radius * percents[0]);
if (i == 0) {
mPathRegion.moveTo(mCenterX + x, mCenterY);
} else {
mPathRegion.lineTo(mCenterX + x, mCenterY + y);
}
}
mPathRegion.close();
canvas.drawPath(mPathRegion, mPaintRegion);
}
/**
* 绘制直线
*/
private void drawLine(Canvas canvas) {
float radius = mStartRadius * 5;
for (int i = 0; i < NUM_OF_SIDES; i++) {
mPathLine.moveTo(mCenterX, mCenterY);
float x = (float) (mCenterX + Math.cos(mAngel * i) * radius);
float y = (float) (mCenterY + Math.sin(mAngel * i) * radius);
mPathLine.lineTo(x, y);
canvas.drawPath(mPathLine, mPaintLine);
}
}
/**
* 绘制多边形
*/
private void drawPolygon(Canvas canvas) {
for (int count = 1; count <= 5; count++) {
float newRadius = mStartRadius * count;
mPathPolygon.moveTo(mCenterX + newRadius, mCenterY);
for (int i = 1; i < NUM_OF_SIDES; i++) {
float x = (float) (mCenterX + Math.cos(mAngel * i) * newRadius);
float y = (float) (mCenterY + Math.sin(mAngel * i) * newRadius);
mPathPolygon.lineTo(x, y);
}
mPathPolygon.close();
canvas.drawPath(mPathPolygon, mPaintPolygon);
mPathPolygon.reset();
}
}
}`
其中setRegionValue();方法用来控制数据,init方法中还根据屏幕的宽度来确定雷达图的大小,使用SharedPreferences在程序启动的时候获取屏幕的宽度。