ios股票K线图的绘制

作者: __阳阳 | 来源:发表于2017-01-06 17:29 被阅读1635次

    前言:因为工作需要,要绘制一个股票K线图,因为自己不炒股,所以对股票知识很是有限,当时也想在网上找个demo直接拿来用的,但是找了很多都不合适,后来查了些资料,也看了很多别人的demo,打算自己写,此文针对不会画直线画文字的新手, 没有考虑优化问题! 大神请略过 !

    因为自己当时对股票知识很是有限, 所以这里就从最基础说起, 首先看一下K线图解, 了解一下一个K线点所需要的数据:


    图片来自网络.gif

      阳线代表股票上涨(收盘价大于开盘价), 阴线则代表股票下跌(收盘价小于开盘价), 由此可以看出画一个K线点需要四个数据, 分别是: 开盘价 - 收盘价 - 最高价 - 最低价, 根据这四个数据画出上影线实体以及下影线, 柱状图(成交量)先不考虑, K线图画出来之后, 成交量柱状图就不在话下了;

    这里主要说一下怎么绘制线段和实体以及字符串,这些如果会了,那么绘制K线图就不是问题了;

    创建一个继承自UIView的类YBStockChartView, 就在这个类里边进行绘制, 首先要绘制背景, 无非就是那些横线竖线虚线之类的, 下边是画一条从p1p2的实线线段的代码:

    - (void)drawRect:(CGRect)rect {
        [super drawRect:rect];
        // 设置背景填充颜色
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
        CGContextFillRect (context, self.bounds);  // 填充范围
        // 画线段
        CGPoint p1 = CGPointMake(20, 20);
        CGPoint p2 = CGPointMake(rect.size.width - 20, rect.size.height - 20);
        CGContextSetLineWidth(context, 1.0f);
        CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
        CGContextMoveToPoint(context, p1.x, p1.y);
        CGContextAddLineToPoint(context, p2.x, p2.y);
        CGContextStrokePath(context);
    }
    

    如果要画虚线加上这句CGFloat dash[] = {1,3};CGContextSetLineDash(context, 0, dash, 0);代码即可,关于虚线,感兴趣的可以上网搜一下更加详细说明,这里只简单说一下{1,3}代表画一个点,空三个点,在画一个点在空三个点这样循环画出来的一条虚线;
      会画线段之后,K线图背景就可以这样轻轻松松的画出来了,那么接下来开始绘制K线点,K线点常见的有两种, 一种是空心的一种是实心的,我们先来画一个空心的,空心的分解一下就是两条线段加上一个矩形边框,只需要四个点就可以画出来,如下图:

    13B0C400-D96A-497C-97AB-CACAB9B67C4E.png
      下边是实现代码:
    - (void)drawRect:(CGRect)rect {
        [super drawRect:rect];
        
        CGPoint p1 = CGPointMake(100, 30);
        CGPoint p2 = CGPointMake(100, 70);
        CGPoint p3 = CGPointMake(100, 120);
        CGPoint p4 = CGPointMake(100, 170);
        
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
        CGContextSetLineWidth(context, 2.0);
        // p1 -> p2线段
        CGContextMoveToPoint(context, p1.x, p1.y);
        CGContextAddLineToPoint(context, p2.x, p2.y);
        // p3 -> p4线段
        CGContextMoveToPoint(context, p3.x, p3.y);
        CGContextAddLineToPoint(context, p4.x, p4.y);
        CGContextStrokePath(context);
        // 中间实体边框
        CGContextStrokeRect(context, CGRectMake(100 - 14 / 2.0, p2.y, 14, p3.y - p2.y));
    }
    

    下边开始画实心的,实心的比空心的简单,可以先画一条线段直接从p1画到p4,然后在中间在画实体就好了下边是效果图:


    4A76DF22-6C5D-4D6A-82AF-B775C9A1D4FD.png

    实现代码:

    - (void)drawRect:(CGRect)rect {
        [super drawRect:rect];
        
        CGPoint p1 = CGPointMake(185, 30);
        CGPoint p2 = CGPointMake(185, 70);
        CGPoint p3 = CGPointMake(185, 120);
        CGPoint p4 = CGPointMake(185, 170);
        
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
        CGContextSetLineWidth(context, 2.0);
        // p1 -> p4
        CGContextMoveToPoint(context, p1.x, p1.y);
        CGContextAddLineToPoint(context, p4.x, p4.y);
        CGContextStrokePath(context);
        // 画实心实体
        CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
        CGContextFillRect(context, CGRectMake(p1.x - 14 / 2.0, p2.y, 14, p3.y - p2.y));
    }
    

    然后将画K线的代码封装成一个方法,然后将最高价最低价开盘价收盘价等转换成坐标,通过传入四个参数就可以将K线点画出来,然后循环调用该方法就好,至于均线就是一个点一个点连接起来的,同样可以通过线段画出来,这里就不多说了,还有一个十字线,这个只要会画线段就会画十字线,这个也不多说了;

    之前看到别人的demo K线图可以左右滑动以及放大缩小,本来还以为是像ScrollView那样的,后来发现并不是这样,而是当手指滑动或者啮合的时候调用了- (void)drawRect:(CGRect)rect方法,而是又重新画上去了,因为调用比较频繁,所以看起来像是在滑动一样!在这里需要一个变量来控制绘制显示在视图上的第一个点,然后在通过K线点宽度以及K线点之间的间隔计算出该视图上能绘制会少个K线点,当手势滑动或者啮合的时候通过控制这个变量来控制要绘制的第一个点!这点复杂,但是不难,就不多说了!

    还需要一个变量来记录当前手指滑动所选择的K线点,然后在手指滑动的时候通过代理方法或者block将该点所对应的模型传过去,这样在外部就可以获取到当前用户所点击或者选择模型对应的数据,在外部就可以进行其他操作;

    接下来就是画文字,显示日期时间对应的价格日期等信息,画文字或者说画字符串更合理一点,用的是属性字符串NSMutableAttributedString废话不多说,上代码:

    - (void)drawRect:(CGRect)rect {
        [super drawRect:rect];
        NSString *str = @"我是要绘制的字符串";
        NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:str];
        // 设置字符串字体大小以及颜色
        [attributedStr setAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20], NSForegroundColorAttributeName:[UIColor greenColor]} range:NSMakeRange(0, str.length)];
        // 要绘制的区域
        CGRect strRect = CGRectMake(50, 80, attributedStr.size.width, attributedStr.size.height);
        // 给字符串添加一个弧形背景
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:strRect cornerRadius:attributedStr.size.height / 2.0];
        CGContextAddPath(context, path.CGPath);
        CGContextDrawPath(context, kCGPathEOFill);
        // 绘制
        [attributedStr drawInRect:strRect];
    }
    

    效果图:

    1E922BBD-804A-4EEE-8CE8-34B5E6F6E904.png

    这些掌握了之后就可以绘制专属自己的K线图了,其他的都是一些细节小问题,CGContextRef还有很多用法,有兴趣的自己可以找度娘,接下来附上我的最终的绘制结果:

    效果图.gif

    另外这个demo我已经封装好了,可以直接拿去使用,本来是想连那些指标什么的都绘制好的,因为自己对股票知识不了解,在加上公司把这部分功能给砍了,所有demo里边就没有绘制各项指标;

    Demo已上传github

    如果对你帮助就给个star吧!

    相关文章

      网友评论

      • 风火游龙:好东西啊,喜欢+评论 = 我的操作
      • 3d9894c18d05:你好,用你的框架打印台会输出,你的demo也会出现,请问是什么原因
        Jul 6 10:12:47 YBStockChartView[2147] <Error>: Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem.
        Jul 6 10:12:47 YBStockChartView[2147] <Error>: If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental variable.
        __阳阳:@jackAnd禅心 没有.............
        jackAnd禅心:@Hu1明 大神,这个有做横屏吗处理吗
        3d9894c18d05:找到原因了,如果没有数据就去绘制就会报这个错,判断一下就OK
      • JohnQ:我咋git上下载后点击查看的时候十字线纤细数据指数没有了
        __阳阳:@JohnQ 我现在在老家,我回去之后看看
      • JohnQ:博主 这个请求接口数据是你们公司测试数据还是 你在网上拔过来的
        __阳阳:@JohnQ 是我之前公司后台抓的新浪的数据
      • 雪_晟:大神,崩溃了 ,没有数据啊
        __阳阳:@雪_晟 我看了下, 因为新浪返回的数据不是json格式的数据, 所以获取到数据之后要进行处理,是我正则匹配有问题,最后的格式还是不对,所以解析不出来,数组数据是空的,所以会崩, 之前是没有问题的
        雪_晟:@__阳阳 我只保留了涨幅的数据才可以运行。 有没有周K的,我看到有分时,五天,日K
        __阳阳:把你的情况描述一下, 然后把代码发我邮箱, 我晚上回去看下 1135162587@qq.com
      • 爱生活爱康康:jiakang1004@163.com我最近正在研究绘制K线,想研究一下大神是如何绘制的。
        __阳阳:修复了两个问题, 代码已上传github
      • 顾泠轩:大神,求一份代码,非常感谢!
        邮箱:249166831qq.com
        顾泠轩:@__阳阳 收到了,非常感谢。对我这种菜得抠脚的渣渣而言,已经很厉害了:grin:
        __阳阳:已发送, 不过大神这两个字担当不起!

      本文标题:ios股票K线图的绘制

      本文链接:https://www.haomeiwen.com/subject/biiapttx.html