加入核心散点图中的缺失点

时间:2014-08-05 11:15:01

标签: ios objective-c core-plot

我在同一绘图区域有一个包含多个散点图的图形。 X轴始终固定为1-31个月的日期。有些日子里没有y值(正如你在图片中看到的那样)......但我需要逐行加入这些点(例如:点1和12然后是12和16 ......)。 / p>

图片:enter image description here

这是我作为情节记录传递的数组

arrType1 = [[NSMutableArray alloc]initWithObjects:@"123",[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],@"234",[NSNull null],@"34",@"69",[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],@"45",[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],@"23", nil];

核心图数据源方法

#pragma mark - CPTPlotDataSource methods
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
    return [[[CPDStockPriceStore sharedInstance] datesInMonth] count];
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
NSInteger valueCount = [[[CPDStockPriceStore sharedInstance] datesInMonth] count];
switch (fieldEnum) {
    case CPTScatterPlotFieldX:
        if (index < valueCount) {
            return [NSNumber numberWithUnsignedInteger:index];
        }
        break;

    case CPTScatterPlotFieldY:
        if ([plot.identifier isEqual:CPDTickerSymbolAAPL] == YES) {

            return [arrType1 objectAtIndex:index];
        }

        else if ([plot.identifier isEqual:CPDTickerSymbolGOOG] == YES) {

            return [arrType2 objectAtIndex:index];
        }

        else if ([plot.identifier isEqual:CPDTickerSymbolMSFT] == YES) {

            return [arrType3 objectAtIndex:index];
        }
        break;
}
    return [NSDecimalNumber zero];
}

我该怎么办?任何想法......

3 个答案:

答案 0 :(得分:1)

我认为您不了解Coreplot的工作原理。您不需要为每个x坐标提供值。您只需为Coreplot提供要添加的数据点的x和相应的y坐标。 您使用的是绘图数据源实现吗?如果是,请发布您的实施。

作为快速修复,只需在数组中省略NSNull实例,这些点就会连接起来。

基本上可以说你有3个Datapoints:

  1. x = 1 and y = 31
  2. x = 15 and y = 20
  3. x= 25 and y=22
  4. 为了做到这一点,您只需要将这3个图表添加到图表中,而不需要其他任何内容。为此,您可以将它们添加到字典数组中(就像在核心绘图示例项目中完成的那样!)

    NSMutableArray *theDataPoints = [NSMutableArray new];
    [theDataPoints addObject:@{@"x": @(1),@"y" : @(31)}];
    [theDataPoints addObject:@{@"x": @(15),@"y" : @(20)}];
    [theDataPoints addObject:@{@"x": @(25),@"y" : @(22)}];
    

    然后在您的数据源方法中返回数组的计数作为NumberOfRecords:

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

    并在numberForPlot:field:recordIndex:函数中:

    首先按索引访问theDataPoints数组:

    NSDictionary *currentDataPoint = [theDataPoints objectAtIndex:index];
    

    然后计算正确的Dictionary Key to Access(无论您是在寻找X还是Y值)

    NSString *theKey;
    if(fieldEnum == CPTScatterPlotFieldX){
        theKey = @"x";
    }
    else if(fieldEnum == CPTScatterPlotFieldY){
        theKey = @"y";
    }
    else{
        //throw an Error here
    }
    

    并最终获得您要从NSNumberNSDictionary返回的return

    NSNumber *theNumber = [currentDataPoint objectForKey:theKey];
    return theNumber;
    

    这将产生您想要的图表,只显示3个数据点并且所有数据点都已连接。

    旁注。由于您的Plot基本上显示了与日期相关的值,因此您可能希望查看随Framework下载提供的Coreplot示例工作区中的DatePlot示例。

    无论如何,我希望我能提供帮助。

答案 1 :(得分:0)

我只考虑一个选项:从原始数据数组创建另一个数组,其中null对象将被右值替换,以便在点之间绘制一条线,并且此数组将用于核心图数据源:

//original array:
arrType1 = [[NSMutableArray alloc] initWithObjects:@"123",[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],@"234",[NSNull null],@"34",@"69",[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],@"45",[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],[NSNull null],@"23", nil];

//datasource array:
dataSourceArray = [[NSMutableArray alloc] initWithObjects:@(123),@(123 + ((234-123)/11)*1),@(123 + ((234-123)/11)*2),@(123 + ((234-123)/11)*3),@(123 + ((234-123)/11)*4),@(123 + ((234-123)/11)*5),@(123 + ((234-123)/11)*6),@(123 + ((234-123)/11)*7),...,@(234),..., nil]; 
//11 is the number of first null intervals.

您需要根据以上示例编写通用算法。

答案 2 :(得分:0)

您遇到的问题来自对recordIndex回调中numberForPlot:field:recordIndex:的含义的误解。它可以总结如下:recordIndex x。相反,此方法要求您将recordIndex,索引到相应的记录中,然后返回x 的值(假设它要求{{1}你可能需要以某种方式计算。

这也是我的意思,尽管事后看来这是令人尴尬的。如果您在Core Plot上遵循Ray Wenderlich教程,那么在请求CPTScatterPlotFieldX时,这些教程始终返回recordIndex。这就是为什么我一直认为CPTScatterPlotFieldXrecordIndex(显然很多人对Core Plot不熟悉)。但是你可以返回任何你想要的价值。