折线图的绘制,这种方式可以自定义X轴Y轴的长度,显示的数值的大小,而我之前用的方式根据屏幕的像素来绘制折线图,虽然搞了很久但是一点都不稳定,研究很久才找到这种方法,贴出来和大家分享一下
需求:绘制一个折线图,要求一共显示7个点,刚开始的时候没有点,随着数据传入依次显示1,2。。。。7个点,当7个点铺满的时候,新加入的数据占据第一个点的位置,并将第8个点移除屏幕位置。数据为动态加载的。
实现思路:拿一个画笔在画布上画图,首先要定义好一些基础数据,如X轴的最大最小值,显示的点的数量,标题等,具体的看下面的代码部分
public class ChartView extends View {
public static final int MAX_DATA_COUNT=7;
private int maxValue=100;
private int minValue=0;
private int[]datas=new int[10];
private int dataCount=0;//
private String title="";
private int value; //传送进来的值,用于判断是否超标
private int viewHeight,viewWidth;
public ChartView(Context context) {
super(context);
for(int i=0;i<MAX_DATA_COUNT;i++)
datas[i]=20;
}
public ChartView(Context context, AttributeSet attrs) {
super(context, attrs);
for(int i=0;i<MAX_DATA_COUNT;i++)
datas[i]=20;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getMaxValue() {
return maxValue;
}
public void setMaxValue(int maxValue) {
this.maxValue = maxValue;
}
public int getMinValue() {
return minValue;
}
public void setMinValue(int minValue) {
this.minValue = minValue;
}
/**
* 传送数据进来
* @param d 传送进来数据
* @param value 传送进来的判断数据
*/
public void addDatas(int d,int value){
this.value=value;
if(dataCount<MAX_DATA_COUNT){//datacount作为数组的下标
datas[dataCount]=d;//如果小于七个点,就一个一个点的加,向右布满七个点
dataCount++;
System.out.println("Add Data:"+d);
}
else{
for(int i=0;i<MAX_DATA_COUNT-1;i++){//如果已经有七个点,后一个覆盖前一个,实现点的更新
datas[i]=datas[i+1];//后一个替换前一个
}
datas[MAX_DATA_COUNT-1]=d;
}
System.out.println("Add Data:"+d);
}
private float toViewPosX(int x){
float dx=1.0f*viewWidth/(1.0f*(MAX_DATA_COUNT+2));//得到一个X轴的刻度长度
return dx+x*dx; // 第一个刻度加上X*一个刻度,做为当前的X轴的坐标,返回当前X轴的坐标
}
private float toViewPosY(int y){
float dy=1.0f*viewHeight/(1.0f*(maxValue-minValue));//获得一个Y的刻度长度
return 1.0f*viewHeight-y*dy;//返回当前Y轴的坐标
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
viewHeight = this.getHeight();
viewWidth = this.getWidth();
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
public void onDraw(Canvas canvas) {//画布
//白色 画笔
Paint whitePaint = new Paint();
whitePaint.setAlpha(100);
whitePaint.setAntiAlias(true);
whitePaint.setStyle(Paint.Style.FILL);
whitePaint.setColor(Color.WHITE);
whitePaint.setStrokeWidth(3);
//红色
Paint redPaint = new Paint();
redPaint.setAntiAlias(true);
redPaint.setAlpha(0);
redPaint.setStyle(Paint.Style.FILL);
redPaint.setColor(Color.RED);
redPaint.setStrokeWidth(3);
//蓝色
Paint bluePaint = new Paint();
bluePaint.setAntiAlias(true);
bluePaint.setAlpha(0);
bluePaint.setStyle(Paint.Style.FILL);
bluePaint.setColor(Color.BLUE);
bluePaint.setStrokeWidth(4);
if(dataCount>0){//如果下标大于0
//canvas.drawText("dataCount:"+dataCount,10, 50, p);
for (int i = 0; i <dataCount-1; i++) {
float startX=toViewPosX(i);
float startY=toViewPosY(datas[i]);
float stopX=toViewPosX(i+1);
float stopY=toViewPosY(datas[i+1]);
canvas.drawLine(startX, startY, stopX, stopY, whitePaint);
if (datas[i]>value) {//当前值大于value,画出前六个点
canvas.drawCircle(startX, startY, 5, redPaint);
canvas.drawText(String.valueOf(datas[i]), startX-4, startY-6, redPaint);
}else {
canvas.drawCircle(startX, startY, 5, whitePaint);
canvas.drawText(String.valueOf(datas[i]), startX-4, startY-6, whitePaint);
}
/*canvas.drawText("X"+startX+"Y"+startY, 10, 80, p);
break;*/
}
//画最后一个点与值
if (datas[dataCount-1]>value) {
canvas.drawCircle(toViewPosX(dataCount-1), toViewPosY(datas[dataCount-1]), 5, redPaint);
canvas.drawText(String.valueOf(datas[dataCount-1]), toViewPosX(dataCount-1)-4, toViewPosY(datas[dataCount-1])-6, redPaint);
}else {
canvas.drawCircle(toViewPosX(dataCount-1), toViewPosY(datas[dataCount-1]), 5, whitePaint);
canvas.drawText(String.valueOf(datas[dataCount-1]), toViewPosX(dataCount-1)-4, toViewPosY(datas[dataCount-1])-6, whitePaint);
}
}
canvas.drawText(title,10, 20, bluePaint);
canvas.drawText("Max:"+maxValue,10, 40, bluePaint);
canvas.drawText("Min:"+minValue,10, 60, bluePaint);
}
public void reFresh() {
this.invalidate();
}
}
附上:将折线图中的点换成图片的方法
//生成一个对象,设定缩放倍数
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize=2;
if(value<342(如果value大于342就把图片设置成另一张图片)){
//获得资源文件drawable中的图片
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pm2_point,options);
//将折线图中的换成图片
canvas.drawBitmap(bitmap, (交点的x轴的坐标)XPoint + i * XScale-3, (交点的Y轴坐标)258-YPoint-YCoord(Data[i]),paint);
}else if(value>=342(如果value大于342就把图片设置成另一张图片)){
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pm2_point_,options);
canvas.drawBitmap(bitmap, XPoint + i * XScale-3, 258-YPoint-YCoord(Data[i]),paint);
}