2012-07-05 60 views
1

我已經查看了大多數似乎最相關的問題,但他們中沒有一個真正涉及到我目前有點麻煩。我的問題是,儘管我知道我需要更新plotSpace.xRange,不管我如何更新它,要麼沒有任何反應,要麼我會崩潰。CorePlot:更新實時繪製的X軸範圍

我現在正在做的是我有2個全局變量(xMinVal,xMaxVal)聲明在我的RealTimeScatterPlot.m文件中,而這些就是我在繪圖初始化時使用的plotSpace.xRange計算。然後,我的視圖控制器託管劇情視圖包含一個函數,每秒生成一個隨機點並繪製。在這個函數內部,我會追蹤我是否有超過25個點(我的默認x軸範圍從0到50),如果我這樣做,我嘗試將RealTimeScatterPlot.m中的全局值增加1,應該在理論上將我的圖的觀點轉移1.第一次增加會發生,儘管視圖沒有改變,我也不能再次增加,因爲值保持不變。如果看到代碼會讓我知道,我會編輯它,但它的所有非常簡單/通用。我在想,不是編碼問題,這可能不是我應該實現的方式。

任何有識之士將非常感激!

回答

4

你可以做你想做的事情,就像tableview數據更新一樣簡單。 這裏是代碼的一部分,我已經做了你可以使用它作爲參考。希望這可以幫助你。

-(void) fetchArrayOffeedback { 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Pulse" 
               inManagedObjectContext:appDelegate.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    NSPredicate *predictate = [NSPredicate predicateWithFormat:@"sessionKey == %@", appDelegateiPhone.strSessionId]; 

    [fetchRequest setPredicate:predictate]; 

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] 
           initWithKey:@"date" ascending:YES]; 
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]]; 
    [sort release]; 

    NSError *error; 

    chartData = (NSMutableArray*)[appDelegate.managedObjectContext 
              executeFetchRequest:fetchRequest error:&error]; 

    [chartData retain]; 
    NSLog(@"array count :%d", [chartData count]); 

    [graph reloadData]; 

    CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace; 
    plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0) length:CPDecimalFromFloat(fiveHour*3)]; 
} 

- (void)constructScatterPlotForFeedback 
{ 
    [graph release]; 

    graph = [[CPXYGraph alloc] initWithFrame:CGRectZero]; 
    graph.delegate = self; 
    CPTheme *theme = [CPTheme themeNamed:kCPPlainWhiteTheme]; 
    [graph applyTheme:theme]; 
    feedbackChart.hostedGraph = graph; 
    [feedbackChart setBackgroundColor:[UIColor clearColor]]; 

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

    graph.plotAreaFrame.paddingLeft = 5.0; 
    graph.plotAreaFrame.paddingTop = 10.0; 
    graph.plotAreaFrame.paddingRight = 10.0; 
    graph.plotAreaFrame.paddingBottom = 10.0; 

    NSTimeInterval oneHour = 60 * 60; 

    CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace; 
    plotSpace.allowsUserInteraction = YES; 
    plotSpace.delegate = self; 

    float xRange; 
    xRange = [chartData count] + 1.0; 

    if (xRange>5) { 
     xRange = 5.0; 
    } 
    plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0) length:CPDecimalFromFloat(fiveHour*3)]; 
    plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-20.0) length:CPDecimalFromFloat(40.0)]; 


    CPLineStyle *gridline = [CPLineStyle lineStyle]; 
    gridline.lineColor = [CPColor grayColor]; 
    gridline.lineWidth = 1.0f; 

    CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet; 
    CPXYAxis *x = axisSet.xAxis; 
    x.majorIntervalLength = CPDecimalFromFloat(fiveHour); 
    x.minorTicksPerInterval = 0; 
    x.labelOffset=0; 

    NSDate *refDate = [NSDate date]; 
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; 

    dateFormatter.dateFormat = @"HH:mm:ss"; 

    CPTimeFormatter *timeFormatter = [[[CPTimeFormatter alloc] initWithDateFormatter:dateFormatter] autorelease]; 
    timeFormatter.referenceDate = refDate; 
    x.labelFormatter = timeFormatter; 

    CPXYAxis *y = axisSet.yAxis; 

    y.minorTicksPerInterval = 0; 
    y.orthogonalCoordinateDecimal = CPDecimalFromString(@"0.0"); 
    y.majorIntervalLength = CPDecimalFromString(@"5"); 
    y.majorGridLineStyle = nil; 

    y.visibleRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-20.0f) length:CPDecimalFromFloat(40.0f)]; 
    CPConstraints yConstraints = {CPConstraintNone, CPConstraintFixed}; 
    y.isFloatingAxis=YES; 
    y.constraints=yConstraints; 

    CPScatterPlot *dataSourceLinePlot = [[[CPScatterPlot alloc] init] autorelease]; 
    dataSourceLinePlot.identifier = @"FeedBack Plot"; 
    dataSourceLinePlot.dataLineStyle.lineWidth = 3.f; 
    dataSourceLinePlot.dataLineStyle.lineColor = [CPColor blackColor]; 
    dataSourceLinePlot.dataLineStyle.dashPattern = [NSArray arrayWithObjects:[NSNumber numberWithFloat:1.0f], [NSNumber numberWithFloat:1.0f], nil]; 
    dataSourceLinePlot.dataSource = self; 

    dataSourceLinePlot.opacity = 0.0f; 
    dataSourceLinePlot.cachePrecision = CPPlotCachePrecisionDecimal; 

    CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
    fadeInAnimation.duration = 1.0f; 
    fadeInAnimation.removedOnCompletion = NO; 
    fadeInAnimation.fillMode = kCAFillModeForwards; 
    fadeInAnimation.toValue = [NSNumber numberWithFloat:1.0]; 
    [dataSourceLinePlot addAnimation:fadeInAnimation forKey:@"animateOpacity"]; 

    CPColor *areaColor1 = [CPColor colorWithComponentRed:0.3 green:0.3 blue:1.0 alpha:0.8]; 
    CPGradient *areaGradient1 = [CPGradient gradientWithBeginningColor:areaColor1 endingColor:[CPColor clearColor]]; 
    areaGradient1.angle = -90.0f; 

    NSUInteger i; 

    [graph addPlot:dataSourceLinePlot]; 

    NSMutableArray *contentArray1 = [NSMutableArray arrayWithCapacity:100]; 

    NSMutableArray *customTickLocations = [[NSMutableArray alloc] init]; 
    NSMutableArray *xAxisLabels = [[NSMutableArray alloc] init]; 
    for (i = 0; i < [chartData count]; i++) { 
    //for (i = 0; i < 10; i++) { 
     [customTickLocations addObject:[NSDecimalNumber numberWithInt:i]]; 
     [xAxisLabels addObject:[NSString stringWithFormat:@"%0.1f", 5.0 * i]]; 
     Pulse *objPulse1 = (Pulse *)[chartData objectAtIndex:i]; 
//  id x = [NSNumber numberWithFloat:i*fiveHour]; 
     id x = [NSNumber numberWithFloat:i]; 
     id y = [NSNumber numberWithFloat:[objPulse1.feedBack floatValue]]; 
     NSLog(@"point of gragh for Performance x:%@, y : %@ ", x, y); 
     [contentArray1 addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, @"x", y, @"y", nil]]; 
    } 

    NSLog(@"Axis lable count : %d", [xAxisLabels count]); 
    NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[chartData count]]; 
    NSUInteger labelLocation = 0; 

    for (NSNumber *tickLocation in customTickLocations) { 
     NSLog(@">>>>>>>>>>>>>>>>> tick location"); 
     CPAxisLabel *newLabel = [[CPAxisLabel alloc] initWithText: [xAxisLabels objectAtIndex:labelLocation++] textStyle:x.labelTextStyle]; 
     newLabel.tickLocation = [tickLocation decimalValue]; 
     newLabel.offset = x.labelOffset + x.majorTickLength - 5.0f; 
     newLabel.rotation = 0; 
     [customLabels addObject:newLabel]; 
     [newLabel release]; 
    } 

    x.axisLabels = [NSSet setWithArray:customLabels]; 

    arrScatter = contentArray1; 
    [arrScatter retain]; 
} 

-(NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot 
{ 

    if ([(NSString *)plot.identifier isEqualToString:@"FeedBack Plot"]) { 
     return [chartData count]; 
    } 

    return 0; 
} 

-(NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{ 
    switch (fieldEnum) { 
     case CPScatterPlotFieldX: 
      return (NSDecimalNumber *)[NSDecimalNumber numberWithUnsignedInteger:index*fiveHour]; 
     case CPScatterPlotFieldY: 
     { 
      Pulse *objPulse1 = (Pulse *)[chartData objectAtIndex:index]; 
      return [NSNumber numberWithFloat:[objPulse1.feedBack floatValue]];   
     } 
    } 
    return nil; 
} 

-(CGPoint)plotSpace:(CPPlotSpace *)space willDisplaceBy:(CGPoint)displacement { 

    return CGPointMake(displacement.x, 0); 
} 


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

    if ([(NSString *)plot.identifier isEqualToString:@"FeedBack Plot"]) { 
     if ([arrScatter count] != 0) { 
      num = [[arrScatter objectAtIndex:index] valueForKey:(fieldEnum == CPScatterPlotFieldX ? @"x" : @"y")]; 
     } 
    } 
    return num; 
} 
*/ 

-(CPLayer *)dataLabelForPlot:(CPPlot *)plot recordIndex:(NSUInteger)index { 

     Pulse *objPulse1 = (Pulse *)[chartData objectAtIndex:index]; 
     float value = [objPulse1.feedBack floatValue];  
     //CPTextLayer *textLayer = [[CPTextLayer alloc] initWithText:[NSString stringWithFormat:@"%d", value]]; 

     CPTextStyle *textStyle = [CPTextStyle textStyle]; 
     textStyle.color = [CPColor blackColor]; 

     CPTextLayer *textLayer = [[CPTextLayer alloc] initWithText:[NSString stringWithFormat:@"%0.1f", value] style:textStyle]; 
     return textLayer; 
} 
+0

我的解決辦法結束不完全是看起來像,但似乎是一個相當完整的答案。 – 2012-07-12 15:42:05

+0

@KarolyS你可以用解決方案添加你自己的答案,我在完全相同的麻煩中運行。 – 2014-05-21 18:56:17

+0

@ Roma-MT我可以看到,如果我能在第二天左右爲你找到我的解決方案,不幸的是,很久以前,我不太記得我的解決方案。 – 2014-05-21 19:12:05

1

我子類真正的繪圖表是這樣的:

注:我沒有把我用在這裏繪製標籤,並決定一些方法涼圖形 的我把本代碼來顯示創建實時情節的想法。

在my.h

#import <CorePlot/CorePlot.h> 
#import <Cocoa/Cocoa.h> 
#import "sharedPrefferences.h" 
#import "RMBlurredView.h"//Not really needed I am just using it for my custom label 
@interface GenericCPTGraphView : NSView <CPTPlotDataSource,CPTPlotSpaceDelegate> 
{ 

    CPTGraphHostingView *hostView; 
    CPTXYGraph *graph; 
    NSMutableArray *plotData; 
    NSTextField* percentLabel; 
    CPTMutableLineStyle *lineStyle; 
    CPTScatterPlot *dataSourceLinePlot; 
    NSInteger currentIndex; 
    NSTimer* dataTimer; 
    BOOL animated; 
} 

-(void)updateGraph :(NSNumber*)Load;//method that will add the new Dots to the plot. 
@end 

在my.m

#define SECTION_COUNT 15 //maybe will be changed to 16 who knows. 

static const double kAlpha  = 0.25; // smoothing constant 

static const NSUInteger kMaxDataPoints = 40; 
static NSString *const kPlotIdentifier = @"Data Source Plot"; 
@implementation GenericCPTGraphView 

- (id)initWithFrame:(NSRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
     plotData = [[NSMutableArray alloc] initWithCapacity:kMaxDataPoints]; 
     [self generateData];//create plot method 
     [self checkGraph]; 
    } 
    return self; 
} 


-(void)checkGraph 
{ 
    currentIndex=0; 
    NSDate *refDate  = [NSDate dateWithNaturalLanguageString:@"12:00 Oct 29, 2009"]; 
    NSTimeInterval oneDay = 1; 
    // Create graph from theme 
    graph = [[CPTXYGraph alloc] initWithFrame:CGRectZero]; 
    CPTTheme *theme = [CPTTheme themeNamed:kCPTSlateTheme]; 
    [graph applyTheme:theme]; 
    graph.paddingLeft = 1.0; 
    graph.paddingTop = 1.0; 
    graph.paddingRight = 1.0; 
    graph.paddingBottom = 1.0; 
    graph.fill = [CPTFill fillWithColor:[CPTColor clearColor]]; 
    graph.plotAreaFrame.fill = [CPTFill fillWithColor:[self getCPTColorObjectFromHexString:@"062118" alpha:1.0]]; 
    graph.plotAreaFrame.borderLineStyle = nil; 
    graph.plotAreaFrame.cornerRadius = 0; 
    hostView = [[CPTGraphHostingView alloc]initWithFrame:CGRectMake(0,0,self.frame.size.width,self.frame.size.height)]; 
    hostView.hostedGraph = graph; 
    RMBlurredView *LabelView = [[RMBlurredView alloc]initWithFrame:CGRectMake(1,0+hostView.frame.size.height-16 , hostView.frame.size.width-2, 15)]; 
    [LabelView setTintColor:[sharedPrefferences colorWithHexColorString:@"000000" alpha:0.5]]; 
    NSTextField* textLabel = [[NSTextField alloc]initWithFrame:CGRectMake(0, 1,  LabelView.frame.size.width, 15)]; 
    dataSourceLinePlot.identifier  = (__bridge id<NSCopying,NSCoding,NSObject>)(kMDItemIdentifier); 
    [textLabel setTextColor:[NSColor whiteColor]]; 
    // textLabel 
    [textLabel setBezeled:NO]; 
    [textLabel setDrawsBackground:NO]; 
    [textLabel setEditable:NO]; 
    [textLabel setSelectable:NO]; 
    [textLabel setStringValue:@"LOAD"]; 
    [textLabel sizeToFit]; 
    percentLabel = [[NSTextField alloc]initWithFrame:CGRectMake(0, 1, LabelView.frame.size.width, 15)]; 
    [percentLabel setTextColor:[NSColor whiteColor]]; 
    [percentLabel setBezeled:NO]; 
    [percentLabel setDrawsBackground:NO]; 
    [percentLabel setEditable:NO]; 
    [percentLabel setSelectable:NO]; 
    // [percentLabel setStringValue:@"X%"]; 
    //[percentLabel sizeToFitWithAlignmentRight]; 
    LabelView.blurRadius = 0; 
    dataSourceLinePlot = [[CPTScatterPlot alloc] init]; 
    dataSourceLinePlot.dataSource = self; 
    [graph addPlot:dataSourceLinePlot]; 
    // Setup scatter plot space 
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace; 
    plotSpace.allowsUserInteraction = NO; 
    plotSpace.delegate = self; 
    CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
    fadeInAnimation.duration = 1.0f; 
    fadeInAnimation.removedOnCompletion = NO; 
    fadeInAnimation.fillMode = kCAFillModeForwards; 
    fadeInAnimation.toValue = [NSNumber numberWithFloat:1.0]; 
    [dataSourceLinePlot addAnimation:fadeInAnimation forKey:@"animateOpacity"]; 
    [graph addPlot:dataSourceLinePlot]; 
    NSTimeInterval xLow  = 0.0; 
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(xLow) length:CPTDecimalFromDouble(oneDay * 40.0)]; 
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(100.0)]; 
    // Axes 
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet; 
    CPTXYAxis *x   = axisSet.xAxis; 
    x.hidden = YES; 
    x.majorIntervalLength   = CPTDecimalFromFloat(oneDay); 
    x.orthogonalCoordinateDecimal = CPTDecimalFromDouble(0.0); 
    x.minorTicksPerInterval  = 0; 
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
    dateFormatter.dateStyle = kCFDateFormatterShortStyle; 
    CPTTimeFormatter *timeFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter]; 
    timeFormatter.referenceDate = refDate; 
    x.labelFormatter   = timeFormatter; 
    CPTXYAxis *y = axisSet.yAxis; 
    y.hidden = YES; 
    y.majorIntervalLength   = CPTDecimalFromDouble(0.5); 
    y.minorTicksPerInterval  = 1; 
    y.orthogonalCoordinateDecimal = CPTDecimalFromFloat(oneDay); 
    // Create a plot that uses the data source method 
    //CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init]; 
    y.minorTicksPerInterval = 0; 
    [LabelView addSubview:percentLabel]; 
    [LabelView addSubview:textLabel]; 
    [graph.hostingView addSubview:LabelView]; 
    [self addSubview:hostView]; 
} 

-(void)updateGraph :(NSNumber*)Load 
{  
    if (dataSourceLinePlot) { 
     if (plotData.count >= 40) { 
      [plotData removeObjectAtIndex:0]; 
      [dataSourceLinePlot deleteDataInIndexRange:NSMakeRange(0, 1)]; 
     } 
     CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace; 
     plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(0) length:CPTDecimalFromUnsignedInteger(kMaxDataPoints - 2)]; 
     plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(0) length:CPTDecimalFromUnsignedInteger(1)]; 
     NSUInteger location  = (currentIndex >= kMaxDataPoints ? currentIndex - kMaxDataPoints + 2 : 0); 
     CPTPlotRange *newRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(location) 
                  length:CPTDecimalFromUnsignedInteger(kMaxDataPoints - 2)]; 
    plotSpace.xRange = newRange; 
    currentIndex++; 
    [plotData addObject:[NSNumber numberWithDouble:((Load.doubleValue - kAlpha)/100.0)]]; 
    [percentLabel setStringValue:[NSString stringWithFormat:@"%ld%%",(Load.integerValue) ]]; 
    graph.borderWidth = 0.0 ; 
    dataSourceLinePlot.borderWidth = 0.0; 
    [dataSourceLinePlot setBorderWidth:0.0]; 
    dataSourceLinePlot.identifier = @"Date Plot"; 
    lineStyle = [dataSourceLinePlot.dataLineStyle mutableCopy]; 
    lineStyle.lineWidth    = 2.0; 
    [percentLabel sizeToFitWithAlignmentRight]; 
    lineStyle.lineColor = [self decideColor: [self numberOfSectionsToHighlight:Load.doubleValue]]; 
    dataSourceLinePlot.dataLineStyle = lineStyle; 
    [dataSourceLinePlot insertDataAtIndex:(plotData.count - 1) numberOfRecords:1];//inserting object to the plot. 
} 

}

#pragma mark - 
#pragma mark Plot Data Source Methods 

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot 
{ 
    NSLog(@"%lu",(unsigned long)plotData.count); 
    return plotData.count; 
} 
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{ 
    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; 
} 
@end