Источник данных

Описание: получение данных для построения диаграммы из текстового файла.

Файл «DataSource.h»

#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

Файл «DataSource.m»

#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];
        // Определяем массив с данными
        data = [NSMutableArray new];
        [self loadData];
        seriesCount = [data count];
        return self;
    }
    return nil;
}
- (void )loadData
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"data.txt" ofType:nil]; // Получаем путь к файлу с данными
    NSString *dataString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; // Прочитываем содержимое
    NSArray *lines = [dataString componentsSeparatedByString:@"\n"]; // Разбиваем строку с содержимым на подстроки и заносим в массив
    NSMutableArray *table = [NSMutableArray new];
    for (NSString *line in lines) {
        [table addObject:[line componentsSeparatedByString:@";"]]; // Разбиваем каждый элемент массива еще на подстроки
    }
    NSMutableArray *timelineTitles = [[table objectAtIndex:0] mutableCopy];
    [timelineTitles removeObjectAtIndex:0];
    _timestampTitles = [[NSArray arrayWithArray:timelineTitles] retain];
    _timestampArray = [[NSArray arrayWithArray:timelineTitles] retain];
    [timelineTitles release];
    // Заносим данные по каждой стране в массив
    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];
    }
}
// Определяем данные ряда (численность населения за определенный период)
- (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;
}
// Определяем значения для шкалы временной оси
-(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;
}
// Определяем заголовки для значений шкалы временной оси
- (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;
}
// Определяем массив, содержащий ключи доступных рядов
- (NSArray *)availableSeriesKeys
{
    return data;
}
// Определяем наименование ряда, выводимое в легенде
- (NSString *)seriesNameWithIndex:(int)seriesIndex
{
    return [legendTitles objectAtIndex:seriesIndex];
}
// Вычисляем значения максимального и минимального элементов в данных
- (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];
}
// Определяем объект, содержащий параметры заголовков доступных рядов
- (NSDictionary *) availableSeriesHeaders
{
    return nil;
}
// Определяем подписи для оси X
- (NSString *)xAxisNameForMask:(NSString *)mask
{
    return @"";
}
// Определяем подписи для оси Y
- (NSString *)yAxisNameForMask:(NSString *)mask
{
    return @"";
}
// Определяем подписи для дополнительной оси
- (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

См. также:

Создание линий уровня и тренда на диаграмме