ios股票K線圖的繪製

weixin_34208283發表於2017-01-06

前言:因為工作需要,要繪製一個股票K線圖,因為自己不炒股,所以對股票知識很是有限,當時也想在網上找個demo直接拿來用的,但是找了很多都不合適,後來查了些資料,也看了很多別人的demo,打算自己寫,此文針對不會畫直線畫文字的新手, 沒有考慮優化問題! 大神請略過 !

因為自己當時對股票知識很是有限, 所以這裡就從最基礎說起, 首先看一下K線圖解, 瞭解一下一個K線點所需要的資料:


2887144-a966f3b96ab6be43.gif
圖片來自網路.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線點常見的有兩種, 一種是空心的一種是實心的,我們先來畫一個空心的,空心的分解一下就是兩條線段加上一個矩形邊框,只需要四個點就可以畫出來,如下圖:

2887144-234840fc5c19ca11.png
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,然後在中間在畫實體就好了下邊是效果圖:


2887144-7812298876cb9854.png
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];
}

效果圖:

2887144-f170f03992388e77.png
1E922BBD-804A-4EEE-8CE8-34B5E6F6E904.png

這些掌握了之後就可以繪製專屬自己的K線圖了,其他的都是一些細節小問題,CGContextRef還有很多用法,有興趣的自己可以找度娘,接下來附上我的最終的繪製結果:

2887144-6f2410310de3f681.gif
效果圖.gif

另外這個demo我已經封裝好了,可以直接拿去使用,本來是想連那些指標什麼的都繪製好的,因為自己對股票知識不瞭解,在加上公司把這部分功能給砍了,所有demo裡邊就沒有繪製各項指標;

Demo已上傳github

如果對你幫助就給個star吧!

相關文章