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