2012-03-21 6 views
0

CorePlotで2行の簡単なグラフを作成しようとしています。 http://www.johnwordsworth.com/2011/10/adding-charts-to-your-iphone-ipad-app-using-core-plot/にある偉大なチュートリアルから始めて、私は最初に1行(チュートリアルからのコピーと貼り付けは簡​​単でした)を作成してから、少し修正して2行目を追加することができました。CorePlotコードを変更してX軸に日付を設定する

私が得たいと思っている次のコードからは、数字の代わりにX軸に日付を付けることができます。この例の値はCGPointの配列に格納されます。私はnumberForPlotで何かを変えなければならないと思いますが、どうですか?

TUTSimpleScatterPlot.h

#import <Foundation/Foundation.h> 
    #import "CorePlot-CocoaTouch.h" 

@interface TUTSimpleScatterPlot : NSObject <CPTScatterPlotDataSource> { 
     CPTGraphHostingView *_hostingView; 
     CPTXYGraph *_graph; 
     NSMutableDictionary *_graphData; 
    } 

    @property (nonatomic, retain) CPTGraphHostingView *hostingView; 
    @property (nonatomic, retain) CPTXYGraph *graph; 
    @property (nonatomic, retain) NSMutableDictionary *graphData; 

    -(id)initWithHostingView:(CPTGraphHostingView *)hostingView andData:(NSMutableDictionary *)data; 

    // Specific code that creates the scatter plot. 
    -(void)initialisePlot; 

TUTSimpleScatterPlot.m

#import "TUTSimpleScatterPlot.h" 

@implementation TUTSimpleScatterPlot 
@synthesize hostingView = _hostingView; 
@synthesize graph = _graph; 
@synthesize graphData = _graphData; 

-(id)initWithHostingView:(CPTGraphHostingView *)hostingView andData:(NSMutableDictionary *)data 
{ 
    self = [super init]; 

    if (self != nil) { 
     self.hostingView = hostingView; 
     self.graphData = data; 
     self.graph = nil; 
    } 

    return self; 
} 

// This does the actual work of creating the plot if we don't already have a graph object. 
-(void)initialisePlot 
{ 
    // Start with some simple sanity checks before we kick off 
    if ((self.hostingView == nil) || (self.graphData == nil)) { 
     NSLog(@"TUTSimpleScatterPlot: Cannot initialise plot without hosting view or data."); 
     return; 
    } 

    if (self.graph != nil) { 
     NSLog(@"TUTSimpleScatterPlot: Graph object already exists."); 
     return; 
    } 

    // Create a graph object which we will use to host just one scatter plot. 
    CGRect frame = [self.hostingView bounds]; 
    self.graph = [[CPTXYGraph alloc] initWithFrame:frame]; 

    // Add some padding to the graph, with more at the bottom for axis labels. 
    self.graph.plotAreaFrame.paddingTop = 20.0f; 
    self.graph.plotAreaFrame.paddingRight = 20.0f; 
    self.graph.plotAreaFrame.paddingBottom = 50.0f; 
    self.graph.plotAreaFrame.paddingLeft = 20.0f; 

    // Tie the graph we've created with the hosting view. 
    self.hostingView.hostedGraph = self.graph; 

    // If you want to use one of the default themes - apply that here. 
    //[self.graph applyTheme:[CPTTheme themeNamed:kCPTDarkGradientTheme]]; 

    // Create a line style that we will apply to the axis and data line. 
    CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle]; 
    lineStyle.lineColor = [CPTColor whiteColor]; 
    lineStyle.lineWidth = 2.0f; 

    CPTMutableLineStyle *lineStyle2 = [CPTMutableLineStyle lineStyle]; 
    lineStyle2.lineColor = [CPTColor redColor]; 
    lineStyle2.lineWidth = 2.0f; 

    // Create a text style that we will use for the axis labels. 
    CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle]; 
    textStyle.fontName = @"Helvetica"; 
    textStyle.fontSize = 14; 
    textStyle.color = [CPTColor whiteColor]; 

    // Create the plot symbol we're going to use. 
    CPTPlotSymbol *plotSymbol = [CPTPlotSymbol crossPlotSymbol]; 
    plotSymbol.lineStyle = lineStyle; 
    plotSymbol.size = CGSizeMake(8.0, 8.0); 

    // Setup some floats that represent the min/max values on our axis. 
    float xAxisMin = -10; 
    float xAxisMax = 10; 
    float yAxisMin = 0; 
    float yAxisMax = 100; 

    // We modify the graph's plot space to setup the axis' min/max values. 
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace; 
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xAxisMin) length:CPTDecimalFromFloat(xAxisMax - xAxisMin)]; 
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(yAxisMin) length:CPTDecimalFromFloat(yAxisMax - yAxisMin)]; 

    // Modify the graph's axis with a label, line style, etc. 
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet; 

    axisSet.xAxis.title = @"Data X"; 
    axisSet.xAxis.titleTextStyle = textStyle; 
    axisSet.xAxis.titleOffset = 30.0f; 
    axisSet.xAxis.axisLineStyle = lineStyle; 
    axisSet.xAxis.majorTickLineStyle = lineStyle; 
    axisSet.xAxis.minorTickLineStyle = lineStyle; 
    axisSet.xAxis.labelTextStyle = textStyle; 
    axisSet.xAxis.labelOffset = 3.0f; 
    axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(2.0f); 
    axisSet.xAxis.minorTicksPerInterval = 1; 
    axisSet.xAxis.minorTickLength = 5.0f; 
    axisSet.xAxis.majorTickLength = 7.0f; 

    axisSet.yAxis.title = @"Data Y"; 
    axisSet.yAxis.titleTextStyle = textStyle; 
    axisSet.yAxis.titleOffset = 40.0f; 
    axisSet.yAxis.axisLineStyle = lineStyle; 
    axisSet.yAxis.majorTickLineStyle = lineStyle; 
    axisSet.yAxis.minorTickLineStyle = lineStyle; 
    axisSet.yAxis.labelTextStyle = textStyle; 
    axisSet.yAxis.labelOffset = 3.0f; 
    axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(10.0f); 
    axisSet.yAxis.minorTicksPerInterval = 1; 
    axisSet.yAxis.minorTickLength = 5.0f; 
    axisSet.yAxis.majorTickLength = 7.0f; 

    // Add a plot to our graph and axis. We give it an identifier so that we 
    // could add multiple plots (data lines) to the same graph if necessary. 
    CPTScatterPlot *plot = [[CPTScatterPlot alloc] init]; 
    plot.dataSource = self; 
    plot.identifier = @"mainplot"; 
    plot.dataLineStyle = lineStyle; 
    plot.plotSymbol = plotSymbol; 
    [self.graph addPlot:plot]; 


    // second plot 
    CPTScatterPlot *plot2 = [[CPTScatterPlot alloc] init]; 
    plot2.dataSource = self; 
    plot2.identifier = @"otherplot"; 
    plot2.dataLineStyle = lineStyle2; 
    plot2.plotSymbol = plotSymbol; 
    [self.graph addPlot:plot2]; 

} 

// Delegate method that returns the number of points on the plot 
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot 
{ 
    if ([plot.identifier isEqual:@"mainplot"]) 
    { 
     return [[self.graphData objectForKey:@"1"] count]; 
    } 

    if ([plot.identifier isEqual:@"otherplot"]) 
    { 
     return [[self.graphData objectForKey:@"2"] count]; 

    } 

    return 0; 
} 

// Delegate method that returns a single X or Y value for a given plot. 
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{ 
    if ([plot.identifier isEqual:@"mainplot"]) 
    { 
     NSValue *value = [[self.graphData objectForKey:@"1"] objectAtIndex:index]; 
     CGPoint point = [value CGPointValue]; 

     // FieldEnum determines if we return an X or Y value. 
     if (fieldEnum == CPTScatterPlotFieldX) 
     { 
      return [NSNumber numberWithFloat:point.x]; 
     } 
     else // Y-Axis 
     { 
      return [NSNumber numberWithFloat:point.y]; 
     } 
    } 

    if ([plot.identifier isEqual:@"otherplot"]) 
    { 
     NSValue *value = [[self.graphData objectForKey:@"2"] objectAtIndex:index]; 
     CGPoint point = [value CGPointValue]; 

     // FieldEnum determines if we return an X or Y value. 
     if (fieldEnum == CPTScatterPlotFieldX) 
     { 
      return [NSNumber numberWithFloat:point.x]; 
     } 
     else // Y-Axis 
     { 
      return [NSNumber numberWithFloat:point.y]; 
     } 
    } 


    return [NSNumber numberWithFloat:0]; 
} 

@end 

そして、私は上記のメソッドを呼び出し、別のクラスの:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 

    NSMutableArray *data = [NSMutableArray array]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(-10, 100)]]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(-8, 50)]]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(-6, 20)]]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(-4, 10)]]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(-2, 5)]]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(0, 0)]]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(2, 4)]]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(4, 16)]]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(6, 36)]]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(8, 64)]]; 
    [data addObject:[NSValue valueWithCGPoint:CGPointMake(10, 100)]]; 

    // second line values 
    NSMutableArray *data2 = [NSMutableArray array]; 
    [data2 addObject:[NSValue valueWithCGPoint:CGPointMake(0, 0)]]; 
    [data2 addObject:[NSValue valueWithCGPoint:CGPointMake(3, 5)]]; 
    [data2 addObject:[NSValue valueWithCGPoint:CGPointMake(5, 17)]]; 
    [data2 addObject:[NSValue valueWithCGPoint:CGPointMake(7, 37)]]; 
    [data2 addObject:[NSValue valueWithCGPoint:CGPointMake(9, 65)]]; 
    [data2 addObject:[NSValue valueWithCGPoint:CGPointMake(11, 99)]]; 

    NSMutableDictionary *dataDictionary = [NSMutableDictionary dictionary]; 
    [dataDictionary setObject:data forKey:@"1"]; 
    [dataDictionary setObject:data2 forKey:@"2"]; 




    self.scatterPlot = [[TUTSimpleScatterPlot alloc] initWithHostingView:_graphHostingView andData:dataDictionary]; 
    [self.scatterPlot initialisePlot]; 

} 

最後に、使用するデータは、タイムスタンプが含まれます各行の値を指定します。タイムスタンプを変換して、X軸に読み取り可能な日付を作成します。これは、1行または複数行の場合に発生します。

答えて

1

コアプロットには、軸に日付をプロットする方法を示すいくつかのサンプルアプリケーションがあります。 CPTCalendarFormatterおよびCPTTimeFormatterのクラスは、日付の書式設定に役立ちます。 CPTCalendarFormatterがリリースされた後に追加されたので、使用するにはMercurialで最新のコードを取得する必要があります。

+0

私は1.0バージョンを使用しています。 'CPTCalendarFormatter'クラスを見ていきます。一方、私は描く必要がある値を抽出しました。すべての行について、(unixtimestamp、value)、(unixtimestamp + 300secs、value2)、(unixtimestamp + 600secs、value3)などの形式で表示されます。したがって、unixtimestampを何か可読なものに変換するのに十分かもしれません。私は例を探しています:) – Simon

+0

申し訳ありませんが、 'CPTCalendarFormatter'が1.0ではなく、 'CPTTimeFormatter'しかありません – Simon