前几天为了实现类window资源管理器的效果实现了这个折线图。
效果如下:
使用方法:
通过renderPoint添加节点。
代码如下:
package com.hyena.cpumonitor.view;
import android.content.Context;
import android.graphics.Bitmap;
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 yangzc
*
*/
public class LineChartView extends View {
private int mSpeedX = 4;//速度
//刻度相关
private int mScalePos = 0;//刻度面板位置
// private int mCurYMaxValue = 0;
private int mScaleCellWidth = 0;
private Canvas mScaleCanvas = new Canvas();
private Bitmap mScaleBitmap;
private Path mScalePath;
private Paint mScalePaint = new Paint();
//图表相关
private int mGraphicPos = 0;
private int mSecoundGraphicPos = 0;
private Canvas mGraphicCanvas = new Canvas();
private Bitmap mGraphicBitmap;
private Paint mGraphicPaint = new Paint();
private Point mLastPoint = new Point();
private int mWidth = 0;
private int mHeight = 0;
public LineChartView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public LineChartView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LineChartView(Context context) {
super(context);
}
/**
* 添加采样点
* @param value
*/
public void renderPoint(int value){
if(mGraphicPos <= -mWidth){
mGraphicPos = 0;
Bitmap graphicBm = Bitmap.createBitmap(mGraphicBitmap, mWidth, 0, mWidth, mHeight);
mGraphicBitmap = Bitmap.createBitmap(mWidth*2, mHeight, Bitmap.Config.ARGB_8888);
mGraphicCanvas.setBitmap(mGraphicBitmap);
mGraphicCanvas.drawBitmap(graphicBm, 0, 0, null);
mLastPoint.x = mWidth;
}
float v = mHeight - (value / 100f * mHeight);
mGraphicCanvas.drawLine(mLastPoint.x, mLastPoint.y, mLastPoint.x + mSpeedX, v, mGraphicPaint);
mLastPoint = new Point(mLastPoint.x + mSpeedX, (int) v);
invalidate();
mGraphicPos -= mSpeedX;
mSecoundGraphicPos -= mSpeedX;
}
/**
* 构筑刻度
* @param x
* @param y
* @param width
* @param height
* @param maxXValue
* @param maxYValue
* @return
*/
private Path buildScalePath(int x, int y, int width, int height, int maxXValue, int maxYValue) {
Path path = new Path();
int rowHeight = Math.round(height / maxYValue)%2 == 0 ? Math.round(height / maxYValue): Math.round(height / maxYValue) + 1;
int columnWidth = Math.round(width / maxXValue)%2 == 0 ? Math.round(width / maxXValue) : Math.round(width / maxXValue) + 1;
//画X轴
for(int i=0; i< maxYValue; i++){
path.moveTo(x, i * rowHeight);
path.lineTo(x + width, i * rowHeight);
}
//画竖线
for(int i=0; i< maxXValue; i++){
path.moveTo(i * columnWidth, y);
path.lineTo(i * columnWidth, y + height);
}
path.close();
return path;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if(w <= 0 || h <= 0)return;
this.mWidth = w;
this.mHeight = h;
//构造刻度内容
mScaleBitmap = Bitmap.createBitmap(w + 40, h, Bitmap.Config.ARGB_8888);
mScaleCanvas.setBitmap(mScaleBitmap);
mScalePaint.setAntiAlias(true);
mScalePaint.setColor(Color.GREEN);
mScalePaint.setStrokeWidth(.5f);
mScalePaint.setStyle(Paint.Style.STROKE);
mScalePath = buildScalePath(0, 0, mWidth + 40, mHeight, 25, 8);
mScaleCanvas.drawPath(mScalePath, mScalePaint);
mScaleCellWidth = (mWidth + 40)/25;
//单元格宽度务必要可以被2整除
mScaleCellWidth = mScaleCellWidth%2 == 0 ? mScaleCellWidth : mScaleCellWidth + 1;
mSpeedX = mScaleCellWidth/2;
//构造图表
mGraphicBitmap = Bitmap.createBitmap(w*2, h, Bitmap.Config.ARGB_8888);
mGraphicCanvas.setBitmap(mGraphicBitmap);
mGraphicPaint.setAntiAlias(true);
mGraphicPaint.setColor(Color.GREEN);
mGraphicPaint.setStyle(Paint.Style.STROKE);
mGraphicPos = mWidth;
mLastPoint = new Point(10, 0);
if(mLineChartStateChangeListener != null)
mLineChartStateChangeListener.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
int left = mScalePos - mSpeedX;
// Log.v("yangzc", "Left : " +left + ", mScaleCellWidth: " + mScaleCellWidth);
if(Math.abs(left) >= mScaleCellWidth)
left = 0;
canvas.drawBitmap(mScaleBitmap, left, 0, null);
mScalePos = left;
//画报表
canvas.drawBitmap(mGraphicBitmap, mGraphicPos, 0, null);
}
private LineChartStateChangeListener mLineChartStateChangeListener;
public void setLineChartStateChangeListener(LineChartStateChangeListener lineChartStateChangeListener){
this.mLineChartStateChangeListener = lineChartStateChangeListener;
}
public static interface LineChartStateChangeListener {
public void onSizeChanged(int w, int h, int oldw, int oldh);
}
}