從零開始實現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閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,806評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,180評論 4 61
  • 之前看過好幾篇文章介紹斷點的方式設置reveal好處以及方式,但是多多少少有點問題,今天仔細看了下官方文檔介紹方式...
    漫步在銀河畔閱讀 355評論 0 0
  • 《明珠幻夢》——藍風 心,是顆掌心明珠,曾萬般呵護 不知某天,又是誰,在我心埋下種子 滴血澆灌,合掌作傘,以為是愛...
    是藍風吖閱讀 111評論 0 0
  • 當她向我撲過來的時候,我在想是不是親親她。 哥頓什么都不知道,她怒氣沖沖的如是告訴她所有朋友。 天上還飄著雪,記得...
    丹波的悍匪們閱讀 364評論 0 1