Description: getting of data for building a chart from text file.
#import "Charting/ChartDataSource.h" @interface DataSource : NSObject <ChartDataSource> { NSArray *_timestampTitles; NSArray *_timestampArray; double _yMin; double _yMax; double _xMin; double _xMax; double _minValue; double _maxValue; double _secondaryYMin; double _secondaryYMax; double _accumulatedMin; double _accumulatedMax; double _accumulatedSecondaryMin; double _accumulatedSecondaryMax; int m_prevCount; int m_nextCount; int seriesCount; NSMutableArray *legendTitles; NSMutableArray *data; int _currTimestamp; NSMutableArray *_availableKeys; } - (id) init; - (void) loadData; - (void)obtainMin:(double *)min andMax:(double *)max fromArray:(NSArray *)arr addingPositivesTo:(NSMutableArray *)positiveValues addingNegativesTo:(NSMutableArray *)negativeValues; - (void)prepare; @property (assign) int countSeries; @property (nonatomic,assign) int prevCount; @property (nonatomic,assign) int nextCount; @end
#import "DataSource.h" @implementation DataSource @synthesize accumulatedMax = _accumulatedMax; @synthesize accumulatedMin = _accumulatedMin; @synthesize accumulatedSecondaryMax = _accumulatedSecondaryMax; @synthesize accumulatedSecondaryMin = _accumulatedSecondaryMin; @synthesize yMax = _yMax; @synthesize xMax = _xMax; @synthesize yMin = _yMin; @synthesize xMin = _xMin; @synthesize minValue = _minValue; @synthesize maxValue = _maxValue; @synthesize secondaryYMax = _secondaryYMax; @synthesize secondaryYMin = _secondaryYMin; @synthesize availableSeriesKeys = _availableSerKeys; @synthesize timestampArray = _timestampArray; @synthesize timestampTitles = _timestampTitles; @synthesize countSeries = seriesCount; @synthesize nextCount = m_nextCount; @synthesize prevCount = m_prevCount; - (id) init{ self = [super init]; if(self) { _yMin = 0.0; _yMax = 0.0; _xMin = 0.0; _xMax = 0.0; _secondaryYMin = 0.0; _secondaryYMax = 0.0; _accumulatedMin = 0.0; _accumulatedMax = 0.0; _accumulatedSecondaryMin = 0.0; _accumulatedSecondaryMax = 0.0; _availableKeys = [NSMutableArray new]; legendTitles = [NSMutableArray new]; // Determine data array data = [NSMutableArray new]; [self loadData]; seriesCount = [data count]; return self; } return nil; } - (void )loadData { NSString *path = [[NSBundle mainBundle] pathForResource:@"data.txt" ofType:nil]; // Get path to data file NSString *dataString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; // Read contents NSArray *lines = [dataString componentsSeparatedByString:@"\n"]; // Split string with contents into substrings and insert to array NSMutableArray *table = [NSMutableArray new]; for (NSString *line in lines) { [table addObject:[line componentsSeparatedByString:@";"]]; // Split each array element into substrings } NSMutableArray *timelineTitles = [[table objectAtIndex:0] mutableCopy]; [timelineTitles removeObjectAtIndex:0]; _timestampTitles = [[NSArray arrayWithArray:timelineTitles] retain]; _timestampArray = [[NSArray arrayWithArray:timelineTitles] retain]; [timelineTitles release]; // Insert information on each country to array for (int i = 1; i < [table count]; i++) { NSArray *line = [table objectAtIndex:i]; NSMutableArray *values = [[NSMutableArray new] autorelease]; [legendTitles addObject:[line objectAtIndex:0]]; for (int j = 1; j < [line count]; j++) { [values addObject:[NSNumber numberWithFloat:[[line objectAtIndex:j] floatValue]] ]; } [data addObject:values]; } } // Determine series data (population for specific period) - (NSArray *) seriesDataWithIndex:(int)seriesIndex { if (seriesIndex < 0) { seriesIndex = 3; } NSMutableArray *serData = [[data objectAtIndex:seriesIndex] mutableCopy]; for(int i = 0; i < m_prevCount; i++) [serData insertObject:[NSNull null] atIndex:0]; for (int i = 0; i < m_nextCount; i++) { [serData addObject:[NSNull null]]; } return serData; } // Determine values for timeline axis -(NSArray *)timestampArray { NSMutableArray *ar = [_timestampArray mutableCopy]; for(int i = 0; i < m_prevCount; i++) [ar insertObject:[NSNumber numberWithInt:-1] atIndex:0]; for (int i = 0; i < m_nextCount; i++) { [ar addObject:[NSNumber numberWithInt:-1]]; } return ar; } // Determine titles for timeline axis values - (NSArray *)timestampTitles { NSMutableArray *ar = [_timestampTitles mutableCopy]; for(int i = 0; i < m_prevCount; i++) [ar insertObject:@" " atIndex:0]; for (int i = 0; i < m_nextCount; i++) { [ar addObject:@" "]; } return ar; } // Determine the array containing available series keys - (NSArray *)availableSeriesKeys { return data; } // Determine series name displayed in legend - (NSString *)seriesNameWithIndex:(int)seriesIndex { return [legendTitles objectAtIndex:seriesIndex]; } // Calculate values of maximum and minimum elements in data - (void)obtainMin:(double *)min andMax:(double *)max fromArray:(NSArray *)arr addingPositivesTo:(NSMutableArray *)positiveValues addingNegativesTo:(NSMutableArray *)negativeValues { if(([positiveValues count] == 0) || ([negativeValues count] == 0) ) { [positiveValues removeAllObjects]; [negativeValues removeAllObjects]; for (int i=0; i < [arr count]; i++) { NSNumber *value = [arr objectAtIndex:i]; if ([value class] == [NSNull class]) { continue; } if ([value floatValue] > 0) { [positiveValues addObject:[arr objectAtIndex:i]]; } [positiveValues addObject:[NSNumber numberWithFloat:0.0f]]; } for (int i=0; i < [arr count]; i++) { NSNumber *value = [arr objectAtIndex:i]; if ([value class] == [NSNull class]) { continue; } if ([value floatValue] < 0) { [negativeValues addObject:[arr objectAtIndex:i]]; } [negativeValues addObject:[NSNumber numberWithFloat:0.0f]]; } } else { for (int i=0; i < [arr count]; i++) { NSNumber *value = [arr objectAtIndex:i]; if ([value class] == [NSNull class]) { continue; } if ([value floatValue] > 0) { NSNumber *num = [positiveValues objectAtIndex:i]; num = [NSNumber numberWithFloat:[num floatValue] + [value floatValue]]; [positiveValues replaceObjectAtIndex:i withObject:num]; } else { NSNumber *num = [negativeValues objectAtIndex:i - m_prevCount]; num = [NSNumber numberWithFloat:[num floatValue] + [value floatValue]]; [negativeValues replaceObjectAtIndex:i - m_prevCount withObject:num]; } } float _min = *min; float _max = *max; for (int i=0; i < [arr count]; i++) { NSNumber *value = [arr objectAtIndex:i]; if ([value class] == [NSNull class]) { continue; } if ([value floatValue] > _max) _max = [value floatValue]; if([value floatValue] < _min) _min = [value floatValue]; } *max = _max; *min = _min; } } - (void)prepare { NSMutableArray *positive = [NSMutableArray new]; NSMutableArray *negative = [NSMutableArray new]; for(int i = 0; i < seriesCount; i++) { NSLog(@"%d",i); [self obtainMin:&_yMin andMax:&_yMax fromArray:[self seriesDataWithIndex:i] addingPositivesTo:positive addingNegativesTo:negative]; } for (int i=0; i < [positive count]; i++) { NSNumber *value = [positive objectAtIndex:i]; if ([value floatValue] > _accumulatedMax) _accumulatedMax = [value floatValue]; } for (int i=0; i < [negative count]; i++) { NSNumber *value = [negative objectAtIndex:i]; if ([value floatValue] < _accumulatedMax) _accumulatedMin = [value floatValue]; } _xMax = _yMax; _xMin = _yMin; _maxValue = _yMax; _minValue = _yMin; [positive release]; [negative release]; } // Determine the object containing available series title parameters - (NSDictionary *) availableSeriesHeaders { return nil; } // Determine labels for X axis - (NSString *)xAxisNameForMask:(NSString *)mask { return @""; } // Determine labels for Y axis - (NSString *)yAxisNameForMask:(NSString *)mask { return @""; } // Determine labels for secondary axis - (NSString *)secondaryAxisNameForMask:(NSString *)mask { return @""; } - (double)xMax { return _xMax; } - (double) xMin { return _xMin; } - (double) yMax { return _yMax; } - (double) yMin { return _yMin; } - (double)secondaryYMin { return 0.0; } - (double)secondaryYMax { return 0.0; } - (double)accumulatedSecondaryMin { return 0.0; } - (double)accumulatedSecondaryMax { return 0.0; } - (int)minTimestamp { return 0; } - (int)maxTimestamp { return 0; } - (void)setMaxTimestamp:(int)mt{} - (void)setMinTimestamp:(int)mt{} - (void)setCurrentTimestamp:(int)currentTimestamp { _currTimestamp = currentTimestamp; } - (void)setStartDataIndexOffset:(int)startOffset andEndDataIndexOffset:(int)endOffset {} @end
See also: