CorePlotを理解可能なレベルに噛み砕きたい件 part2

[前回の続き](http://qiita.com/rooooomania/items/949cb7a14aedb47e99eb)も記録しておく。


## X軸を日付にする
X軸、Y軸ともに通常は数字が軸ラベルとして用いられる。今回私が作りたいのは時系列の情報の推移なので、X軸を数字から日付にする必要がある。

前回記載したように、CorePlotを使う場合の基本的なアプローチで下記のような設定を行った。

* ホスト設定
* グラフ設定
* プロット設定
* 軸設定

それに加えて`configureCalendar`というカレンダー用設定処理を追加した。

```objc
NSTimeInterval const oneDay = 60.0f * 60.0f * 24.0f;
- (void)configureCalendar
{
    CPTGraph *graph = self.hostview.hostedGraph;
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
    
    //プロットスペースのX軸表示範囲設定
    CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
    xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(oneDay * 30)];
    plotSpace.xRange = xRange;
    

    //30日前の日付を取得する
    NSDate *today = [NSDate date];
    NSDate *startDate = [NSDate dateWithTimeInterval:-(oneDay * 30) sinceDate:today];
    //グラフのX軸に描かれる日付を設定する
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"MM-dd"];
    [formatter setLocale:[NSLocale systemLocale]];
    [formatter setTimeZone:[NSTimeZone systemTimeZone]];
    CPTTimeFormatter *timeFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:formatter];
    timeFormatter.referenceDate = startDate;
    
    //X軸のラベルを日付形式に設定
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
    CPTXYAxis *x = axisSet.xAxis;
    x.labelFormatter = timeFormatter;
    x.majorIntervalLength = CPTDecimalFromFloat(7*oneDay);
    x.minorTicksPerInterval = 6;
    
}
```
1. プロットスペースのX軸表示範囲は、当日を最新として30日間分としたい。軸の`labelFormatter`にはCPTimeFomartterのオブジェクトを設定するため、表示の範囲としては30 × [1日の秒換算]をlengthに設定する。これは、CPTimeFomatterが秒数を使って日付を管理しているため。
2. 時間的な範囲を30日前〜本日、と定義したいため、30日前の日付を取得し、CPTimeFormatterの開始日`referenceDate`プロパティに設定している。
3. このグラフのX軸のラベルを日付形式に設定している。インターバルは7日間なので、この場合は`7*oneDay`秒となり、それを`x.minorTicksPerInterval=6`とすることで6分割（1日ごとに目盛表示される）した。

続いて、DataSourceメソッドにてX軸の値を返却する場合も、日付フォーマットであることを考慮して`index * oneDay`としている。

```objc
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
    NSUInteger valueCount = [self.calendarData count];
     
    switch (fieldEnum) {
        case CPTScatterPlotFieldX:
            //index * 1日分の秒数
            if (index < valueCount) {
                return [NSNumber numberWithUnsignedInteger:index * oneDay]; //<- here
            }
            break;
        case CPTScatterPlotFieldY:
            if ([plot.identifier isEqual:kData] == YES) {
                NSNumber *numberForPlot = [[self.calendarData objectAtIndex:index] valueForKey:@"max"];
                return numberForPlot;
            }
        default:
            break;
    }
    return [NSDecimalNumber zero];
}
```

## 元となるデータをユーザが指定してグラフを作成する
通常、グラフはviewDidLoadまたはviewDidAppear:のタイミングで描画されることが多いように思う。
私の実現したかったことは、グラフ表示させるプロットをユーザが動的に選択（テキストフィールドで条件を指定）することだったので、UITextFieldDelegateプロトコルを実装し、`textFieldDidEndEditing:`メソッド内にて、グラフ更新処理を記述した。

```objc
#pragma mark - UITextFieldDelegate
- (void)textFieldDidEndEditing:(UITextField *)textField
{
    if (![self.nameTextField.text isEqualToString:@""]) {
        //グラフ表示させるためのモデルデータ作成
        ......

		//グラフ更新処理
       [self reloadGraphData:self.hostview.hostedGraph];
    }
}
```
ちなみに`reloadGraphData:`は内部のメソッドで、下記のように実装。

```objc
- (void) reloadGraphData:(CPTGraph*)graph
{
    // データ取得の各種delegateが実行される。
    [graph reloadData];
}
```

## 連続しないデータ間を補完したプロットは作れないのか
https://groups.google.com/forum/#!searchin/coreplot-discuss/scatter/coreplot-discuss/8ulsY6MUqMU/oFaf7-kY5GoJ

これについては、現在調査中・・・、もとい、調査凍結中。
X軸に設定した目盛り単位にY軸の値をプロットできればその2点間は線で結ばれるが、間の値が欠落しているとそれを補完して最も近い2点間を結んでくれるわけではない。
折れ線グラフという体裁において、これはかなり違和感がある。間の値は`NSNULL null`を設定していると上述のようになるのだが、`@0`を設定すると一応折れ線の体は維持してくれる（本質的な解決ではない）。
![iOSシミュレータのスクリーンショット 2014.03.05 0.18.18.png](https://qiita-image-store.s3.amazonaws.com/0/37895/263082a7-db2d-c1e6-8095-d6d2321f736f.png "iOSシミュレータのスクリーンショット 2014.03.05 0.18.18.png")
![iOSシミュレータのスクリーンショット 2014.03.05 0.16.57.png](https://qiita-image-store.s3.amazonaws.com/0/37895/18ab5d08-b682-abe3-77cb-bd564ce1227c.png "iOSシミュレータのスクリーンショット 2014.03.05 0.16.57.png")