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

推薦閱讀更多精彩內容

  • 一、什么是K線圖 1、K線圖的定義: K線(Candlestick chart)又稱“陰陽燭”,是反映價格走勢的一...
    夏天的風_song閱讀 4,272評論 3 7
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,702評論 25 708
  • 十月一號的時候,朋友給我打電話說,她開通了公眾號,想發我的文章。還有一個朋友不停的問我什么時候不忙,和他一起做自媒...
    新言舊序閱讀 185評論 0 0
  • 生活中有些觀念,有些事情真的很重要,但它們常常被我們錯過! 重新升級“錯過”這個觀念,主要有以下兩個方面: 1、分...
    新小派自由行走的花閱讀 140評論 0 0
  • 佛家的因果論講的也是這個道理,你種了什么因,就會結什么樣的果。這個世界沒有后悔藥可以買。有一句民間的說法叫“凡人...
    精神燦爛閱讀 10,702評論 0 0