Core-plot, неспособный построить два графика

56
7

В настоящее время я пытаюсь использовать библиотеку основного сюжета для графика некоторых данных, которые я получаю через JSON. Я пытаюсь построить два графика на одной диаграмме, но я не могу этого добиться. Когда я просто рисую только один график, он работает правильно.


Ниже приведен код моего разностного графика с использованием библиотеки основного сюжета.


#pragma mark -
#pragma mark Plot construction methods

- (void)constructScatterPlot
{
NSMutableArray *appleContentArray = [NSMutableArray arrayWithCapacity:270];
NSMutableArray *googleContentArray = [NSMutableArray arrayWithCapacity:270];

NSData *stocks = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://d1sz0kydzogekx.cloudfront.net/stocks.txt"]];
NSInputStream *stockStream = [[NSInputStream alloc] initWithData:stocks];
[stockStream open];

NSUInteger i;
i = 1;

if (stockStream) {
NSError *parseError = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithStream:stockStream options:NSJSONReadingAllowFragments error:&parseError];

if ([jsonObject respondsToSelector:@selector(objectForKey:)]) {
for (NSDictionary *stock in [jsonObject objectForKey:@"stocks"]) {
if ([[stock objectForKey:@"stock"] isEqualToString:@"AAPL"]){
id x = [NSNumber numberWithInt:i];
id y = [stock objectForKey:@"close"];

[appleContentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, @"x", y, @"y", nil]];
}

if ([[stock objectForKey:@"stock"] isEqualToString:@"GOOG"]){
id x = [NSNumber numberWithInt:i];
id y = [stock objectForKey:@"close"];

[googleContentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, @"x", y, @"y", nil]];
}

i++;
}
}

} else {
NSLog(@"Failed to open stream.");
}

// Create graph from theme
graph = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainBlackTheme];
[graph applyTheme:theme];
scatterPlotView.hostedGraph = graph;

graph.paddingLeft = 0;
graph.paddingTop = 0.0;
graph.paddingRight = 0;
graph.paddingBottom = 0;

// Setup plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-20.0) length:CPTDecimalFromFloat(260.0)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(150.0) length:CPTDecimalFromFloat(400.0)];

// Axes
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPTDecimalFromString(@"1000");
x.orthogonalCoordinateDecimal = CPTDecimalFromString(@"2");
x.minorTicksPerInterval = 2;
NSArray *exclusionRanges = [NSArray arrayWithObjects:
[CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(1.99) length:CPTDecimalFromFloat(0.02)],
[CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.99) length:CPTDecimalFromFloat(0.02)],
[CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(2.99) length:CPTDecimalFromFloat(0.02)],
nil];
x.labelExclusionRanges = exclusionRanges;

CPTXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = CPTDecimalFromString(@"50");
y.orthogonalCoordinateDecimal = CPTDecimalFromString(@"2");
y.minorTicksPerInterval = 2;

exclusionRanges = [NSArray arrayWithObjects:
[CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(1.99) length:CPTDecimalFromFloat(0.02)],
[CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.99) length:CPTDecimalFromFloat(0.02)],
[CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(3.99) length:CPTDecimalFromFloat(0.02)],
nil];
y.labelExclusionRanges = exclusionRanges;

// Create a green Apple plot area
CPTScatterPlot *appleLinePlot = [[[CPTScatterPlot alloc] init] autorelease];
appleLinePlot.identifier = @"Green Plot";

CPTMutableLineStyle *appleLineStyle = [[appleLinePlot.dataLineStyle mutableCopy] autorelease];

appleLineStyle.lineWidth = 2.0;
appleLineStyle.lineColor = [CPTColor greenColor];

appleLinePlot.dataLineStyle = appleLineStyle;
appleLinePlot.opacity = 0.0f;
appleLinePlot.cachePrecision = CPTPlotCachePrecisionDecimal;

// Create a red Google plot area
CPTScatterPlot *googleLinePlot = [[[CPTScatterPlot alloc] init] autorelease];
googleLinePlot.identifier = @"Red Plot";

CPTMutableLineStyle *googleLineStyle = [[googleLinePlot.dataLineStyle mutableCopy] autorelease];

googleLineStyle.lineWidth = 2.0;
googleLineStyle.lineColor = [CPTColor redColor];
googleLinePlot.dataLineStyle = googleLineStyle;

// Animate in the new plot
CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeInAnimation.duration = 0.0f;
fadeInAnimation.removedOnCompletion = NO;
fadeInAnimation.fillMode = kCAFillModeForwards;
fadeInAnimation.toValue = [NSNumber numberWithFloat:1.0];
[appleLinePlot addAnimation:fadeInAnimation forKey:@"animateOpacity"];
[googleLinePlot addAnimation:fadeInAnimation forKey:@"animateOpacity"];

appleLinePlot.cachePrecision = CPTPlotCachePrecisionDecimal;
googleLinePlot.cachePrecision = CPTPlotCachePrecisionDecimal;

appleLinePlot.dataSource = self;
self.dataForPlot = appleContentArray;
[graph addPlot:appleLinePlot];

googleLinePlot.dataSource = self;
self.dataForPlot = googleContentArray;
[graph addPlot:googleLinePlot];
}

#pragma mark -
#pragma mark CPTBarPlot delegate method

-(void)barPlot:(CPTBarPlot *)plot barWasSelectedAtRecordIndex:(NSUInteger)index
{
NSLog(@"barWasSelectedAtRecordIndex %d", index);
}

#pragma mark -
#pragma mark Plot Data Source Methods

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
return [dataForPlot count];
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSDecimalNumber *num = nil;

num = [[dataForPlot objectAtIndex:index] valueForKey:(fieldEnum == CPTScatterPlotFieldX ? @"x" : @"y")];

if ( [(NSString *)plot.identifier isEqualToString:@"Green Plot"] ) {
if ( fieldEnum == CPTScatterPlotFieldX ) {
num = (NSDecimalNumber *)[NSDecimalNumber numberWithDouble:[num doubleValue]];
}

if ( fieldEnum == CPTScatterPlotFieldY ) {
num = (NSDecimalNumber *)[NSDecimalNumber numberWithDouble:[num doubleValue]];
}
}

if ( [(NSString *)plot.identifier isEqualToString:@"Red Plot"] ) {
if ( fieldEnum == CPTScatterPlotFieldX ) {
num = (NSDecimalNumber *)[NSDecimalNumber numberWithDouble:[num doubleValue]];
}
}

return num;
}

спросил(а) 2012-01-26T05:08:00+04:00 7 лет, 10 месяцев назад
1
Решение
77

Вот несколько вещей, которые выскочили на меня в вашем коде:

    Данные графика должны быть доступны для источника данных. Самый простой способ - сохранить два массива содержимого в переменных экземпляра, чтобы они были видны во всем классе, а не в локальных переменных, которые исчезают, когда метод -constructScatterPlot завершен.


    У обоих участков всегда одинаковое количество сюжетных точек? Если нет, проверьте идентификатор графика в -numberOfRecordsForPlot: и верните правильный счет для каждого из них.


     -(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot 
    {
    if ( [(NSString *)plot.identifier isEqualToString:@"Green Plot"] ) {
    return appleContentArray.count;
    }
    else if ( [(NSString *)plot.identifier isEqualToString:@"Red Plot"] ) {
    return googleContentArray.count;
    }
    return 0;
    }

    Ваш источник данных может быть значительно упрощен (в моем примере используется ваша исходная структура данных):


    -(NSNumber *)numberForPlot:(CPTPlot *)plot
    field:(NSUInteger)fieldEnum
    recordIndex:(NSUInteger)index
    {
    NSArray *contentArray = nil;

    if ( [(NSString *)plot.identifier isEqualToString:@"Green Plot"] ) {
    contentArray = appleContentArray;
    }
    else if ( [(NSString *)plot.identifier isEqualToString:@"Red Plot"] ) {
    contentArray = googleContentArray;
    }

    return [[contentArray objectAtIndex:index] valueForKey:(fieldEnum == CPTScatterPlotFieldX ? @"x" : @"y")];
    }


    Имеются ли в ваших массивах содержимого ожидаемые значения? Вам действительно нужно хранить индекс? Если вам это не понадобится, я бы просто сохранил значение close в массиве контента и забыл о структуре словаря. В этом случае метод источника данных будет выглядеть следующим образом:


    -(NSNumber *)numberForPlot:(CPTPlot *)plot
    field:(NSUInteger)fieldEnum
    recordIndex:(NSUInteger)index
    {
    NSNumber *num = nil;

    switch ( fieldEnum ) {
    case CPTScatterPlotFieldX:
    num = [NSNumber numberWithUnsignedInteger:index];
    break;

    case CPTScatterPlotFieldY:
    if ( [(NSString *)plot.identifier isEqualToString:@"Green Plot"] ) {
    num = [appleContentArray objectAtIndex:index];
    }
    else if ( [(NSString *)plot.identifier isEqualToString:@"Red Plot"] ) {
    num = [googleContentArray objectAtIndex:index];
    }
    break;
    }

    return num;
    }


ответил(а) 2012-01-26T05:51:00+04:00 7 лет, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема