浅析简易k线图图表

浅析简易k线图图表

先说下实现的需求: 咱们须要一个x轴分为12个刻度,x轴最大值为24. y轴最大刻度值为180,这样的一个k线图,如右图所示canvas

咱们先来整理下思路:

x最大为刻度24,y最大值为180.那么咱们怎么去绘制x轴刻度呢? 仔细想一想,x轴分为12份,最大值24.而且k线图表的宽度是已知的,那么咱们等比例计算: xStep(一个刻度)=已知宽度/24。 不就能够知道一个刻度值是多少了么?api

那咱们再来分析分析y轴的怎么处理。数组

如今已知的数值:最大值180,图表的高度(ps:别纠结图表高宽怎么来的啊~会挨板子的。控件生命周期onLayout 哪里就能够获取了) 那么 参考x轴的计算方式,同样咱们能够经过:yStep=已知高度/180.是否是挺简单的啊。至于驼峰,留到文末再说。有了思路,那么代码实现起来就很容易了,写这篇简易文章的出发点是想跟你们说说本身日常的我的观点,不要什么场景、事物开始前都想着直接找轮子,本身尝试实现、摸索的过程对于我的是y颇有益的。咳咳咳,很差意思。我跑题了。 回到原点,接下来开始编码部分:bash

编写X轴

继承View 重写onLayout 获取已知高宽markdown

@Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        width = getWidth();
        height = getHeight();
    }
复制代码

按照上面分析的公式,绘制X轴刻度ide

xPaint = new Paint();
        xPaint.setAntiAlias(true);
        xPaint.setStrokeWidth(xlinewidth);
        xPaint.setStrokeCap(Paint.Cap.ROUND);
        xPaint.setColor(xlinecolor);
        
     @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        step = width / 24f;
        y_step = height / 180f;
        canvas.drawLine(0, height, width, height, xPaint);
        for (int i = 0; i <= 12; i++) {
            canvas.drawLine((i * 2) * step, 0, (i * 2) * step, height, xPaint);
        }

       


    }
复制代码

知道刻度步伐,实现轴刻度是否是简单多了。 接下来咱们绘制k线吧。 我有一个24长度的集合数据:编码

ArrayList<Integer> data = new ArrayList<>();
        data.add(10);
        data.add(50);
        data.add(100);
        data.add(40);
        data.add(120);
        data.add(60);
        data.add(80);
        data.add(160);
        data.add(90);
        data.add(80);
        data.add(60);
        data.add(40);
        data.add(20);
        data.add(50);
        data.add(80);
        data.add(100);
        data.add(130);
        data.add(160);
        data.add(180);
        data.add(50);
        data.add(120);
        data.add(100);
        data.add(80);
        data.add(60);
        data.add(10);
复制代码

集合的角标分别对应x轴的1-24,我想把他们体如今图标上。那要怎么作呢? 其实想一想,咱们已知xStep和yStep,那么不久能够知道每一个值在每一个刻度的x,y坐标了么? 如 data集合0角标:x坐标=xStep1 y坐标=yStep10(data集合0角标的值)。 绘制一个点须要x,y就足够了。 那么咱们的实现逻辑代码以下:spa

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        step = width / 24f;
        y_step = height / 180f;
        canvas.drawLine(0, height, width, height, xPaint);
        for (int i = 0; i <= 12; i++) {
            canvas.drawLine((i * 2) * step, 0, (i * 2) * step, height, xPaint);
        }

        Path path = new Path();
        path.moveTo(0, height);
        for (int i = 0; i < data.size(); i++) {
            float x = (i + 1) * step;  //这是x坐标
            float y = height - (data.get(i) * y_step);//这是y坐标  总高度-y坐标,是为了从下往上

          path.lineTo(x, y);

        }
        canvas.drawPath(path, linePaint);
    }
复制代码

到了这一步是否是感受特别简单啊,那么恭喜你,又收获了自定义综合使用路上的小小知识点。毕竟水滴石穿嘛。 言归正传,咱们还有最后一个步骤,渲染驼峰呢~~~ 这一步我就不罗嗦了,官方其实有提供api的,小火鸡们日常要多查查看看文档啊(LinearGradient)code

mPaintShader = new Paint();
 mPaintShader.setAntiAlias(true);
 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        step = width / 24f;
        y_step = height / 180f;
        canvas.drawLine(0, height, width, height, xPaint);
        for (int i = 0; i <= 12; i++) {
            canvas.drawLine((i * 2) * step, 0, (i * 2) * step, height, xPaint);
        }



        //绘制折线
        Path path = new Path();
        path.moveTo(0, height);
        for (int i = 0; i < data.size(); i++) {
            float x = (i + 1) * step;  //这是x坐标
            float y = height - (data.get(i) * y_step);//这是y坐标  总高度-y坐标,是为了从下往上


            path.lineTo(x, y);

        }

        path.lineTo(width, height);
        canvas.drawPath(path, linePaint);


        Shader mShader = new LinearGradient(0, height + 10, 0, 0, getResources().getColor(R.color.colorAccent1), getResources().getColor(R.color.colorAccent5), Shader.TileMode.REPEAT);
//新建一个线性渐变,前两个参数是渐变开始的点坐标,第三四个参数是渐变结束的点的坐标。链接这2个点就拉出一条渐变线了,
// 。而后那个数组是渐变的颜色。下一个参数是渐变颜色的分布,若是为空,每一个颜色就是均匀分布的。最后是模式,这里设置的是循环渐变

        mPaintShader.setShader(mShader);
        canvas.drawPath(path, mPaintShader);
    }

复制代码

回过头看看,这一切实现起来不麻烦吧,只要日常多分析分析,碰到需求能够适当尝试一下本身实现,毕竟技术进阶之路不是一味的搬轮子~~不喜勿碰orm

相关文章
相关标签/搜索