CPTPlotDataSource プロトコル対応
CPTPlotDataSource プロトコルに対応するには、まずこれが必ず必要
(NSUInteger) - numberOfRecordsForPlot:
この部分は今回はこんな感じ。
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot { return 5; }
単純にグラフには何個レコードがありますか?という確認なので、今回は決め打ちで 5個にしてある。
実際に使う場合には、例えば横軸が日付になるなら何日分か?を返すとかすれば良い。
で、次に必要なのは以下の中のどれか1つ
(NSArray *) - numbersForPlot:field:recordIndexRange: (NSNumber *) - numberForPlot:field:recordIndex: (double *) - doublesForPlot:field:recordIndexRange: (double) - doubleForPlot:field:recordIndex: (CPTNumericData *) - dataForPlot:field:recordIndexRange:
今回は (NSNumber *) - numberForPlot:field:recordIndex: を使用してみてこんな感じに。
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index { if(fieldEnum == CPTBarPlotFieldBarLocation) return [NSNumber numberWithDouble:index+1]; else { if(plot.identifier == @"Bar Plot 1") return [NSNumber numberWithDouble:(index+1)*2.0f]; else return 0; } }
まず、(NSNumber *) - numberForPlot:field:recordIndex: は、そのプロット(CPTPlot)の field の recordIndex 番目のレコードの値を返すというメソッド。
今回は CPTPlot が棒グラフ1つしかないから CPTPlot の確認は行ってない。
けど、もしも複数の CPTPlot を乗せるなら確認が必要になる。
次の field はプロットのどの部分の値が必要なのかを示している。
これはそれぞれの CPTPlot(CPTBarPlot や CPTScatterPlot 等)で用意されていて、CPTBarPlot の場合はこんなのがある。
typedef enum _CPTBarPlotField { CPTBarPlotFieldBarLocation = 2, ///< Bar location on independent coordinate axis. CPTBarPlotFieldBarTip = 3, ///< Bar tip value. CPTBarPlotFieldBarBase = 4 ///< Bar base (used only if barBasesVary is YES). } CPTBarPlotField;
そして CPTScatterPlot ではこんなんがある。
typedef enum _CPTScatterPlotField { CPTScatterPlotFieldX, ///< X values. CPTScatterPlotFieldY ///< Y values. } CPTScatterPlotField;
今回の CPTBarPlot の場合は CPTBarPlotFieldBarLocation が来たら「そのレコードは何番目の棒か?」を返せば良い。
今回は recordIndex の値に 1 をプラスしている。これは最初のレコードを 0番目でなく 1番目の場所から描く様にしたため。
ちなみに 1を加えずにそのまま index を返すとこんな感じのグラフになる。
最初の棒の位置が 0なので、Y軸に重なっちゃう…。
これ、Y軸の交差する位置を変えたり、棒を描く位置をずらしたり、方法は色々とあるのだけど、今回はとりあえずこんな感じで。
今回は CPTBarPlotFieldBarLocation でなければ実際のレコードの値の問い合わせなので、(index+1)*2.0f で右肩上がりの棒グラフになるようにしている。
で、これを最初に示したサンプル(+Y軸の目盛線)にするにはもう少しだけ修正をしている。
// First bar plot CPTBarPlot *barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor redColor] horizontalBars:NO]; barPlot.baseValue = CPTDecimalFromString(@"0"); barPlot.dataSource = self; barPlot.barWidth = CPTDecimalFromFloat(1.0f); barPlot.identifier = @"Bar Plot 1"; barPlot.barOffset = CPTDecimalFromString(@"3"); [graph addPlot:barPlot toPlotSpace:plotSpace];
- barPlot.barWidth = CPTDecimalFromFloat(1.0f); で棒の幅を1にしている。これで棒の間の隙間が無くなった。
- barPlot.barOffset = CPTDecimalFromString(@"3"); で描く位置を右に3ずらしている。小数点でもいけるので 0.5 だと棒の半分ずれる。
取り敢えず簡単な棒グラフならこれで作れるようになったはず!
UITableView みたいに datasource に値を問い合わせてくるので、CoreData を使ってグラフを描くのは結構簡単。
というわけで、明日は X軸を日付にしてみる!