以前用achartengine绘制折线图,但是想要实现类似于方波矩形波这中工程图没实现,项目需要就动手绘制了一个,效果还好
我是用DrawLineChartView.java进行图形绘制,mainactivity.java进行界面设置,xml进行布局
效果图如下:
直接上代码:
/*************************************************************************************************************************
*DrawLineChartView.java中的ondraw方法
************************************************************************************************************************/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置绘制模式为-虚线作为背景线。
PathEffect effect = new DashPathEffect(new float[] { 6, 6, 6, 6, 6}, 2);
//背景虚线路径.
Path path = new Path();
//只是绘制的XY轴
linePaint.setStyle(Style.STROKE);
linePaint.setStrokeWidth((float)0.7);
linePaint.setColor(Color.BLACK);
linePaint.setAntiAlias(true);// 锯齿不显示
//XY刻度上的字
textPaint.setStyle(Style.FILL);// 设置非填充
textPaint.setStrokeWidth(1);// 笔宽5像素
textPaint.setColor(Color.BLACK);// 设置为蓝笔
textPaint.setAntiAlias(true);// 锯齿不显示
textPaint.setTextAlign(Align.CENTER);
textPaint.setTextSize(15);
//绘制XY轴上的字:Y开关状态、X时间
xyChartPaint.setStyle(Style.FILL);
xyChartPaint.setStrokeWidth(1);
xyChartPaint.setColor(Color.BLUE);
xyChartPaint.setAntiAlias(true);
xyChartPaint.setTextAlign(Align.CENTER);
xyChartPaint.setTextSize(18);
//绘制的折线
chartLinePaint.setStyle(Style.FILL);
chartLinePaint.setStrokeWidth(3);
chartLinePaint.setColor(Color.RED);//(1)黄色
chartLinePaint.setAntiAlias(true);
//基准点。
float gridX = 30+10;
float gridY = getHeight() - 50;
//XY间隔。
float xSpace = (float) ((getWidth()-60)/6-1.5);
//画Y轴(带箭头)。
canvas.drawLine(gridX, gridY-20-10, gridX, 30+10, linePaint);
canvas.drawLine(gridX, 30+10, gridX-6, 30+14+10, linePaint);//Y轴箭头。
canvas.drawLine(gridX, 30+10, gridX+6, 30+14+10, linePaint);
//画Y轴名字。
//由于是竖直显示的,先以原点顺时针旋转90度后为新的坐标系
canvas.rotate(-90);
//当xyChartPaint的setTextAlign()设置为center时第二、三个参数代表这四个字中点所在的xy坐标
canvas.drawText("开关状态", -((float)(getHeight()-60)-15-5 - 1/((float)1.6*1) * (getHeight()-60)/2), gridX-15, xyChartPaint);
canvas.rotate(90); //改变了坐标系还要再改过来
float y = 0;
//画X轴。
y = gridY-20;
canvas.drawLine(gridX, y-10, getWidth(), y-10, linePaint);//X轴.
canvas.drawLine(getWidth(), y-10, getWidth()-14, y-6-10, linePaint);//X轴箭头。
canvas.drawLine(getWidth(), y-10, getWidth()-14, y+6-10, linePaint);
//画背景虚线,一条(因为除去了X轴),画Y轴刻度
y = (float)(getHeight()-60)-15-5 - 1/((float)1.6*1) * (getHeight()-60);//虚线的Y,开关是开的时候的Y。
linePaint.setPathEffect(effect);//设法虚线间隔样式。
//画除X轴之外的------背景虚线一条-------
path.moveTo(gridX, y);//背景【虚线起点】。
path.lineTo(getWidth(), y);//背景【虚线终点】。
canvas.drawPath(path, linePaint);
//画Y轴刻度。
canvas.drawText("关", gridX-6-7, gridY-20, textPaint);
canvas.drawText("开", gridX-6-7, y+10, textPaint);
//绘制X刻度坐标。
float x = 0;
if(dateX[0] != null) { //用X来判断,就是用来如果刚开始的点数少于7个则从左到右递增,从而没有了刚开始的几个虚点;(因为X和Y的数组初始化时都没赋值,所以刚开始的时候用这个就可以判断数组中到底几个点)
for(int n = 0; n < dateX.length; n++) {
//取X刻度坐标.
x = gridX + (n) * xSpace;//在原点(0,0)处也画刻度(不画的话就是n+1),向右移动一个跨度。
//画X轴具体刻度值。
if(dateX[n] != null) {
canvas.drawLine(x, gridY-30, x, gridY-18, linePaint);//短X刻度。
canvas.drawText(dateX[n], x, gridY+5, textPaint);//X具体刻度值。
}
}
}
//起始点。
float lastPointX = 0; //前一个点
float lastPointY = 0;
float currentPointX = 0;//当前点
float currentPointY = 0;
if(dateY != null) {
//1.绘制折线。
for(int n = 0; n < dateY.length; n++) {
//get current point
currentPointX = n * xSpace + gridX;
currentPointY = (float)(getHeight()-60)-15-5 - (float)dateY[n]/((float)1.6*1) * (getHeight()-60);
if(dateX[n] != null){//用X来判断,就是用来如果刚开始的点数少于7个则从左到右递增,从而没有了刚开始的几个虚点;(因为X和Y的数组初始化时都没赋值,所以刚开始的时候用这个就可以判断数组中到底几个点)
if(n>0){//从第二个点开始判断
if(dateY[n-1]==dateY[n]){//如果相邻两个点相等一直画直线
//draw line
canvas.drawLine(lastPointX, lastPointY, currentPointX, currentPointY, chartLinePaint);//第一条线[蓝色]
}
else{//如果相邻间的点不相等证明是从开到关或者关到开的状态,要画竖线
//draw line 横线
canvas.drawLine(lastPointX, lastPointY, currentPointX, lastPointY, chartLinePaint);//第一条线[蓝色]
//draw line 竖线
canvas.drawLine(currentPointX, lastPointY, currentPointX, currentPointY, chartLinePaint);//第一条线[蓝色]
}
}
}
lastPointX = currentPointX;
lastPointY = currentPointY;
}
}
//画X轴名字。
canvas.drawText("时间", getWidth()/2-10, getHeight()-18, xyChartPaint);
}
/*************************************************************************************************************************
*mainactivity.java 数据更新
************************************************************************************************************************/
public class MainActivity extends Activity {
private Timer timer = new Timer();
private TimerTask task;
TextView status_switch;
TextView status_online;
SimpleDateFormat shijian = new SimpleDateFormat("HH:mm:ss");
DrawLineChartView drawLineChartView;
int addY;
String addX ;
int flag_start=0;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawLineChartView= (DrawLineChartView) findViewById(R.id.drawLineChart);//控件实例化
status_switch=(TextView)findViewById(R.id.status_switch);
status_online=(TextView)findViewById(R.id.status_online);
//Looper.prepare();
final Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
if (msg.what == 0x123)
{
addX= shijian.format(new java.util.Date());
addY = (int) (Math.random()*2);
//显示开关状态的
if(addY==1)
status_switch.setText("开");
else
status_switch.setText("关");
//在刚开始还不足七个点的时候运行
if(flag_start<7){
drawLineChartView.dateY[flag_start]=addY;
drawLineChartView.dateX[flag_start] = addX;
}
else{//超过七个点后运行
for(int n=0;n<6;n++)
{
drawLineChartView.dateY[n]=drawLineChartView.dateY[n+1];
drawLineChartView.dateX[n] = drawLineChartView.dateX[n+1];
}
drawLineChartView.dateY[6]=addY;
drawLineChartView.dateX[6] = addX;
}
flag_start++;
if(flag_start>=7)
flag_start=7;
}
}
};
task=new TimerTask()
{
@Override
public void run()
{
handler.sendEmptyMessage(0x123);//发送给本类更新数据的
drawLineChartView.handler.sendEmptyMessage(0x124);//发送给DrawLineChartView类更新图形的
}
};
timer.schedule(task, 0, 2000);
}//oncreate结束
/*************************************************************************************************************************
*布局文件略
************************************************************************************************************************/