核心情节,无法绘制两张图

我目前正在尝试使用核心图库来绘制通过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; } 

这里有一些在你的代码中跳出来的东西:

  1. 绘图数据需要可用于数据源。 最简单的方法是将两个内容数组存储在实例variables中,以便在整个类中可见,而不是在完成-constructScatterPlot方法时消失的局部variables。

  2. 这两个地块总是有相同数量的积点? 如果不是,请在-numberOfRecordsForPlot:检查graphics的标识符,并返回每个graphics的正确计数。

      -(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; } 
  3. 您的数据源可以大大简化(我的例子使用您的原始数据结构):

     -(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")]; } 
  4. 你的内容数组是否包含期望值? 你真的需要存储索引吗? 除非你需要其他的东西,否则我只是简单地将closures值存储在内容数组中,忘记字典结构。 在这种情况下,数据源方法变成:

     -(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; }