核心情节,无法绘制两个图 [英] core-plot, unable to plot two graphs

查看:106
本文介绍了核心情节,无法绘制两个图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试使用核心图库来绘制我通过JSON获得的一些数据。我试图在同一个图表上绘制两个图,但我无法实现这一点。当我只绘制一个图表时,它可以正常工作。

I'm currently trying to use the core-plot library to graph some data I get via JSON. I'm trying to plot two graphs on the same chart but am unable to achieve this. When I simply plot just one chart, it works correctly.

下面是我使用核心图库的散点图代码。

Below is my scatter plot code using the core-plot library.

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


推荐答案

以下是一些事情在你的代码中向我跳了出来:

Here are a few things that jumped out at me in your code:


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

  1. The plot data needs to be available for the datasource. The easiest way would be to store the two content arrays in instance variables so they are visible throughout the class rather than in local variables that go away when the -constructScatterPlot method is finished.

这两个情节总是有相同数量的情节点吗?如果没有,请检查 -numberOfRecordsForPlot:中的图标识符,并为每个标识符返回正确的计数。

Do both plots always have the same number of plot points? If not, check the plot's identifier in -numberOfRecordsForPlot: and return the correct count for each one.

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


  • 您的数据源可以大大简化(我的示例使用您的原始数据)结构):

  • Your datasource could be greatly simplified (my example uses your original data structure):

    -(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值存储在内容数组中而忘记字典结构。在这种情况下,数据源方法变为:

  • Do your content arrays contain the expected values? Do you really need to store the index? Unless you need that for something else, I would simply store the close value in the content array and forget about the dictionary structure. In this case the datasource method becomes:

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


  • 这篇关于核心情节,无法绘制两个图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆