金融软件里的行情分时图,这是我们最常见的折线图,当然了,折线图的用途并不仅仅局限于此,像一般在一定区间内,为了更好的能显示出幅度的变化,那么用折线图来展示无疑是最符合效果的,当然了,网上也有很多的第三方开源,这篇文章呢,对开源的不做过多描述,想要了解请关注后续文章,好了,废话不多说,让我们从0来一步步绘制折线图吧。


先来看一下我们最终要实现的效果:

        


Android 折线图加背景 android绘制折线图_android怎么画折线图

很简单的一个空气质量折线图,俗话说,磨刀不误砍柴功,我们可以简单的分析一下,这个折线图主要包含了那几块,上面的标题可以做为一块,xy坐标轴是一块,折线是一块,简单的分为三块之后,代码我们就可以一块一块的去写。


定义一个类继承于View,实现其构造方法,先初始化我们需要的东西,背景设置偏黑色,初始化画笔。


private void initView() {
     setBackgroundColor(Color.parseColor("#222222"));
     mPaint = new Paint();
} 
在onDraw()方法里绘制标题:

/**
  * 绘制标题
  */
private void canvasTitle(Canvas canvas) {
     mPaint.setColor(Color.WHITE);
     mPaint.setTextSize(50);
     mPaint.setTypeface(blodFont);
     canvas.drawText("帝都空气质量趋势图(author:AbnerMing)", 100, 50, mPaint);
}

setTypeface()是用来设置字体,这里我设置的是,宋体加粗

Typeface blodFont = Typeface.create("宋体", Typeface.BOLD);

在onDraw()方法里绘制XY轴:

为了使整体看起来稍稍美观,我们绘制的时候,尽量与上下左右保持一定的距离,这里我设置的是距离底部为this.getBottom()-100,距离左边为100,代码如下:

int marginBottom = this.getBottom() - 100;
 int marginLeft = 100;

初始化XY轴:

//初始化X轴
mPaint.setColor(Color.WHITE);
canvas.drawLine(marginLeft, marginLeft, marginLeft, marginBottom, mPaint);
//初始化Y轴
mPaint.setStrokeWidth(6);
canvas.drawLine(marginLeft, marginBottom, this.getRight() - 20, marginBottom, mPaint);

XY轴绘制好之后,紧接着我们绘制时间轴,时间轴,这里我分成了5份,每份为5个小时,最后一份为4个小时,一份的宽度计算方式为:屏幕的宽度-距离右边的宽度-距离左边的宽度/5,代码如下:


int xWidth = (this.getRight() - 20 - marginLeft) / 5;

起始位置呢,就是距离左边的距离:


int xLine = marginLeft;//起始位置

每一个时间点,都是逐个增加一份的宽度,这里我们new一个Integer数组来存储:


Integer[] xPoint = new Integer[5];
 for (int a = 0; a < 5; a++) {
     xLine += xWidth;
     xPoint[a] = xLine;
}

xPoint就是各个时间点的X轴坐标,显然Y轴是不变的,那么我们就可以如下绘制;

for (int i = 0; i < xPoint.length; i++) {
     mPaint.setColor(Color.parseColor("#FF00FF"));
     mPaint.setTextSize(40);
     mPaint.setTypeface(font);
     mPaint.setTextAlign(Paint.Align.RIGHT);
     if (i == 0) {
         canvas.drawText("0", marginLeft,
                 marginBottom + 50, mPaint);
         canvas.drawText(times[i], xPoint[i],
                 marginBottom + 50, mPaint);
     } else {
         canvas.drawText(times[i], xPoint[i],
                 marginBottom + 50, mPaint);

     }
 }


times是自己定义的时间数组:


private String[] times = {"5:00", "10:00", "15:00", "20:00", "24:00"};

X轴的时间绘制好后,接着我们来绘制Y轴,其实Y轴的思路和X轴一样,也是分成5份,每份的计算方式为:屏幕的高度-距离底部的距离-距离上部的距离/5,代码如下;


int yHeight = (marginBottom - marginLeft) / 5;


由于5份每份的颜色值不一样,所以我们要逐一进行处理:


for (int i = 0; i < xPoint.length; i++) {
     mPaint.setStrokeWidth(6);
     int startY = marginBottom - yHeight * (i + 1);
     int endY = marginBottom - yHeight * i;
     switch (i) {
         case 0:
             mPaint.setColor(Color.GREEN);
             break;
         case 1:
             mPaint.setColor(Color.YELLOW);
             break;
         case 2:
             mPaint.setColor(0xFFFF7E00);
             break;
         case 3:
             mPaint.setColor(Color.RED);
             break;
         case 4:
             mPaint.setColor(0xFF8E1752);
             break;
     }
     //绘制颜色线
     canvas.drawLine(marginLeft, startY,
             marginLeft, endY, mPaint);
     //绘制空气污染值
     canvas.drawText(atmosphereNum[i] + "", marginLeft - 20,
             startY, mPaint);
     //绘制空气污染等级
     canvas.drawText(atmosphere[i], marginLeft - 20,
             endY - yHeight / 2, mPaint);
}

atmosphere是自己定义的污染值等级数组,atmosphere是自己定义的污染值数组:


private String[] atmosphere = {"优", "好", "良", "中", "差"};
 private int[] atmosphereNum = {100, 200, 300, 400, 500};

再来看最后一块,折线图的绘制。其实每个点就是一个坐标,绘制之前我们先把需要的数据整理一下:

private float[] broken = {0f, 30f, 75f, 160f, 66f, 170f, 80f, 120f,130f,150f,138f,180f,200f,
         220f,300f,235f,245f,260f,210f,270f,290f,270f,270f,250f,210f,180f,260f,280f,320f};
 private int[] brokenTimes = {0, 5, 10, 15, 20, 25, 30, 35,40,45,50,55,60,
         65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140};
 private Paint mPaint;

broken数组,是空气污染值,下面的brokenTimes是时间点,我是这样做的,X轴是24小时,共有1440分钟,我分成了10分钟一个点,也就是最多有144个点,brokenTimes里的数值都是增的,毕竟时间走着走着不可能变小,broken数组和brokenTimes数组的长度一定要一样大,因为,各个对应的值就是xy值。

纵轴是500个值,所以纵轴刻度值等于屏幕的高度-距离底部的距离-距离上部的距离/500,代码如下:


float brokenSizeY = (marginBottom - marginLeft) / 500;//得到纵轴刻度值

横轴刻度值等于屏幕的宽度-距离左边的距离-距离右边的距离/144,代码如下:

float brokenSizeX = (this.getRight() - 20 - marginLeft) / 144;

绘制如下:

float lastX = brokenTimes[0] * brokenSizeX + marginLeft, lastY = marginBottom - broken[0] * brokenSizeY;
 for (int a = 0; a < broken.length; a++) {
     float height = marginBottom - broken[a] * brokenSizeY;
     float width = brokenTimes[a] * brokenSizeX + marginLeft;
     canvas.drawCircle(width, height, 10, mPaint);

     canvas.drawLine(lastX, lastY, width, height, mPaint);
     lastX = width;
     lastY = height;
}


lastX是记录上一个X点,lastY是记录上一个Y点。

经过以上的代码,我们就可以绘制出文章刚开始的图片效果了,具体使用,也特别简单,哪里需要用,就在layout里调用就可以了:

<com.ming.abner.chartline.BrokenLineView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     />