1#import "CPTDataSourceTestCase.h" 2#import "CPTExceptions.h" 3#import "CPTScatterPlot.h" 4#import "CPTPlotRange.h" 5#import "CPTUtilities.h" 6 7const CGFloat CPTDataSourceTestCasePlotOffset = 0.5; 8 9/** @cond */ 10@interface CPTDataSourceTestCase () 11 12-(CPTPlotRange *)plotRangeForData:(NSArray *)dataArray; 13 14@end 15/** @endcond */ 16 17@implementation CPTDataSourceTestCase 18 19@synthesize xData; 20@synthesize yData; 21@synthesize nRecords; 22@synthesize xRange; 23@synthesize yRange; 24@synthesize plots; 25 26-(void)dealloc 27{ 28 self.plots = nil; 29 [super dealloc]; 30} 31 32-(void)setUp 33{ 34 //check CPTDataSource conformance 35 STAssertTrue([self conformsToProtocol:@protocol(CPTPlotDataSource)], @"CPTDataSourceTestCase should conform to <CPTPlotDataSource>"); 36} 37 38 39-(void)tearDown 40{ 41 self.xData = nil; 42 self.yData = nil; 43 [[self plots] removeAllObjects]; 44} 45 46-(void)buildData 47{ 48 NSMutableArray *arr = [NSMutableArray arrayWithCapacity:self.nRecords]; 49 for ( NSUInteger i=0; i < self.nRecords; i++ ) { 50 [arr insertObject:[NSDecimalNumber numberWithUnsignedInteger:i] atIndex:i]; 51 } 52 self.xData = arr; 53 54 arr = [NSMutableArray arrayWithCapacity:self.nRecords]; 55 for ( NSUInteger i=0; i < self.nRecords; i++ ) { 56 [arr insertObject:[NSDecimalNumber numberWithDouble:sin(2*M_PI*(double)i/(double)nRecords)] atIndex:i]; 57 } 58 self.yData = arr; 59} 60 61-(void)addPlot:(CPTPlot *)newPlot 62{ 63 if ( nil == self.plots ) { 64 self.plots = [NSMutableArray array]; 65 } 66 67 [[self plots] addObject:newPlot]; 68} 69 70-(CPTPlotRange *)xRange 71{ 72 [self buildData]; 73 return [self plotRangeForData:self.xData]; 74} 75 76-(CPTPlotRange *)yRange 77{ 78 [self buildData]; 79 CPTPlotRange *range = [self plotRangeForData:self.yData]; 80 81 if ( self.plots.count > 1 ) { 82 range.length = CPTDecimalAdd([range length], CPTDecimalFromDouble(self.plots.count)); 83 } 84 85 return range; 86} 87 88-(CPTPlotRange *)plotRangeForData:(NSArray *)dataArray 89{ 90 double min = [[dataArray valueForKeyPath:@"@min.doubleValue"] doubleValue]; 91 double max = [[dataArray valueForKeyPath:@"@max.doubleValue"] doubleValue]; 92 double range = max-min; 93 94 return [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(min - 0.05*range) 95 length:CPTDecimalFromDouble(range + 0.1*range)]; 96} 97 98#pragma mark - 99#pragma mark Plot Data Source Methods 100 101-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot 102{ 103 return self.nRecords; 104} 105 106-(NSArray *)numbersForPlot:(CPTPlot *)plot 107 field:(NSUInteger)fieldEnum 108 recordIndexRange:(NSRange)indexRange 109{ 110 NSArray *result; 111 112 switch ( fieldEnum ) { 113 case CPTScatterPlotFieldX: 114 result = [[self xData] objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:indexRange]]; 115 break; 116 case CPTScatterPlotFieldY: 117 result = [[self yData] objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:indexRange]]; 118 if ( self.plots.count > 1 ) { 119 STAssertTrue([[self plots] containsObject:plot], @"Plot missing"); 120 NSMutableArray *shiftedResult = [NSMutableArray arrayWithCapacity:result.count]; 121 for ( NSDecimalNumber *d in result ) { 122 [shiftedResult addObject:[d decimalNumberByAdding:[NSDecimalNumber decimalNumberWithDecimal:CPTDecimalFromDouble(CPTDataSourceTestCasePlotOffset * ([[self plots] indexOfObject:plot]+1))]]]; 123 } 124 125 result = shiftedResult; 126 } 127 128 break; 129 default: 130 [NSException raise:CPTDataException format:@"Unexpected fieldEnum"]; 131 } 132 133 return result; 134} 135@end 136