ios股票K线图的绘制

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 一、什么是K线图 1、K线图的定义: K线(Candlestick chart)又称“阴阳烛”,是反映价格走势的一...
    夏天的风_song阅读 4,125评论 3 7
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 十月一号的时候,朋友给我打电话说,她开通了公众号,想发我的文章。还有一个朋友不停的问我什么时候不忙,和他一起做自媒...
    新言旧序阅读 166评论 0 0
  • 生活中有些观念,有些事情真的很重要,但它们常常被我们错过! 重新升级“错过”这个观念,主要有以下两个方面: 1、分...
    新小派自由行走的花阅读 117评论 0 0
  • 佛家的因果论讲的也是这个道理,你种了什么因,就会结什么样的果。这个世界没有后悔药可以买。有一句民间的说法叫“凡人...
    精神灿烂阅读 10,473评论 0 0