Question

I'm using core plot to make a real time graph. The values come from a webservice, but only 45 values are supplied, then it must stop. I got the sample of real time plot of core plot 1.4, and it's almost working.

I have two problems, my graph is fixed at 0,0 and my y axis disappeared. The graph is correctly inputting data at the array of values (axis X). The array of dates (axis Y) is different of the array of values. Also, before this I got the graph working without animation.

Here's my code so far, I believe all that is needed is there:

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


    -(void)newData:(NSTimer *)theTimer
    {
        //    CPTGraph *theGraph = [self.graphs objectAtIndex:0];
        CPTPlot *thePlot   = [self.hostView.hostedGraph plotWithIdentifier:CPDTickerSymbolGOOG];

    if ( thePlot ) {
        if ( plotData.count >= kMaxDataPoints ) {
            [plotData removeObjectAtIndex:0];
            [thePlot deleteDataInIndexRange:NSMakeRange(0, 1)];

            [dataTimer invalidate];
            return;
        }

        CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.hostView.hostedGraph.defaultPlotSpace;
        NSUInteger location       = (currentIndex >= kMaxDataPoints ? currentIndex - kMaxDataPoints + 2 : 0);

        CPTPlotRange *newRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(location)
                                                              length:CPTDecimalFromUnsignedInteger(kMaxDataPoints - 2)];

        [CPTAnimation animate:plotSpace
                     property:@"xRange"
                fromPlotRange:plotSpace.xRange
                  toPlotRange:newRange
                     duration:(1.0 / kFrameRate)];

        currentIndex++;
        NSLog(@"%@",plotData);

        [plotData addObject:[arrValues lastObject]];
        [arrValues removeObjectAtIndex:[arrValues count] -1];
        [thePlot insertDataAtIndex:plotData.count - 1 numberOfRecords:1];
    }
    }

    -(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
        NSInteger valueCount = [[self datesInMonth]count];

    //  switch (fieldEnum) {
    //      case CPTScatterPlotFieldX:
    //          if (index < valueCount) {
    //              return [NSNumber numberWithUnsignedInteger:index];
    //          }
    //          break;
    //          
    //      case CPTScatterPlotFieldY:
    //            
    //          if ([plot.identifier isEqual:CPDTickerSymbolAAPL] == YES) {
    //              return [[[CPDStockPriceStore sharedInstance] monthlyPrices:CPDTickerSymbolAAPL] objectAtIndex:index];
    //          } else if ([plot.identifier isEqual:CPDTickerSymbolGOOG] == YES) {
    //              return [[[CPDStockPriceStore sharedInstance] monthlyPrices:CPDTickerSymbolGOOG] objectAtIndex:index];
    //          } else if ([plot.identifier isEqual:CPDTickerSymbolMSFT] == YES) {
    //              return [[[CPDStockPriceStore sharedInstance] monthlyPrices:CPDTickerSymbolMSFT] objectAtIndex:index];
    //          }
    //          break;
    //  }

    NSNumber *num = nil;

    switch ( fieldEnum ) {
        case CPTScatterPlotFieldX:
            num = [NSNumber numberWithUnsignedInteger:index + currentIndex - plotData.count];
            break;

        case CPTScatterPlotFieldY:
            num = [plotData objectAtIndex:index];
            break;

        default:
            break;
    }

    return num;


    return [NSDecimalNumber zero];
    }

    -(void)configureAxes {

    // 1 - Create styles
    CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
    axisTitleStyle.color = [CPTColor whiteColor];
    axisTitleStyle.fontName = @"Helvetica-Bold";
    axisTitleStyle.fontSize = 16.0f;

    CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
    axisTextStyle.fontName = @"Helvetica";
    axisTextStyle.fontSize = 12.0f;

    CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
    axisLineStyle.lineWidth = 0.5f;
    axisLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.4];

    CPTMutableLineStyle *tickLineStyle = [CPTMutableLineStyle lineStyle];
    tickLineStyle.lineColor = [CPTColor whiteColor];
    tickLineStyle.lineWidth = 0.0f;

    CPTMutableLineStyle *majorGridLineStyle = [CPTMutableLineStyle lineStyle];
    majorGridLineStyle.lineWidth = 1.0;
    majorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.4];

    CPTMutableLineStyle *minorGridLineStyle = [CPTMutableLineStyle lineStyle];
    minorGridLineStyle.lineColor = [CPTColor whiteColor];
    minorGridLineStyle.lineWidth = 1.0f;
    // 2 - Get axis set

    CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.hostView.hostedGraph.axisSet;

    // 3 - Configure x-axis
    CPTXYAxis *x = axisSet.xAxis;
    x.orthogonalCoordinateDecimal = CPTDecimalFromInteger(0);
    //x.title = @"Day of Month";
    x.titleTextStyle = axisTitleStyle;
    x.titleOffset = 15.0f;
    x.axisLineStyle = axisLineStyle;
    //    x.majorGridLineStyle = majorGridLineStyle;


    x.labelingPolicy = CPTAxisLabelingPolicyNone;


    x.majorTickLineStyle = axisLineStyle;
    x.majorTickLength = 30.0f;
    x.tickDirection = CPTSignNegative;
    //x.labelOffset = -25;

    CGFloat dateCount = 1;
    NSMutableSet *xLabels = [NSMutableSet setWithCapacity:dateCount];
    NSMutableSet *xLocations = [NSMutableSet setWithCapacity:dateCount];
    NSInteger i = 0;

    //    NSLog(@"datesInMonth - >%@",[self datesInMonth]);

    NSArray *_weekDays = @[@"", @"D", @"S", @"T", @"Q", @"Q", @"S", @"S"];

    int z = 0;
    for (NSString *date in [self datesInMonth]) {

        int contador = i++;
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"dd/MM/yyyy"];

        NSString *dateTimeString = [date stringByAppendingString:@"12:00:00"];
        const char* dateString = [dateTimeString UTF8String];
        struct tm tm;
        time_t timestamp;
        strptime(dateString, "%d/%m/%Y %H:%M:%S", &tm);
        timestamp = mktime(&tm);

        NSDate *myDate = [NSDate dateWithTimeIntervalSince1970:timestamp];
        NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay |
                                                                                NSCalendarUnitMonth |
                                                                                NSCalendarUnitYear fromDate:myDate];

        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSRange weekdayRange = [calendar maximumRangeOfUnit:NSWeekdayCalendarUnit];
        NSDateComponents *_components = [calendar components:NSWeekdayCalendarUnit fromDate:myDate];
        NSUInteger weekdayOfDate = [_components weekday];

        if (weekdayOfDate == weekdayRange.location || weekdayOfDate == weekdayRange.length) {
            axisTextStyle.color = [CPTColor orangeColor];

            CPTPlotRange *bandRange;
            bandRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble((double)z-1) length:CPTDecimalFromDouble(1)];

            CPTColor *areaColor       = [CPTColor colorWithComponentRed:1.0 green:1.0 blue:1.0 alpha:0.1];
            CPTColor *areaColorEnd       = [CPTColor colorWithComponentRed:1.0 green:1.0 blue:1.0 alpha:1.0];
            CPTGradient *areaGradient = [CPTGradient gradientWithBeginningColor:areaColor endingColor:areaColorEnd];
            areaGradient.angle = -90.0f;
            CPTFill *areaGradientFill = [CPTFill fillWithGradient:areaGradient];

            areaGradient.angle                = -90.0f;
            areaGradientFill                  = [CPTFill fillWithGradient:areaGradient];

            [x addBackgroundLimitBand:[CPTLimitBand limitBandWithRange:bandRange fill:areaGradientFill]];

        } else {
            axisTextStyle.color = [CPTColor whiteColor];
        }

        axisTextStyle.textAlignment = CPTAlignmentCenter;
        x.labelTextStyle = axisTextStyle;

        CPTAxisLabel *label = [[CPTAxisLabel alloc]
                               initWithText:[NSString stringWithFormat:@"%i\n%@",[components day], _weekDays[weekdayOfDate]]
                                  textStyle:x.labelTextStyle];

        label.alignment = CPTAlignmentRight;
        NSDecimal location = CPTDecimalFromInteger(contador);


        label.tickLocation = CPTDecimalFromCGFloat(contador);
        //label.offset = x.majorTickLength - 10;

        if (label){
            [xLabels addObject:label];
        }

        [xLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:location]];

        z++;
    }

    axisTextStyle.color = [CPTColor whiteColor];
    axisTextStyle.textAlignment = CPTAlignmentCenter;
    x.axisLabels = xLabels;
    x.majorTickLocations = xLocations;

    CPTXYAxis *y = axisSet.yAxis;
    //  y.title = @"";
        y.titleTextStyle = axisTitleStyle;
    //  y.titleOffset = -40.0f;
        y.axisLineStyle = axisLineStyle;
        y.majorTickLineStyle = axisLineStyle;
    //  y.minorTickLineStyle = nil;
        y.majorGridLineStyle = majorGridLineStyle;
    //  y.minorGridLineStyle = minorGridLineStyle;
        y.labelingPolicy = CPTAxisLabelingPolicyNone;
        y.labelTextStyle = axisTextStyle;
        y.labelOffset = 36.0f;
        //y.majorTickLineStyle = axisLineStyle;
        //y.majorTickLength = 4.0f;
        //y.minorTickLength = 1.0f;
        y.gridLinesRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-1.0f) length:CPTDecimalFromFloat(45.0f)];
        y.tickDirection = CPTSignPositive;

        NSInteger majorIncrement = 10000000;
        NSInteger minorIncrement = 10000000;
        CGFloat yMax = 180000000;  // should determine dynamically based on max price
        NSMutableSet *yLabels = [NSMutableSet set];
    //  NSMutableSet *yMajorLocations = [NSMutableSet set];
    //  NSMutableSet *yMinorLocations = [NSMutableSet set];
        NSMutableSet *yLocations = [NSMutableSet set];

        for (NSInteger j = minorIncrement; j <= yMax; j += minorIncrement) {
            NSUInteger mod = j % majorIncrement;

            NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init];
            [numFormatter setNumberStyle:NSNumberFormatterDecimalStyle];

            if (mod == 0) {
                CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[numFormatter stringFromNumber:[NSNumber numberWithInt:j]] textStyle:y.labelTextStyle];
                NSDecimal location = CPTDecimalFromInteger(j);
                label.tickLocation = location;
                label.offset = -y.majorTickLength - y.labelOffset - 60;

                if (label) {
                    [yLabels addObject:label];
                }
                [yLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:location]];

            }
        }
        y.axisLabels = yLabels;
    //  y.majorTickLocations = yMajorLocations;
    //  y.minorTickLocations = yMinorLocations;
        y.majorTickLocations = yLocations;

    }
Was it helpful?

Solution

You should use constraints to position the y-axis so it doesn't move as the graph scrolls.

y.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];

What is the value of kMaxDataPoints? If it's greater than the number of data points, the graph won't scroll.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top