上篇文章中,我們了解了走勢圖k線圖繪制及的一些關鍵點,基于大家都懂期貨股票這些東西的基礎上去講解的,說的也不夠全面,這篇文章我們以實戰為主,一步一步寫出可以商業化的k線圖。
1.k線圖:有最新價、收盤價、開盤價、最高價、最低價、均價、賣量、買量等等。而我們需要展示給用戶看的第一眼就是把它們全部繪制為k線圖,直觀。還有部分要轉化為數值直接推動;
蠟燭:需要用到收盤價、開盤價、最高價、最低價;紅色是漲(國內),開盤價在上,收盤價在下;綠色是相反的;
這是一張沒有背景圖片的蠟燭圖 蠟燭demo的實現! 通過這篇文章,你可以繪制出商業用的各種組合走勢圖。。

均線:需要用到均價;5均線:比如有100個數據,5均線就是在第4點的時候拿到0-4的平均數繪制在第4點的位置,類推; 還有10 20 30均線等;
分時圖閃電圖:現價;
買量賣量持倉量:下面的那些柱子。
1.畫一條分時圖,具有拉動效果;十字光標,十字光標出現的時候數值的軸對應的分時圖數據要顯示在上方的詳情框里(聯動);縮放效果;橫屏效果;(閃電圖 分時圖 均線都是這樣做)
2.畫k線圖,也就是蠟燭圖;具有拉動效果;十字光標,十字光標出現的時候要把對應蠟燭的數據展現在詳情款里面(聯動);縮放;橫屏;(買量買量持倉量圖可以參考這個)
1.基本圖;
2.拉動效果;
3.十字光標,聯動數據(展示對應的蠟燭 分時);
4.縮放效果;
5.橫屏效果;
6.如果還有什么效果可以做的?;
1.我們的數據是以json數組形式推送過來的。所以我們要有一個數據類,數據轉model類,然后用這個model去和繪圖類做交互及展示; 當然商業用的不單單那么簡單,至少你還得加個統計類統計每分鐘的變化趨勢添加到這個model類里面轉化成為可用model,也就是60s內的直接替換最后一個蠟燭圖,60s過了,這個要把它加入這個蠟燭數據(也就是新增一個蠟燭)這里可以匹配每組數據推送過來的時間和數組的最后一個元素的時間差是否大于60s;后臺推送過來的數據都是那邊已經統計好的每分鐘數據;
我們這邊還有一個1 3 5 10 15 30 60 90 120分鐘的k線圖 這些k線圖就是要用這分鐘數組去計算得出對應的數組model;
2.API:
數據類:請求數據的類,緩存數據或者網絡數據;用delegate,當model類被釋放數據還沒落地的時候也可以及時釋放這個model類。
model類:填入一個合約名稱提交事務,把合約名稱交給數據類去獲取數據,把獲取完成的數據驗證解析后轉化為模型數組通過block遞交對應的請求類(比如給統計類(相當于MVVM的VM))
這些都是繪制k線圖需要的數據,除此之外還有其它需要展示給外界的數據(買賣價買賣量時間等)繪圖類:
demo沒有統計類,所以我們直接在vc里面把這些數據通過代理給繪圖類;此時我們的k線圖可以說是死k,不會有跳動效果;(我們的跳動效果在上文也有解析到,就是通過TCP推送的數據去替換或者新增蠟燭圖,優化看后文)
到了這個繪圖類;本文以k線圖為主,不考慮分時圖閃電圖均線;k線圖我們需要外界提供數據,這時候我們需要用到代理;我們需要向外界獲取顯示的個數、還有目前顯示的范圍;也需要告訴外界這個視圖即將刷新、以及這個十字光標滑動的時候這個y軸對應model是什么;所以現在我們需要給每一個繪圖類做動作規范的PRotocol為:
index會在下文講解到,indexpoint這個值是告訴外界現在手指到哪個地方了方便調整詳情框位置現在基礎的和外界交互的API已經確定下來了;我們可以開始繪圖了!
我們新建一個KLineView繼承于UIView(這樣做縮放滑動等效果可以直接操作所以不繼承CAShapeLayer);由上圖我們可以知道我們這個繪圖的搭配是CAShapelayer配合UIBezierPath;原因、優化的原理和一些關鍵點看上一篇文章;
我們定義這個類專屬的和外界交互的動作(并不定義改變類變動的動作);
如圖定義好這些對外操作后,我們開始實現邏輯。
我們先定義好每一個蠟燭圖的寬度 間隔 和每一次的偏移量

2:建立私有屬性(相對私有)記錄好每一個數據 顏色 控件

3.初始化這些屬性

- (void)reload:
獲取展示數據的最大值 刷新展示框的width、heighe
重新設置縮放比例x_scale
計算能容納多少個蠟燭count
//計算現在是從哪一個下標開始取 總個數減去顯示的個數
NSInteger index = self.ShowArrayMaxCount - _count;
self.OffsetIndex = index;//初始化偏移位置
因為插入圖片之后變得非常卡沒法打字 所以不插入代碼了 我會把代碼放在GitHub里面; 大家可以提交優化版本!
方法介紹(包含以上除了橫屏外的所有效果實現)
- (void)offset_xPoint方法:
如果point.x >0 減去偏移量 顯示之前的數據 為0的時候顯示self.OffsetIndex開始的數據 否則顯示之后的數據。
- (void)CalculationHeightAndLowerFromArray:(NSArray:) ;
//遍歷獲取顯示數據的最高最低值
- (void)CalculationH;
//計算self.h每個點代表的值是多少
- (void)CalculationShowPointFromLastPrices:(NSArray <KlineModel *>*)array
//繪制所有蠟燭圖通過代理獲取到的model數據的蠟燭圖
- (void)replacementLastPoint:(KlineModel *)model
//替換最后一個點 邏輯是刪除self.ShapeLayer的最后一個視圖 再通過model生成這個位置對應的蠟燭圖 添加到父layer
- (CAShapeLayer *)GetShapeLayerFromModel:(KlineModel *)model Index:(NSInteger)idx
//通過model和對應下標生成蠟燭圖 添加到父視圖中
- (void)offset_xPoint:(CGPoint)point
//滑動效果 改變OffsetIndex的值 刷新數據
- (void)pinchAction:(UipinchGestureRecognizer *)pinch
//縮放效果 改變x_scale的值 刷新數據
- (void)panGesture:(UIPanGestureRecognizer *)pan
//通過self.isShowTrackingCross判斷是否顯示十字光標 否則拉動新的數據
- (void)TrackingCrossFromPoint:(CGPoint)point
//十字光標 通過point逆推得出index 現在的下標/(單元大小)*縮放量
//獲取point.x坐標 和這個model的最新價或者其它價格對應的y 這里展示最新價
//把model通過@selector(TrackingCrossIndexModel:IndexPoint:)傳遞給外界 繪制當前路徑
- (void)setShowTrackingCross:(BOOL)ShowTrackingCross
重寫set方法判斷是否隱藏十字光標
橫屏效果
在監控到屏幕轉動的時候重新設置frame 調用reload就好了。 里面暫時沒做任何處理.
其它細節請參考理論篇 請找茬 共同進步!!
demo鏈接:https://github.com/454961172/KlineDemo
原文鏈接:http://www.jianshu.com/p/f37ab1e73006
作者:不留名的黃子嘉
新聞熱點
疑難解答