从零开始实现k线图走势图绘制(iOS理论篇)

       前言:现在做金融的越来越多了,在很多的技术群中都有人问到k线图怎么去做,有没有相关的框架?两年前,我刚入这金融公司也是走这条路,但是发现网上的框架不多,干脆就自己搞一个出来。没人分享相关知识,就分享下绘图心得好了,大家一起探讨优化。

一、理论知识

1.用什么去绘制k线图?

       在移动端、前端这边,绘图从来都不是什么大事,包括接下来的小程序。大多数都是把相关的东西提交给系统去做!所以不要怕绘图!在iOS中,我们经常会用到CoreGraphics上下文渲染,或者用CAShapelayer配合UIBezierPath去做。当然,本文不是教你怎么用API,我不会去侮辱程序员的。。

卡顿:CPU计算的内容太多 来不及提交新的东西给GPU渲染显示 它还是弄旧的.. 

UIBezierPath:绘制路径的,绘制出来的路径可以给上下文环境(drawrect系列方法)渲染或者CAShapelayer渲染。上下文环境对资源的消耗较大 一不小心就离屏渲染或者各种内存问题(我也是听来的 实际上使用貌似没多大消耗 不知道是不是苹果改了还是我用对API了)上下文语法不熟悉的也得看一会才能好好用,所以我们介绍CAShapelayer为主.

2.坐标系?

iOS的坐标系由上往下,左往右,这大家都懂。。但是我要说的是走势图的坐标系!!

绘图我们肯定要知道x,y坐标,我们在外部传入这个view的位置大小之后,我们的x坐标就基本确定下来了。比如我用width:320,那么我们可以确定320个,当然这个可以按照需求。一般我走势图数据量大的股票期货都会默认为1,其它的大于一,当然,这是可以缩放的。

y坐标:这个试图的高我们一定确定好了。我们现在是要知道这个高每一点代表的值是多少?比如我现在这个股票,最高点40,最低点30,现价32,高度100,那么我们每一点代表0.1,然后这个是第一个数据,所以它的对应坐标是(0,20)? 呵呵,答错了!虽然是这个没错,但是我们看盘的时候是从下往上看的嘛,所以它应该是(0,80)的位置(下方往上为20);

3.耗电耗性能?

一开始我们的版本是用上下文去渲染显示的,但是由于考虑不周,被用户投诉耗电耗流量非常多。然后就开始操刀优化了。

说点无关的:首先解决的事耗流量的问题。我们的数据都是用TCP去推送的,由于之前的某些原因,数据的组合格式过于浪费,后来改为按需拉取,于是就解决了。==! TCP是个好东西,即时性高,能主动推送数据不丢包,应用在前台还能绕过APNS,微信的聊天貌似也用TCP+Http。当然即时性不高的可以用轮询+设置超时90s..你懂的!

那耗电量是什么回事?

我们知道iOS耗电高的 就是不断的循环操作、CPU GPU转啊转。。 知道这些就好办了,优化算法减少计算量,用enumerateObjectsUsingBlock取代forin。。当然这些你肯定知道的!但是要解决这个耗电量得知道它还有什么业务操作才行。。 由于期货股票这东西有时候拨动的非常快,一秒几次,可能这时候我们已经有上千点数据准备去画了,一秒算三次,那么CPU过的非常充实哦? 我们当然不可以这么做。。

那么如何去优化它?

我们都知道,iOS的view都是使用组合模式的,基类的写好公用的(大概就是模板模式那理论啦),然后继承这个类,然后addSubview..remove..,那么我们可以从中得到什么信息? 那就是分层。。 这也告诉了我们 研究系统API的设计 规范化开发是多么重要..(至少会减少逻辑bug),顺便带一句,我和别人聊天的时候都会问block和delegate的应用场景。。 大部分人都局限于传值..这貌似是培训班的套路?? 看看第三方框架或者分析系统框架?

那我们知道这些东西我们差不多可以开始动工了。

我们知道要做好绘制好走视图,需要分层,那怎么分? 单一职责帮助你。

说一说我们的需求。

1.显示走势图(废话)

2.拉动显示其它数据

3.十字光标滑动的时候 出现左边或者右边的对应的点或者蜡烛的详情(开收盘等) 也有些公司会用点击某根蜡烛弹出详情

4.缩放功能。 暂时就这么多了 我也不知道还要示范些啥?

二、动工

1.确定好需要外界提供什么材料?

想想就有点小激动了。。 外界? 当然是委托别人去做的啦。。 先写好一个协议。我看那个蜡烛图怎么和collectionView那么像啊? 那我的API也和它差不多就好啦。 好,确定好我需要外界给我东西,就是显示的个数,还有现在显示的范围。。

设计API 就是要简单粗暴。。 太难用了自己都不想用啦!

我们知道,现在是在实现基础的走视图 不包含其它的

简单些:-(NSInteger)numberOfView:(UIView *)view;

              - (KlineModel *)LineView:(UIView *)view cellAtIndex:(NSInteger)index;

那我们怎么确定index数据?

我们已经获取到了这个视图的宽度了,这时候分情况。1.分时图:自定义或者默认1;2:k线图,我们先在上方写好:

static const NSInteger KlineCellSpacing = 2;//cell间隔

static const NSInteger KlineCellWidth = 6;//cell宽度

static const NSInteger CellOffset = 1;//偏移的单位


这个时候,我们已经清楚的知道 宽度为6 间隔为2,那么一个单位就是8.. 我有320,那就能画40个咯? 假设代理给我的个数是1200 那我只需要拿1161-1200。 那就回调它 开始获取数据制作k线图了。

当然,这也是需要分两种情况的,分时图太简单了 就是一条线,那我们拿k线图来说。 制作原理一样。

2.开始绘图

绘制基础显示图

假设这个时候 我们已经拿到40个数据了。我们先遍历它,获得最高最低点,获得每个点代表的值,当然我们要在外面写好willXXX等方法告诉外面 我们知道这个最高价最低价是多少了,顺便放出这两个只读属性(业务需求)。这个时候 我们有两种数据类型,一种是永远不变的(至少没突破最高最低值的时候不会变),一种是会变动的。每次Socket推送过来的数据我们都要及时的更新为视图。那我们开始分层了!

先新建一个CAShapelayer属性Shapelayer,把刚刚的所有数据通过UIBezierPath 转化为路径 加载在它这边,多个CAShapelayer都加载在这里面。CAShapelayer也是组合模式的。add就好了 设置好每一个的颜色各种形 一个一个加。(这里说的是k线图 曲线图就一个好了 我也是取巧的方法 = =!)

 如果直接加载在这个Shapelayer属性,这里就有个问题了..颜色怎么办?这个是很重要的,毕竟涨跌一个点都要钱啊。。之前我有尝试过用渐变去给一个CAShapelayer染色,但是..惨不忍睹、不忍再提。。 不过还好 对性能没影响,估计是底层苹果把它给合并的吧?这个需要点时间去研究...但是最近又有新项目了 貌似还有接到一个外包?? 这两个问题希望大神能赐教 感激不尽。

跑调了啊 =。=

好吧。画完上面的东西了,我们开始画变的那一层。先定好API 确保API容易用(容不容易去跑下单元测试),这个API传入一个model。 这个时候 我们已经有个Shapelayer,我们拿到它的sublayer数组 删掉最后一个。我们已经有每点代表的值了,直接转化显示就好了。但是,我们不确保它的值不会我们的最高最低值。那我们比较一下,如果超越了,那就替换刚刚获得的数组最后一个model 然后调用刚刚的计算方法 从那一步开始重新走一遍,重新计算。这个过程就要看你的API设计的是不是职责单一了。 = =!封装好每一个关联的面向过程实现吧?

基础绘图的介绍就到这里好了。接下来是拉动效果!

拉动移动显示其它数据

这个也没什么好说的。我们继承的是view对吧? 加个手势或者截取响应链。我这边是用手势!刚刚上面我们已经有一个CellOffset的常量了。在手势中通过translationInView获取的x正负判断方向 加减我们的OffsetIndex(一开始是从1161开始 看上文)。然后移动以后 判断它是不是合法下标 重新获取数据 继续调用计算方法 走流程 。= =! 问题:我一直在想,要保持好这些绘图对象像CollectionView那样子 还是直接重新绘制比较省资源。。 这点还是可以继续优化的。

滑动的时候 联动左边或者右边的对应的点或者蜡烛的详情(开收盘等)

这个时候 我们需要新建一个ShowTrackingCross,让外界控制是否显示十字光标,还是拉动显示其它数据.. 这个时候 我们可以封装一个CALayer类 把触摸点传进一个方法里面 逆推得出对应数组的index而得到model,计算最新价的y 就可以得出这个点。在代理里面写个可选实现方法把它传递出去并绘制这个十字光标,再写个关闭十字光标的方法让使用者或者自己可以把它移除。

缩放功能

= 。=  定义好scale属性,初始化为1。在计算的时候参与x,width的计算。在缩放手势的时候改变它的大小。。 这里要注意在计算显示的个数也是要参与计算的= =!

其它细节

旋转屏幕等操作需要注意重新setFrame。均线 等其它的也是分层好了,闪电图直接画? 暂时就先到这里了 大致的说一遍。这几天整理个demo再从实现说起应该比较好说一点!下次还要探讨socket等网络编程。希望各位大神指出存在的逻辑繁琐问题 bug 优化。只是demo 求大神带上开发对应组件! 跪谢。

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,793评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,066评论 4 62
  • 之前看过好几篇文章介绍断点的方式设置reveal好处以及方式,但是多多少少有点问题,今天仔细看了下官方文档介绍方式...
    漫步在银河畔阅读 341评论 0 0
  • 《明珠幻梦》——蓝风 心,是颗掌心明珠,曾万般呵护 不知某天,又是谁,在我心埋下种子 滴血浇灌,合掌作伞,以为是爱...
    是蓝风吖阅读 105评论 0 0
  • 当她向我扑过来的时候,我在想是不是亲亲她。 哥顿什么都不知道,她怒气冲冲的如是告诉她所有朋友。 天上还飘着雪,记得...
    丹波的悍匪们阅读 361评论 0 1