曲线分布图

来源:互联网 发布:淘宝老七贸易 编辑:程序博客网 时间:2024/04/26 13:35




package com.example.exapmle;



import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.View;


/**
 * 曲线分布�?
 * 
 * @author ryan
 * @date 2016-02-03
 * 
 */
public class CurveProfileView extends View {
// �?��步数
private final static int MAX = 30000;
// 自定义图形的宽度
private float width;
// 自定义图形的高度
private float height;
// 圆环画笔
private Paint circlePaint;
// 实心圆画笔
private Paint mCirclePaint;
// 直线的画�?
private Paint linePaint;
// 区域画笔
private Paint tranglePaint;
// 曲线画笔
private Paint curvelinePaint;
// 日期画笔
private Paint timePaint;
// �?3 �?2 �? 1�?: 0 指示标记
private int index;
// �?��步数
private short maxStep;
// 顶部间隔
private final static int MARGINTOP = 30;
// 左右间隔
private final static int MARGIN = 100;
// y等分间隔
private int y_distance = 0;
// y轴对应的刻度与�?之间的比�?
private double y_scale = 0.0f;
// 步数
private ArrayList<Short> steps;
// 水平方向被均分多少等�?
private int count;
// 圆环半径
private final static int RADIUS = 10;
//日期转换
@SuppressLint("SimpleDateFormat")
private SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
private List<Point> mPoints;


public CurveProfileView(Context context) {
super(context);
init(context, null);
}


public CurveProfileView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}


public CurveProfileView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}


private void init(Context context, AttributeSet attrs) {
setCirclePaint();
setLinePaint();
setTranglePaint();
setCurveLinePaint();
setTimePaint();
steps = new ArrayList<Short>();
mPoints = new ArrayList<Point>();
}


private void test() {
ArrayList<Short> data = new ArrayList<Short>();
data.add((short) 25);
data.add((short) 75);
data.add((short) 100);
setSteps(data, 0);
}


/**
* 设置时间的画笔
*/
private void setTimePaint() {
timePaint = new Paint();
timePaint.setColor(0xff333333);
timePaint.setTextSize(25);
timePaint.setAntiAlias(true);
}


/**
* 设置曲线的画笔
*/
private void setCurveLinePaint() {
curvelinePaint = new Paint();
curvelinePaint.setColor(0xffde4e4f);
curvelinePaint.setStrokeWidth(4);
curvelinePaint.setAntiAlias(true);
}


/**
* 设置多边形的画笔
*/
private void setTranglePaint() {
tranglePaint = new Paint();
tranglePaint.setColor(0xffde4e4f);
tranglePaint.setStyle(Paint.Style.FILL);
tranglePaint.setAlpha(51);
tranglePaint.setAntiAlias(true);
}


/**
* 设置分割线的画笔
*/
private void setLinePaint() {
linePaint = new Paint();
linePaint.setColor(0xffffc2bf);
linePaint.setAlpha(102);
linePaint.setTextSize(28);
linePaint.setAntiAlias(true);
linePaint.setStrokeWidth(3);
}


/**
* 设置圆环形的画笔
*/
private void setCirclePaint() {
circlePaint = new Paint();
circlePaint.setStrokeWidth(3.0f);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setColor(0xffcd3739);
circlePaint.setAntiAlias(true);


mCirclePaint = new Paint();
mCirclePaint.setStyle(Paint.Style.FILL);
mCirclePaint.setColor(Color.rgb(255, 98, 106));
mCirclePaint.setAntiAlias(true);
}


@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
setHeightAndWidth();
test();
drawLineText(canvas);
setPoints();
drawCurveLine(canvas);
drawTrangle(canvas);
drawCircle(canvas);
drawTime(canvas);
}


private void setPoints() {
mPoints.clear();
if (count > 0) {
float distance = 0;
if (index == 0) {
distance = (width - 2 * MARGIN) / 23;
}
for (int i = 0; i < count; i++) {
Point mPoint = new Point((int) (MARGIN + i * distance),
(int) (MARGINTOP + 2 * y_distance - steps.get(i)
* y_scale));
mPoints.add(mPoint);
}
}
}


/**
* 画时间字符串

* @param canvas
*/
private void drawTime(Canvas canvas) {
float textWidth = 0;
float distance = 0;
if (index == 0) {
canvas.drawText("0点", MARGIN, height - y_distance / 2, timePaint);
textWidth = timePaint.measureText("12点");
canvas.drawText("12点", width / 2 - textWidth / 2, height
- y_distance / 2, timePaint);
textWidth = timePaint.measureText("24点");
canvas.drawText("24点", width - MARGIN - textWidth, height
- y_distance / 2, timePaint);
} else if (index == 1) {
distance = (width - MARGIN) / 6;
            setWeekText(canvas,distance);
} else if (index == 2) {
distance = (width - MARGIN) / 29;
setMonthText(canvas,distance);
}else if (index == 3) {
distance = (width - MARGIN) / 11;
for (int i = 0; i < 12; i++) {
textWidth = timePaint.measureText("" + (i + 1));
canvas.drawText("" + (i + 1), MARGIN + i * distance - 
textWidth / 2, height - y_distance / 2, timePaint);
}
}
}


/**
* 设置月的时间
* @param canvas
* @param distance
*/
private void setMonthText(Canvas canvas, float distance) {
long time = System.currentTimeMillis();
for (int i = 29; i < 30; i--) {
time = time - 3600*24*(i - 29);
float textWidth = timePaint.measureText(sdf.format(time));
if (i % 6 == 5 || i % 6 == 0){
 canvas.drawText(sdf.format(time), MARGIN + i * distance - 
textWidth / 2, height - y_distance / 2, timePaint);
}
}
}


/**
* 设置按周文字
*/
private void setWeekText(Canvas canvas,float distance) {
long time = System.currentTimeMillis();
for (int i = 6; i < 7; i--) {
time = time - 3600*24*(i - 6);
float textWidth = timePaint.measureText(sdf.format(time));
if (i == 6) {
canvas.drawText("今日", MARGIN + i * distance - 
textWidth / 2, height - y_distance / 2, timePaint);
}else{
canvas.drawText(sdf.format(time), MARGIN + i * distance - 
textWidth / 2, height - y_distance / 2, timePaint);
}
}
}


/**
* 画圈

* @param canvas
*/
private void drawCircle(Canvas canvas) {
if (mPoints.size() > 0) {
int size = mPoints.size();
for (int i = 0; i < size; i++) {
Point mPoint = mPoints.get(i);
canvas.drawCircle(mPoint.x, mPoint.y - RADIUS, RADIUS,
mCirclePaint);
canvas.drawCircle(mPoint.x, mPoint.y - RADIUS, RADIUS,
circlePaint);


}
}
}


/**
* 画曲线

* @param canvas
*/
private void drawCurveLine(Canvas canvas) {
if (mPoints.size() > 1) {
int size = mPoints.size();
for (int i = 1; i < size; i++) {
Point lastPoint = mPoints.get(i - 1);
Point mPoint = mPoints.get(i);
canvas.drawLine(lastPoint.x, lastPoint.y, mPoint.x, mPoint.y,
curvelinePaint);
}
}
}


/**
* 画多边形

* @param canvas
*/
private void drawTrangle(Canvas canvas) {
if (mPoints.size() > 1) {
int size = mPoints.size();
Path mPath = new Path();
for (int i = 0; i < size; i++) {
Point mPoint = mPoints.get(i);
if (i == 0) {
mPath.moveTo(mPoint.x, height);
}
mPath.lineTo(mPoint.x, mPoint.y);
if (i == size - 1) {
mPath.lineTo(mPoint.x, height);
}
}
mPath.close();
canvas.drawPath(mPath, tranglePaint);
}
}


/**
* 画水平线和水平线右边的文字
*/
private void drawLineText(Canvas canvas) {
for (int i = 0; i < 3; i++) {
canvas.drawLine(MARGIN, MARGINTOP + i * y_distance, width - MARGIN,
MARGINTOP + i * y_distance, linePaint);
if (i == 0) {
canvas.drawText(maxStep + "", width - MARGIN + 5, MARGINTOP + i
* y_distance + 7, linePaint);
} else if (i == 1) {
canvas.drawText(maxStep / 2 + "", width - MARGIN + 5, MARGINTOP
+ i * y_distance + 7, linePaint);
} else if (i == 2) {
canvas.drawText("0", width - MARGIN + 5, MARGINTOP + i
* y_distance + 7, linePaint);
}
}
}


/**
* 设置高宽
*/
private void setHeightAndWidth() {
if (width == 0) {
width = getWidth();
}
if (height == 0) {
height = getHeight();
}
y_distance = (int) (height - MARGINTOP) / 3;
}


/**
* 设置步数

* @param steps
*/
public void setSteps(ArrayList<Short> steps) {
if (null == steps) {
steps = new ArrayList<Short>();
} else {
int size = steps.size();
for (int i = 0; i < size; i++) {
if (i == 0) {
maxStep = steps.get(i);
} else {
if (maxStep < steps.get(i)) {
maxStep = steps.get(i);
}
}
}
}
if (maxStep == 0) {
maxStep = MAX;
}
if (this.steps != null) {
this.steps.clear();
}
this.steps = steps;
count = this.steps.size();
setScale();
invalidate();
}


/**
* 设置x轴和y轴的尺寸比例
*/
private void setScale() {
if (index == 0) {
y_scale = (2 * y_distance) / maxStep;
} else if (index == 1) {
y_scale = height / maxStep;
}


}


/**
* 设置步数

* @param steps
*            步数
* @param index
*            指示标记 �?3 �?2 �?1 �?0
*/
public void setSteps(ArrayList<Short> steps, int index) {
this.index = index;
setSteps(steps);
}


/**
* 释放�?��资源
*/
public void clear() {
if (steps != null) {
steps.clear();
steps = null;
}
if (mPoints != null) {
mPoints.clear();
mPoints = null;
}
linePaint = null;
circlePaint = null;
curvelinePaint = null;
timePaint = null;
tranglePaint = null;
}

}



package com.example.exapmle;


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;


@SuppressLint("SimpleDateFormat")
public class LineCharView extends View {
//横坐标的数量
private final static int xCount = 7;
//纵坐标的数量
private final static int yCount = 7;
//圆的半径
private final static int RADIUS = 10;
//圆与数据间隔
private final static int DISTANCE = 25;

private int xylinecolor;//xy坐标轴颜色
private int xylinewidth;//xy坐标轴大小
private int xytextcolor;//xy坐标轴文字颜色
private int xytextsize;//xy坐标轴文字大小
private int linecolor;//折线的颜色
private int x_interval;//X坐标间的间隔
private int y_interval;//Y坐标间的间隔
private int bgColor;//背景颜色
private int width;//控件宽度
private int heigth;//控件高度
//左右间隔
private final static int MARGIN = 50;
//数据集合
private List<Integer> mList;
//数据集合中的最大值
private int maxValue = 20000;
//把数据转换为点的集合
private List<Point> mPoints;
//日期转换工具
private SimpleDateFormat sdf;
//文字显示
private List<String> texts;
//圆的宽度
public LineCharView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray= context.obtainStyledAttributes(attrs, R.styleable.LineChar);
//x坐标轴颜色
xylinecolor=typedArray.getColor(R.styleable.LineChar_xylinecolor, Color.GRAY);
// x坐标轴宽度 
xylinewidth=typedArray.getInt(R.styleable.LineChar_xylinewidth, 5);
//x坐标轴文字颜色
xytextcolor=typedArray.getColor(R.styleable.LineChar_xytextcolor, Color.BLACK);
//x坐标轴文字大小
xytextsize=typedArray.getLayoutDimension(R.styleable.LineChar_xytextsize, 20);
//折线的颜色 
linecolor=typedArray.getColor(R.styleable.LineChar_linecolor, Color.RED);
//背景颜色
bgColor=typedArray.getColor(R.styleable.LineChar_bgcolor, Color.WHITE);
typedArray.recycle();
//x坐标点的值
mList=new ArrayList<Integer>();
mPoints = new ArrayList<Point>();
texts = new ArrayList<String>();
sdf = new SimpleDateFormat("dd");
}

public LineCharView(Context context) {
super(context);
}




@SuppressLint("DrawAllocation")
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
if(changed){
width=getWidth();
heigth=getHeight();
x_interval = (int)((width - 2 * MARGIN) / (xCount - 0.5));
y_interval = (int)(heigth / (yCount + 0.5));
setBackgroundColor(bgColor);
}
super.onLayout(changed, left, top, right, bottom);
}




@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
test();
drawXY(canvas);
drawTime(canvas);
drawCurveLine(canvas);
drawValue(canvas);
}

/**
* 写数据
* @param canvas
*/
private void drawValue(Canvas canvas) {
if (mPoints.size() > 0) {
int size = mPoints.size();
Paint mPaint = new Paint();
mPaint.setTextSize(xytextsize);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(linecolor);
//画坐标点
for(int i = 0; i < size; i ++){
String text = mList.get(i)+"";
float mDistance = mPaint.measureText(text);
Point mPoint = mPoints.get(i);
float y = mPoint.y - DISTANCE;
if (y < 18) {
y = 75;
}
canvas.drawText(text,(float)mPoint.x - mDistance / 2, y, mPaint);
}
}
}


/**
* 画曲线和圆圈
* @param canvas
*/
private void drawCurveLine(Canvas canvas) {
if (mPoints.size() > 0) {
int size = mPoints.size();
Paint mPaint = new Paint();
mPaint.setTextSize(xytextsize);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
mPaint.setColor(linecolor);
//画坐标点
for(int i = 0; i < size; i ++){
Point mPoint = mPoints.get(i);
if (i > 0) {
Point lastPoint = mPoints.get(i -1);
canvas.drawLine(lastPoint.x, lastPoint.y, mPoint.x, mPoint.y, mPaint);
}
canvas.drawCircle(mPoint.x, mPoint.y, RADIUS, mPaint);
}
}
}


/**
* 设置时间
* @param canvas
*/
private void drawTime(Canvas canvas) {
Paint paint=new  Paint();
paint.setTextSize(xytextsize);
paint.setColor(xytextcolor);
if (texts.size() > 0) {
int size = texts.size();
for(int i= 0;i < size;i++){
String value = texts.get(i);
float distance = paint.measureText(value);
float x = MARGIN + i *x_interval - distance / 2;
float y = (float)(yCount*y_interval);
canvas.drawText(value, x, y, paint);
}
}
}


//画坐标轴
private void drawXY(Canvas canvas){
drawX(canvas);
drawY(canvas);
}

//画X轴坐标点
private void drawX(Canvas canvas){
Paint paint=new  Paint();
paint.setColor(xylinecolor);
paint.setStyle(Paint.Style.FILL);
// Log.i("Ryan", "height = "+ heigth + ",width = "+ width + "y_interval = "+ y_interval + ",x_interval = "+ x_interval);
for(int i= 0;i < yCount;i++){
canvas.drawLine(MARGIN, (float)((i + 0.5) * y_interval), (float)(MARGIN + (xCount - 0.5) * x_interval), (float)((i + 0.5) * y_interval), paint);
}
}

//画Y轴坐标点
private void drawY(Canvas canvas) {
Paint paint=new  Paint();
paint.setColor(xylinecolor);
paint.setStyle(Paint.Style.FILL);
for(int i= 0;i < xCount;i++){
canvas.drawLine(MARGIN + i * x_interval, 0, MARGIN + i * x_interval, (float)((yCount - 0.5) * y_interval), paint);
}
}

public int getXylinecolor() {
return xylinecolor;
}


public void setXylinecolor(int xylinecolor) {
this.xylinecolor = xylinecolor;
}




public int getXylinewidth() {
return xylinewidth;
}




public void setXylinewidth(int xylinewidth) {
this.xylinewidth = xylinewidth;
}




public int getXytextcolor() {
return xytextcolor;
}




public void setXytextcolor(int xytextcolor) {
this.xytextcolor = xytextcolor;
}




public int getXytextsize() {
return xytextsize;
}




public void setXytextsize(int xytextsize) {
this.xytextsize = xytextsize;
}




public int getLinecolor() {
return linecolor;
}




public void setLinecolor(int linecolor) {
this.linecolor = linecolor;
}


public int getBgColor() {
return bgColor;
}


public void setBgColor(int bgColor) {
this.bgColor = bgColor;
}


/**
* 设置坐标折线图值

* @param x_coords 纵坐标点
*/
public void  setList(List<Integer> x_coords) {
if (this.mList != null) {
  this.mList.clear();
}
if (this.mPoints != null) {
  this.mPoints.clear();
}else {
this.mPoints = new ArrayList<Point>();
}
if (this.texts != null) {
  this.texts.clear();
}else {
this.texts = new ArrayList<String>();
}
if (null == x_coords) {
x_coords = new ArrayList<Integer>();
}
this.mList=x_coords;
   changePoints();
invalidate();
}


/**
* 测试
*/
private void test(){
List<Integer> list = new ArrayList<Integer>();
int value = 1000;
for (int i = 0; i < 4; i++) {
value += i * 500;
list.add(value);
}
setList(list);
}
/**
* 把值转换为点坐标
*/
private void changePoints() {
if (mList.size() > 0) {
    int size = mList.size();
    maxValue = Collections.max(mList);
    if (maxValue == 0) {
maxValue = 20000;
}
    double scale = (double)y_interval * (yCount - 1) / maxValue;
Log.i("Ryan", "scale = "+ scale + ",maxValue = "+ maxValue + ",y_interval = "+ y_interval);
    long time = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
int value = mList.get(i);
int y = (int)(0.5 * y_interval + (scale * (maxValue - value)));
Point mPoint = new Point(MARGIN + i * x_interval, y);
mPoints.add(mPoint);
//设置时间字符串
if (i == size - 1) {
texts.add("今日");
}else{
texts.add(sdf.format(time - (size - 1 - i) * 24 * 3600 * 1000));
}
}
}
}


/**
* 获取数据集合
* @return
*/
public List<Integer> getList(){
return mList;
}

/**
* 清理数据
*/
public void clearData(){
if (mList != null) {
mList.clear();
mList = null;
}
if (mPoints != null) {
mPoints.clear();
mPoints = null;
}
if (texts != null) {
texts.clear();
texts = null;
}
}
}

0 0
原创粉丝点击