ios股票K线图的绘制

来源:互联网 发布:人工智能硬件解决方案 编辑:程序博客网 时间:2024/05/01 01:50

  前言:因为工作需要,要绘制一个股票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吧!

原创粉丝点击