CorePlot學習

閱讀這篇國外文章手記而已    原文地址: https://github.com/core-plot/core-plot/wiki/High-Level-Design-Overview css

首先,咱們先看一下咱們繪製圖表是的區域劃分: git

這個圖標的學習頗有必要,在之後的編程中,你會有深入體會,各個區域的劃分,和名稱 程序員

2 再來看看這個CorePlot開源圖形庫的類的層次結構 ,便於咱們源碼的理解 github

3  再來看一下他的成員對象和各個層的樹形結構 編程

4 圖表視圖的動畫層分析 xcode

UIView的核心動畫層,CALayer並不適合產生高質量的矢量圖形,而且它也不支持事件處理,所以,Core Plot layers繼承於 CPTLayer ,而 CPTLayer 是CALayer的子類,只不過作了擴展。 CPTLayer 包含繪圖方法,能夠繪製高質量的矢量圖形,而且可以處理事件 app

繪圖方法包括以下: 框架

-(void)renderAsVectorInContext:(CGContextRef)context;  -(void)recursivelyRenderInContext:(CGContextRef)context;  -(NSData *)dataForPDFRepresentationOfLayer;
當咱們繪製矢量圖形時,就不用重寫(override)- drawInContext :方法,而是隻需重寫- renderAsVectorInContext :方法便可把圖形會知道窗口。

ide

Graphs 分析

CPTGraph 是Core Plot的核心類,在coreplot中graph就是整個圖表,包括:座標軸,標籤,標題,以及多個圖表元素。 函數

看一下該類的定義:

@interface CPTGraph : CPTBorderedLayer  @property (nonatomic, readwrite, copy) NSString *title; //標題  @property (nonatomic, readwrite, copy) CPTTextStyle *titleTextStyle; //標題文本格式  @property (nonatomic, readwrite, assign) CGPoint titleDisplacement; //標題位置  @property (nonatomic, readwrite, assign) CPTRectAnchor titlePlotAreaFrameAnchor; //我目前認爲是PlotArea的原點  @property (nonatomic, readwrite, retain) CPTAxisSet *axisSet; //座標軸設置  @property (nonatomic, readwrite, retain) CPTPlotAreaFrame *plotAreaFrame; //PlotArea的fram  @property (nonatomic, readonly, retain) CPTPlotSpace *defaultPlotSpace; //還沒理解  @property (nonatomic, readwrite, retain) NSArray *topDownLayerOrder; //  @property (nonatomic, readwrite, retain) CPTLegend *legend;  @property (nonatomic, readwrite, assign) CPTRectAnchor legendAnchor;  @property (nonatomic, readwrite, assign) CGPoint legendDisplacement;  -(void)reloadData;  -(void)reloadDataIfNeeded;  -(NSArray *)allPlots;  -(CPTPlot *)plotAtIndex:(NSUInteger)index;  -(CPTPlot *)plotWithIdentifier:(id <NSCopying>)identifier;  -(void)addPlot:(CPTPlot *)plot;  -(void)addPlot:(CPTPlot *)plot toPlotSpace:(CPTPlotSpace *)space;  -(void)removePlot:(CPTPlot *)plot;  -(void)removePlotWithIdentifier:(id <NSCopying>)identifier;  -(void)insertPlot:(CPTPlot *)plot atIndex:(NSUInteger)index;  -(void)insertPlot:(CPTPlot *)plot atIndex:(NSUInteger)index intoPlotSpace:(CPTPlotSpace *)space;  -(NSArray *)allPlotSpaces;  -(CPTPlotSpace *)plotSpaceAtIndex:(NSUInteger)index;  -(CPTPlotSpace *)plotSpaceWithIdentifier:(id <NSCopying>)identifier;  -(void)addPlotSpace:(CPTPlotSpace *)space;  -(void)removePlotSpace:(CPTPlotSpace *)plotSpace;  -(void)applyTheme:(CPTTheme *)theme; @end
the CPTXYGraph  creates an instance of CPTXYAxisSet  , andCPTXYPlotSpace

6 Plot Area

這個事咱們圖表顯示的區域,該區域被座標軸限制在必定方位內,能夠顯示柵格在該區域,每一個圖表視圖只能有一個圖標區域,

7 Plot Spaces

我這裏想稱Plot space爲圖表元素原型,好比說柱狀圖,他有更多個柱元素組成,其中的一個就是元素原型。這時我的理解

而Plot Spaces就是元素原型和座標系的映射關係集合,

一個PLot space 元素原型會知道圖表上,必需要實現如下方法:完成數據和座標空間的轉換

-(CGPoint)plotAreaViewPointForPlotPoint:(NSDecimal *)plotPoint;  
-(CGPoint)plotAreaViewPointForDoublePrecisionPlotPoint:(double *)plotPoint;  
-(void)plotPoint:(NSDecimal *)plotPoint forPlotAreaViewPoint:(CGPoint)point;  
-(void)doublePrecisionPlotPoint:(double *)plotPoint forPlotAreaViewPoint:(CGPoint)point;
一個graph能夠包含多個原型單元的,只不過咱們通常經常使用地就是一個而已。

8 Plots

Plot就是一個數據在圖表中的表現形式,好比條形,柱狀型等,

CPTPlot的dataSource 方法

@protocol CPTPlotDataSource <NSObject> -(NSUInteger)numberOfRecords; @optional // Implement one of the following -(NSArray *)numbersForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndexRange:(NSRange)indexRange;  
-(NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index; @end

9 Axes

座標軸

CPTAxis      和 CPTPlotSpace 有密切關係, CPTXYAxisSet 包含多個CPTAxis , CPTAxis 中的標籤元素能夠自定義的。


Core Plot和s7Graph都是可在iOS平臺下使用的開源矢量圖形庫,s7Graph功能相對比較簡單一些,在此就不介紹了。Core Plot 功能強大不少,咱們能夠利用它很方便地畫出複雜的曲線圖、柱狀圖和餅圖等等。下面我先來介紹如何在項目中配置使用 Core Plot 庫,而後經過一個曲線圖示例來演示如何使用它,最後結合示例介紹 Core Plot 的框架結構。

本文源代碼:https://github.com/kesalin/iOSSnippet/tree/master/CorePlotDemo

效果圖:

 

二,在iOS工程中配置 Core Plot

1,下載 Core Plot 庫

Core Plot 代碼倉庫託管在 Google Code 上,可經過 https://code.google.com/p/core-plot/ 獲取最新的庫和源碼(目前爲1.1),在這裏咱們只關心 iOS平臺:

解壓 CorePlot_1.1.zip,其目錄結構以下:

若是經過靜態連接方式引用CorePlot庫,那麼咱們只須要關心Binaries/iOS目錄便可,可是做爲一個喜歡鑽研的程序員,Documentation和Source下面想必你也不會視而不見;若是經過引入工程文件方式引用CorePlot庫,那麼咱們須要引用Source/framework/CorePlot-CocoaTouch.xcodeproj。注意:CorePlot同時支持OS X 和 iOS 平臺,CorePlot.xcodeproj 是OS X平臺工程。此外,Source/examples 下的大量示例代碼絕對是不可忽視的第一手參考資料。

順便吐槽一句,iOS平臺的開源庫不少,也會強大,但一如 iOS 系統自身,向後兼容性太差,用過Cocos 2D等庫的童鞋應該深有體會。CorePlot也不例外,之前用0.4版本的時候,類名前綴市 CP,如今都修改成 CPT(CorePlot-Touch)了。

2,在工程中添加 Core Plot 庫

下面,我將介紹如何用靜態連接方式引用 CorePlot 庫

a),新建 CorePlotDemo SingleView 工程,拷貝 Binaries/iOS 目錄到項目目錄下,並重命名 iOS 爲 CorePlotLib,如圖所示:

b) 在工程中經過添加已存在文件將 CorePlotHeaders  目錄下的文件所有添加,並連接 libCorePlotTouch.a 靜態庫。如圖所示:

c) 由於CorePlot使用到 QuartzCore 庫,因此咱們還須要鏈接 QuartzCore.framework。此外爲了讓 XCode 裝載導入頭文件,須要設置編譯環境,在 build setting 中查找 other linker flags,添加 '-all_load -ObjC' 標誌。至此設置工做完成。

 

三,使用 Core Plot 描繪曲線圖

1,Core Plot 要求它進行描繪的所在 view 類型必須爲 CPTGraphHostingView 類型,因此在這裏,我將設置 ViewController.nib 中 View 的類型爲 CPTGraphHostingView。如圖所示:

2,修改 KSViewController.h 爲:

#import <UIKit/UIKit.h> #import "CorePlot-CocoaTouch.h" @interface KSViewController : UIViewController<CPTPlotDataSource, CPTAxisDelegate> @end

若是你用過 NSTableView,那你應該很熟悉 CPTPlotDataSource 這種形式協議的用法, CPTPlotDataSource 爲 CorePlot 提供數據源。在這裏我還實現了 CPTAxisDelegate 協議,當咱們想要對軸刻度的標籤進行必定的定製時,須要實現該協議。在本例中,要用不一樣的顏色對 y 軸方向大於等於0和小於0的刻度標籤進行區分,所以須要實現該協議。

3,聲明私有成員和方法

請參考文件:https://github.com/kesalin/iOSSnippet/blob/master/CorePlotDemo/CorePlotDemo/KSViewController.m

@interface KSViewController ()
{
    CPTXYGraph * _graph;
    NSMutableArray * _dataForPlot;
}

- (void)setupCoreplotViews;

-(CPTPlotRange *)CPTPlotRangeFromFloat:(float)location length:(float)length; @end

在本例中,要描繪基於 xy 軸的圖形,所以,聲明瞭 CPTXYGraph 對象 _graph,而後聲明一個可變數字 _dataForPlot 爲 Core Plot 提供數據。私有方法 setupCoreplotView 是本例的重點,全部的描繪設置都在這個函數中進行。CPTPlotRangeFromFloat:length:是一個輔助類以簡化 CPTPlotRange 的建立,其實現以下:

-(CPTPlotRange *)CPTPlotRangeFromFloat:(float)location length:(float)length
{ return [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(location) length:CPTDecimalFromFloat(length)];
}

爲了支持旋轉操做,添加以下代碼(注意,本文只考慮了 iOS6 的旋轉,這又是 iOS 兼容性不太好的一大明證啊!):

#pragma mark - #pragma mark Rotation

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{ return YES;
}

-(BOOL)shouldAutorotate
{ return YES;
}

4,實現 setupCoreplotViews

先來看效果說明圖,此圖很是重要,CorePlot常見的概念都在圖中有說明,後文會屢次引用到該圖。

下面,來介紹重點內容,如何使用 CorePlot 對數據進行描繪。

- (void)setupCoreplotViews
{
    CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle]; // Create graph from theme: 設置主題 //  _graph = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
    CPTTheme * theme = [CPTTheme themeNamed:kCPTSlateTheme];
    [_graph applyTheme:theme];
    
    CPTGraphHostingView * hostingView = (CPTGraphHostingView *)self.view;
    hostingView.collapsesLayers = NO; // Setting to YES reduces GPU memory usage, but can slow drawing/scrolling hostingView.hostedGraph = _graph;
    
    _graph.paddingLeft = _graph.paddingRight = 10.0;
    _graph.paddingTop = _graph.paddingBottom = 10.0;

a)首先,建立了一個可編輯的線條風格 lineStyle,用來描述描繪線條的寬度,顏色和樣式等,這個 lineStyle 會被屢次用到。

而後,建立基於 xy 軸的圖:CPTXYGraph,並設置其主題 CPTTheme,CorePlot 中的主題和平常軟件中的換膚概念差很少。目前支持五種主題:kCPTDarkGradientTheme, kCPTPlainBlackTheme, kCPTPlainWhiteTheme, kCPTSlateTheme,kCPTStocksTheme, 最後一種股票主題效果見上面的效果圖,而石板色主題 kCPTSlateTheme 效果見下面的效果圖。你能夠修改此處的代碼嘗試不一樣的主題效果,^_^。將 hostingView的 hostedGraph與 _graph 關聯起來,也就是說:咱們要在 View (CPTGraphHostingView)上畫一個基於xy軸的圖(CPTXYGraph)。至此,咱們接觸到CorePlot中的兩個概念:宿主view 和圖graph。而後咱們設置_graph的 padding,這樣在圖的四周與屏幕邊緣之間留有一絲空隙。

// Setup plot space: 設置一屏內可顯示的x,y量度範圍 //  CPTXYPlotSpace * plotSpace = (CPTXYPlotSpace *)_graph.defaultPlotSpace;
    plotSpace.allowsUserInteraction = YES;
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(1.0) length:CPTDecimalFromFloat(2.0)];
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(1.0) length:CPTDecimalFromFloat(3.0)];

上面的代碼設置PlotSpace,這是什麼意思呢?x,y二維空間能夠無限延伸,但在屏幕上咱們能夠看到的只是一小部分空間,這部分可視空間就由 Plot Space設置。CPTXYPlotSpace 的 xRange 和 yRange 就設置了一屏內可顯示的x,y方向的量度範圍。在這裏,咱們設置x,y軸上的起點都是1.0,而後長度分別爲2個和3個單位。請結合上面的說明圖理解 PlotSpace 的含義。(注意:說明圖中的起點不是1.0,這是由於設置了 allowsUserInteraction 爲 YES,我對PlotSpace進行了拖動所致使的)。

// Axes: 設置x,y軸屬性,如原點,量度間隔,標籤,刻度,顏色等 //  CPTXYAxisSet *axisSet = (CPTXYAxisSet *)_graph.axisSet;
    
    lineStyle.miterLimit = 1.0f;
    lineStyle.lineWidth = 2.0;
    lineStyle.lineColor = [CPTColor whiteColor];
    
    CPTXYAxis * x = axisSet.xAxis;
    x.orthogonalCoordinateDecimal = CPTDecimalFromString(@"2"); // 原點的 x 位置 x.majorIntervalLength = CPTDecimalFromString(@"0.5"); // x軸主刻度:顯示數字標籤的量度間隔 x.minorTicksPerInterval = 2; // x軸細分刻度:每個主刻度範圍內顯示細分刻度的個數 x.minorTickLineStyle = lineStyle; // 須要排除的不顯示數字的主刻度 NSArray * exclusionRanges = [NSArray arrayWithObjects:
                                 [self CPTPlotRangeFromFloat:0.99 length:0.02],
                                 [self CPTPlotRangeFromFloat:2.99 length:0.02],
                                 nil];
    x.labelExclusionRanges = exclusionRanges;

b), 有了 xy 軸圖對象,咱們能夠來對 xy 軸的顯示屬性進行設置了。經過獲取 XYGraph 的 axisSet 來獲取軸的集合,集合中就包含了 x,y 軸對象 CPTXYAxis。在這裏,設置 x 軸的原點爲 2,主刻度的量度間隔爲 0.5,每個主刻度內顯示細分刻度的個數爲 2 個,並用白色寬度爲2的線條來描繪 x 軸。若是有一些刻度的標籤咱們不想讓它顯示那該如何呢?很簡單,設置軸的排除標籤範圍 labelExclusionRanges 便可。

一樣,咱們設置 y 軸的顯示屬性:

CPTXYAxis * y = axisSet.yAxis;
    y.orthogonalCoordinateDecimal = CPTDecimalFromString(@"2"); // 原點的 y 位置 y.majorIntervalLength = CPTDecimalFromString(@"0.5"); // y軸主刻度:顯示數字標籤的量度間隔 y.minorTicksPerInterval = 4; // y軸細分刻度:每個主刻度範圍內顯示細分刻度的個數 y.minorTickLineStyle = lineStyle;
    exclusionRanges = [NSArray arrayWithObjects:
                       [self CPTPlotRangeFromFloat:1.99 length:0.02],
                       [self CPTPlotRangeFromFloat:2.99 length:0.02],
                       nil];
    y.labelExclusionRanges = exclusionRanges; y.delegate = self;

請參考說明圖理解上面軸設置的含義。注意,在這裏,我設置了 y 軸的 delegate 爲自身,這個 delegate 須要實現CPTAxisDelegate 協議,在這裏我想要用不一樣的顏色對 y 軸方向大於等於0和小於0的刻度標籤進行區分,所以須要實現該協議方法:axis:shouldUpdateAxisLabelsAtLocations:。

#pragma mark - #pragma mark Axis Delegate Methods

-(BOOL)axis:(CPTAxis *)axis shouldUpdateAxisLabelsAtLocations:(NSSet *)locations
{ static CPTTextStyle * positiveStyle = nil; static CPTTextStyle * negativeStyle = nil;
    
    NSNumberFormatter * formatter   = axis.labelFormatter;
    CGFloat labelOffset             = axis.labelOffset;
    NSDecimalNumber * zero          = [NSDecimalNumber zero];
    
    NSMutableSet * newLabels        = [NSMutableSet set]; for (NSDecimalNumber * tickLocation in locations) {
        CPTTextStyle *theLabelTextStyle; if ([tickLocation isGreaterThanOrEqualTo:zero]) { if (!positiveStyle) {
                CPTMutableTextStyle * newStyle = [axis.labelTextStyle mutableCopy];
                newStyle.color = [CPTColor greenColor];
                positiveStyle  = newStyle;
            }

            theLabelTextStyle = positiveStyle;
        } else { if (!negativeStyle) {
                CPTMutableTextStyle * newStyle = [axis.labelTextStyle mutableCopy];
                newStyle.color = [CPTColor redColor];
                negativeStyle  = newStyle;
            }
    
            theLabelTextStyle = negativeStyle;
        }
        
        NSString * labelString      = [formatter stringForObjectValue:tickLocation];
        CPTTextLayer * newLabelLayer= [[CPTTextLayer alloc] initWithText:labelString style:theLabelTextStyle];
        
        CPTAxisLabel * newLabel     = [[CPTAxisLabel alloc] initWithContentLayer:newLabelLayer];
        newLabel.tickLocation       = tickLocation.decimalValue;
        newLabel.offset             = labelOffset;
        
        [newLabels addObject:newLabel];
    }
    
    axis.axisLabels = newLabels; return NO;
}

在上面的代碼中,對於 y 軸上大於等於0的刻度標籤用綠色描繪,而小於0的刻度標籤用紅色描繪。由於在這裏咱們本身設置了軸標籤的描繪,因此這個方法返回 NO 告訴系統不須要使用系統的標籤描繪設置了。其效果以下:

至此,xy軸部分的描繪設置完成。

c) 下面咱們向圖中添加曲線的描繪:

// Create a red-blue plot area //  lineStyle.miterLimit        = 1.0f;
    lineStyle.lineWidth         = 3.0f;
    lineStyle.lineColor         = [CPTColor blueColor];
    
    CPTScatterPlot * boundLinePlot  = [[CPTScatterPlot alloc] init];
    boundLinePlot.dataLineStyle = lineStyle;
    boundLinePlot.identifier    = BLUE_PLOT_IDENTIFIER;
    boundLinePlot.dataSource    = self; // Do a red-blue gradient: 漸變色區域 //  CPTColor * blueColor        = [CPTColor colorWithComponentRed:0.3 green:0.3 blue:1.0 alpha:0.8];
    CPTColor * redColor         = [CPTColor colorWithComponentRed:1.0 green:0.3 blue:0.3 alpha:0.8];
    CPTGradient * areaGradient1 = [CPTGradient gradientWithBeginningColor:blueColor
                                                              endingColor:redColor];
    areaGradient1.angle = -90.0f;
    CPTFill * areaGradientFill  = [CPTFill fillWithGradient:areaGradient1]; boundLinePlot.areaFill = areaGradientFill; boundLinePlot.areaBaseValue = [[NSDecimalNumber numberWithFloat:1.0] decimalValue]; // 漸變色的起點位置 // Add plot symbols: 表示數值的符號的形狀 //  CPTMutableLineStyle * symbolLineStyle = [CPTMutableLineStyle lineStyle];
    symbolLineStyle.lineColor = [CPTColor blackColor];
    symbolLineStyle.lineWidth = 2.0;
    
    CPTPlotSymbol * plotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
    plotSymbol.fill          = [CPTFill fillWithColor:[CPTColor blueColor]];
    plotSymbol.lineStyle     = symbolLineStyle;
    plotSymbol.size          = CGSizeMake(10.0, 10.0); boundLinePlot.plotSymbol = plotSymbol; [_graph addPlot:boundLinePlot];

首先,添加一個由紅到藍漸變的曲線圖 CPTScatterPlot,設置該曲線圖的曲線線條顏色爲藍色,寬度爲3,標識爲 @"Blue Plot",數據源 datasource 爲自身。注意:一個圖中能夠有多個曲線圖,每一個曲線圖經過其 identifier 進行惟一標識。 數據源將在後面介紹。若是咱們不只僅是描繪曲線,還想描繪曲線覆蓋的區域,那麼就要設置曲線圖的區域填充顏色 areaFill,並設置 areaBaseValue。areaBaseValue就是設置該填充顏色從哪一個值開始描述,好比本例是從1.0開始描繪(見上圖中紅色部分開始的位置爲 y=1)。在這裏咱們設置的填充顏色爲從紅色變到藍色的漸變色 CPTGradient,CPTGradient默認的變化開始色從x軸左邊變化到右邊的結束色,以下圖所示:

 

在本例中,將漸變色旋轉-90度(即順時針方向旋轉90度),使得紅色在下面,藍色在上面(見說明圖)。 對於曲線上的數值點用什麼樣的符號來表示呢?這就是CPTPlotSymbol 發揮做用的時候了,在這裏是用藍色的實心圓點來表示具體的數值。

d), 有了藍紅曲線圖的介紹,下面再來添加一個破折線風格的綠色曲線圖:

// Create a green plot area: 畫破折線 //  lineStyle                = [CPTMutableLineStyle lineStyle];
    lineStyle.lineWidth      = 3.f;
    lineStyle.lineColor      = [CPTColor greenColor];
    lineStyle.dashPattern = [NSArray arrayWithObjects:
                                [NSNumber numberWithFloat:5.0f],
                                [NSNumber numberWithFloat:5.0f], nil];
    
    CPTScatterPlot * dataSourceLinePlot = [[CPTScatterPlot alloc] init];
    dataSourceLinePlot.dataLineStyle = lineStyle;
    dataSourceLinePlot.identifier = GREEN_PLOT_IDENTIFIER;
    dataSourceLinePlot.dataSource = self; // Put an area gradient under the plot above //  CPTColor * areaColor            = [CPTColor colorWithComponentRed:0.3 green:1.0 blue:0.3 alpha:0.8];
    CPTGradient * areaGradient      = [CPTGradient gradientWithBeginningColor:areaColor
                                                                  endingColor:[CPTColor clearColor]];
    areaGradient.angle              = -90.0f;
    areaGradientFill                = [CPTFill fillWithGradient:areaGradient];
    dataSourceLinePlot.areaFill     = areaGradientFill;
    dataSourceLinePlot.areaBaseValue= CPTDecimalFromString(@"1.75"); // Animate in the new plot: 淡入動畫 dataSourceLinePlot.opacity = 0.0f;
    
    CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    fadeInAnimation.duration            = 3.0f;
    fadeInAnimation.removedOnCompletion = NO;
    fadeInAnimation.fillMode            = kCAFillModeForwards;
    fadeInAnimation.toValue             = [NSNumber numberWithFloat:1.0]; [dataSourceLinePlot addAnimation:fadeInAnimation forKey:@"animateOpacity"]; [_graph addPlot:dataSourceLinePlot];

上面的代碼與前面的紅藍漸變曲線圖結構大致相同,只不過在這裏使用的市破折線風格的線條,而且沒有使用特殊符號對數值點進行描繪。在這裏,咱們添加了一個有意思的淡入動畫。

至此,描繪相關設置就完成了。先來回顧一下整個步驟:

a) 在 CPTGraphHostingView 上放置一個 xy 軸圖 CPTXYGraph;
b) 而後對 xy 軸圖進行設置,設置其主題,可視空間 CPTPlotSpace,以及兩個軸 CPTXYAxis;
c) 而後在 xy 軸圖上添加紅藍漸變的曲線圖CPTScatterPlot;
d) 而後在 xy 軸圖上添加綠色破折線曲線圖CPTScatterPlot;

e) 最後,咱們來初始化一些演示數據,從而結束 setupCoreplotViews 方法的介紹。

// Add some initial data //  _dataForPlot = [NSMutableArray arrayWithCapacity:100];
    NSUInteger i; for ( i = 0; i < 100; i++ ) { id x = [NSNumber numberWithFloat:0 + i * 0.05]; id y = [NSNumber numberWithFloat:1.2 * rand() / (float)RAND_MAX + 1.2];
        [_dataForPlot addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, @"x", y, @"y", nil]];
    }

5,實現數據源協議

#pragma mark - #pragma mark Plot Data Source Methods

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{ return [_dataForPlot count];
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
    NSString * key = (fieldEnum == CPTScatterPlotFieldX ? @"x" : @"y");
    NSNumber * num = [[_dataForPlot objectAtIndex:index] valueForKey:key]; // Green plot gets shifted above the blue if ([(NSString *)plot.identifier isEqualToString:GREEN_PLOT_IDENTIFIER]) { if (fieldEnum == CPTScatterPlotFieldY) {
            num = [NSNumber numberWithDouble:[num doubleValue] + 1.0];
        }
    } return num;
}

和 NSTableView 類似,咱們須要提供數據的個數,以及對應x/y軸的數據。至此,編譯容許,你就能看到如期的效果:綠色破折線曲線圖淡入,而後整個xy軸圖就呈如今你面前,而且該圖是容許你拖拽的,不妨多拖拽下,以更好地理解 CorePlot 中各類概念屬性的含義。

6,動態修改 CPTPlotSpace 的範圍

爲了讓例子更有趣一點,在 SetupCoreplotViews 的末尾添加以下代碼:

[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(changePlotRange) userInfo:nil repeats:YES];

並實現 changePlotRange 方法:

-(void)changePlotRange
{ // Change plot space CPTXYPlotSpace * plotSpace = (CPTXYPlotSpace *)_graph.defaultPlotSpace;
    
    plotSpace.xRange = [self CPTPlotRangeFromFloat:0.0 length:(3.0 + 2.0 * rand() / RAND_MAX)];
    plotSpace.yRange = [self CPTPlotRangeFromFloat:0.0 length:(3.0 + 2.0 * rand() / RAND_MAX)];
}

 

四,Core Plot 框架結構分析

CorePlot 的類結構關係以下:

其中最核心的就是 CPTGraph,本示例中的 CPTXYGraph是它的子類;一個圖 CPTGraph包含一個軸集 CPTAxiset,每一個軸集可包含多個軸;一個圖 CPTGraph 可包含多個圖空間 CPTPlotSpace;一個圖 CPTGraph 可包含多個圖形CPTSplot(曲線,餅圖,柱狀圖等);圖形CPTSplot 和軸都展示在某個圖空間 CPTPlotSpace 中。其他的部分,還沒有介紹到,暫且不提。

也許下圖能更形象地描述出 Core Plot 各類對象之間的關係。

相關文章
相關標籤/搜索