2016-08-12 10 views
0

縦棒グラフサンプルを使用して、y値が0..1、x値が1..nのグラフを作成しましたが、データソースのCPTBarPlotFieldBarLocationセルに指定されたxラベルインデックスは表示されません。私はy軸のラベルを使用しません。core-plot x軸ラベルは表示されません。

私はそれらをクリッピングしていると思われます。古いIBのように、さまざまなグラフ領域の境界線を描く方法はありますか?

x軸プロットラベルは、例のように数値でない文字列です。私は何を壊しましたか?目に見える手がかりがあった場合はここに私のセットアップ

// 
// InfoBarView.m 

#import "InfoBarView.h" 

// Item index to color mapping for legend symbols not item related 
static NSUInteger fldMapping[] = { 5, 6, 7, 0 }; 

static const BOOL kUseHorizontalBars = NO; 

static NSArray <__kindof NSString *> const* kTargets = nil; 
static NSArray <__kindof NSString *> const* kGetters = nil; 

@interface BarChart() 
@property (nonatomic, readwrite, strong, nullable) CPTPlotSpaceAnnotation * symbolTextAnnotation; 
@end 

@implementation BarChart 
@synthesize symbolTextAnnotation; 
@synthesize plotData; 

+ (void)initialize 
{ 
    kTargets = [@[ @"grpA" , @"grpB", @"grpC", @"grpD" ] retain]; 
    kGetters = [@[ @"fldA", @"fldB", @"fldC", @"fldD" ] retain]; 
} 

- (void)awakeFromNib 
{ 
    // Get our orig scaling 
    [super awakeFromNib]; 
} 

- (void)killGraph 
{ 
    if (self.graphs.count) 
    { 
     CPTGraph * graph = self.defaultGraph; 

     CPTPlotSpaceAnnotation *annotation = self.symbolTextAnnotation; 
     if (annotation) 
     { 
      [graph.plotAreaFrame.plotArea removeAnnotation:annotation]; 
      self.symbolTextAnnotation = nil; 
     } 
    } 

    [super killGraph]; 
} 

- (void)generateData 
{ 
    InfoBarView * barView = (id)[[self defaultLayerHostingView] superview]; 
    InfoController * controller = barView.controller; 
    NSUInteger rndx = controller.barDataRanking; 
    NSArray * rankings = @[ @"Rank", @"Runs" ]; 
    GroupItem * group = controller.group; 
    CPTGraph * graph = [self defaultGraph]; 

    CPTPlotSpaceAnnotation * annotation = self.symbolTextAnnotation; 
    if (annotation) 
    { 
     if (graph) 
     { 
      [graph.plotAreaFrame.plotArea removeAnnotation:annotation]; 
      self.symbolTextAnnotation = nil; 
     } 
    } 

    // Update X title with new controller index 
    if (graph) 
    { 
     graph.title = [NSString stringWithFormat:@"Past Performances by %@", rankings[rndx]]; 
    } 

    // Figure out our rank selector 
    NSString * rankSelectorName = [NSString stringWithFormat:@"%@%@Compare:", 
            kTargets[controller.barDataIndex], 
            rankings[rndx]]; 
    SEL dataRanking = NSSelectorFromString(rankSelectorName); 

    self.plotData = (id)[group.items sortedArrayUsingSelector:dataRanking]; 
} 

- (void)renderInGraphHostingView:(nonnull CPTGraphHostingView *)hostingView 
         withTheme:(nullable CPTTheme *)theme 
         animated:(BOOL)animated 
{ 
#if TARGET_OS_SIMULATOR || TARGET_OS_IPHONE 
    CGRect bounds = hostingView.bounds; 
#else 
    CGRect bounds = NSRectToCGRect(hostingView.bounds); 
#endif 
    InfoController * controller = ((InfoBarView *)hostingView.superview).controller; 
    CPTGraph * graph = [[[CPTXYGraph alloc] initWithFrame:bounds] autorelease]; 
    NSString * titles = @"fldA fldB fldC fldD"; 
    GroupItem * group = controller.group; 
    CPTBarPlot * barPlot; 

    // Initially we default by rank 
    self.title = @"Past Performances by Rank"; 

    [self addGraph:graph toHostingView:hostingView]; 

    graph.plotAreaFrame.masksToBorder = NO; 
    if (kUseHorizontalBars) 
    { 
     graph.plotAreaFrame.paddingBottom += self.titleSize; 
    } 
    else 
    { 
     graph.plotAreaFrame.paddingLeft += self.titleSize; 
    } 

    // Add plot space for bar charts 
    CPTXYPlotSpace * barPlotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace; 
    [barPlotSpace setScaleType:CPTScaleTypeCategory forCoordinate:CPTCoordinateX]; 
    if (kUseHorizontalBars) 
    { 
     barPlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:@(-10.0) length:@120.0]; 
     barPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:@(-1.0) length:@11.0]; 
    } 
    else 
    { 
     barPlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:@(-0.5) length:@(group.itemCount)]; 
     barPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:@(-0.05) length:@1.0]; 
    } 
    barPlotSpace.allowsUserInteraction = YES; 
    [graph addPlotSpace:barPlotSpace]; 
    barPlotSpace.delegate = self; 

    // Create grid line styles 
    CPTMutableLineStyle * majorGridLineStyle = [CPTMutableLineStyle lineStyle]; 
    majorGridLineStyle.lineWidth = 1.0; 
    majorGridLineStyle.lineColor = [[CPTColor grayColor] colorWithAlphaComponent:0.75]; 

    CPTMutableLineStyle * minorGridLineStyle = [CPTMutableLineStyle lineStyle]; 
    minorGridLineStyle.lineWidth = 1.0; 
    minorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.25]; 

    // Create axes 
    CPTXYAxisSet * axisSet = (CPTXYAxisSet *)graph.axisSet; 
    CPTXYAxis * x = axisSet.xAxis; 
    { 
     x.majorIntervalLength   = (kUseHorizontalBars ? @10.0 : @1.0); 
     x.minorTicksPerInterval   = (kUseHorizontalBars ? 9 : 0); 
     x.orthogonalPosition   = (kUseHorizontalBars ? @(-0.5) : @0.0); 

     x.majorGridLineStyle   = majorGridLineStyle; 
     x.minorGridLineStyle   = minorGridLineStyle; 
     x.axisLineStyle     = nil; 
     x.majorTickLineStyle   = nil; 
     x.minorTickLineStyle   = nil; 

     x.labelOffset = self.titleSize * CPTFloat(2.5); 
     if (kUseHorizontalBars) 
     { 
      x.visibleRange = [CPTPlotRange plotRangeWithLocation:@0.0 length:@10.0]; 
      x.gridLinesRange = [CPTPlotRange plotRangeWithLocation:@(-0.5) length:@(group.itemCount)]; 
     } 
     else 
     { 
      x.visibleRange = [CPTPlotRange plotRangeWithLocation:@(-0.5) length:@(group.itemCount)]; 
      x.gridLinesRange = [CPTPlotRange plotRangeWithLocation:@0.0 length:@(1.0)]; 
     } 
     x.plotSpace      = barPlotSpace; 
    } 

    CPTXYAxis * y = axisSet.yAxis; 
    { 
     y.majorIntervalLength   = (kUseHorizontalBars ? @1.0 : @10.0); 
     y.minorTicksPerInterval   = (kUseHorizontalBars ? 0 : 9); 
     y.orthogonalPosition   = (kUseHorizontalBars ? @0.0 : @(-0.5)); 

     y.preferredNumberOfMajorTicks = 8; 
     y.majorGridLineStyle   = majorGridLineStyle; 
     y.minorGridLineStyle   = minorGridLineStyle; 
     y.axisLineStyle     = nil; 
     y.majorTickLineStyle   = nil; 
     y.minorTickLineStyle   = nil; 
     y.labelOffset     = self.titleSize * CPTFloat(0.175); 
     y.titleLocation     = (kUseHorizontalBars ? @55.0 : @(group.itemCount-1)); 

     if (kUseHorizontalBars) 
     { 
      y.visibleRange = [CPTPlotRange plotRangeWithLocation:@(-0.5) length:@10.0]; 
      y.gridLinesRange = [CPTPlotRange plotRangeWithLocation:@0.0 length:@100.0]; 
     } 
     else 
     { 
      y.visibleRange = [CPTPlotRange plotRangeWithLocation:@(-0.5) length:@(group.itemCount)]; 
      y.gridLinesRange = [CPTPlotRange plotRangeWithLocation:@(-0.5) length:@(group.itemCount)]; 
     } 
     y.title       = titles; 
     y.titleOffset     = self.titleSize * CPTFloat(0.25); 
     [barPlotSpace addCategory:title[seg] forCoordinate:CPTCoordinateY]; 
     y.plotSpace      = barPlotSpace; 
    } 

    // Set axes 
    graph.axisSet.axes = @[x, y]; 

    // Create a shared bar line style 
    CPTMutableLineStyle * barLineStyle = [[[CPTMutableLineStyle alloc] init] autorelease]; 
    barLineStyle.lineWidth = 1.0; 
    barLineStyle.lineColor = [CPTColor whiteColor]; 

    // Marshall Y axis into individual plot identifiers 
    NSArray * title = [titles componentsSeparatedByString:@" "]; 

    CPTMutableTextStyle * blackTextStyle = [CPTMutableTextStyle textStyle]; 
    blackTextStyle.color = [CPTColor blackColor]; 

    // Create bar plot(s) 
    for (int seg=0; seg<title.count; seg++) 
    { 
     barPlot = [[[CPTBarPlot alloc] init] autorelease]; 

     barPlot.lineStyle   = barLineStyle; 
     barPlot.fill    = [CPTFill fillWithColor:[CPTColor colorAtIndex:seg]]; 
     barPlot.barBasesVary  = YES; 
     barPlot.barCornerRadius  = 4.0; 
     barPlot.barWidth   = @0.5; 
     barPlot.barsAreHorizontal = kUseHorizontalBars; 
     barPlot.dataSource   = self; 
     barPlot.delegate   = self; 
     barPlot.identifier   = [NSString stringWithFormat:@"%@,%d",title[seg],seg], 
     barPlot.labelTextStyle  = blackTextStyle; 
     barPlot.labelOffset   = 0.0; 
     [graph addPlot:barPlot toPlotSpace:barPlotSpace]; 
     NSLog(@"render:%@", barPlot.identifier); 
    } 

    // Add X category per slot 
    for (Item * item in plotData) 
    { 
     [barPlotSpace addCategory:item.numb forCoordinate:CPTCoordinateX]; 
    } 
} 

#pragma mark - 
#pragma mark Plot Delegate 

- (void)Plot:(nonnull CPTPlot *)plot dataLabelWasSelectedAtRecordIndex:(NSUInteger)index 
{ 
// NSString * barID = (NSString *)[[(id)plot.identifier componentsSeparatedByString:@","] lastObject]; 

    NSLog(@"Data label for '%@' was selected at record %d.", plot.identifier, (int)index); 
} 

- (CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index; 
{ 
    InfoBarView * barView = (id)[[self defaultLayerHostingView] superview]; 
    InfoController * controller = barView.controller; 
    GroupItem * group = controller.group; 

    int sndx = index % group.itemCount; 
    Item * item = (Item *)[self.plotData objectAtIndex:sndx]; 

    CPTMutableTextStyle * textStyle = [CPTMutableTextStyle textStyle]; 
    textStyle.color = [CPTColor colorAtIndex:item.foreRGB]; 
    textStyle.textAlignment = CPTTextAlignmentCenter; 
    textStyle.fontSize = 24; 
    plot.labelOffset = 0; 

    CPTMutableShadow * shadow = [CPTMutableShadow shadow]; 
    shadow.shadowColor = [CPTColor blackColor];//colorAtIndex:item.backRGB]; 
    shadow.shadowOffset = CGSizeMake(1,-1); 
    shadow.shadowBlurRadius = 2.0f; 
    plot.labelShadow = shadow; 

    CPTTextLayer * textLayer = [[CPTTextLayer alloc] initWithText:item.numb.squish style:textStyle]; 

    return [textLayer autorelease]; 
} 

- (void)barPlot:(CPTBarPlot *)plot barWasSelectedAtRecordIndex:(NSUInteger)index 
{ 
    CGFloat floor = [[self valueForPlot:plot field:CPTBarPlotFieldBarBase recordIndex:index] doubleValue]; 
    CGFloat value = [[self valueForPlot:plot field:CPTBarPlotFieldBarTip recordIndex:index] doubleValue]; 
    CGFloat runs = 0; 

    NSString * barID = (NSString *)[[(id)plot.identifier 
            componentsSeparatedByString:@","] lastObject]; 
    InfoBarView * barView = (id)[[self defaultLayerHostingView] superview]; 
    InfoController * controller = barView.controller; 
    GroupItem * group = controller.group; 

    int fndx = [barID intValue]; 
    int sndx = index % group.itemCount; 
    Item * item = (Item *)[self.plotData objectAtIndex:sndx]; 

    SEL dataItem = NSSelectorFromString(kTargets[controller.barDataIndex]); 
    DataItem * data = [item performSelector:dataItem]; 
    runs = [[data fldD] doubleValue]; 

    NSLog(@"BarSelected %@ %@ record:%lu. base:%.2f value:%.2f", 
      plot.identifier, data.name, index, floor, value); 

    CPTGraph * graph = [self defaultGraph]; 

    CPTPlotSpaceAnnotation * annotation = self.symbolTextAnnotation; 
    if (annotation) 
    { 
     [graph.plotAreaFrame.plotArea removeAnnotation:annotation]; 
     self.symbolTextAnnotation = nil; 
    } 

    // Setup a style for the annotation 
    CPTMutableTextStyle * hitAnnotationTextStyle = [CPTMutableTextStyle textStyle]; 
    hitAnnotationTextStyle.color = [CPTColor colorAtIndex:fldMapping[fndx]]; 
    hitAnnotationTextStyle.fontSize = 16.0; 
    hitAnnotationTextStyle.fontName = @"Helvetica-Bold"; 

    // Determine point of symbol in plot coordinates 
    NSNumber * x = @(index); 
    NSNumber * y = @(0.03 + (floor/runs)); 

    CPTNumberArray * anchorPoint = (kUseHorizontalBars ? @[y, x] : @[x, y]); 

    // Add annotation 
    // First make a string for the y value 
    NSString * yString = [[NSNumberFormatter withFormat:@"#,###"] stringFromNumber:@(value)]; 

    // Now add the annotation to the plot area 
    CPTPlotSpace * space = plot.plotSpace; 
    if (space) 
    { 
     CPTTextLayer * textLayer = [[CPTTextLayer alloc] initWithText:yString style:hitAnnotationTextStyle]; 

     annotation     = [[CPTPlotSpaceAnnotation alloc] initWithPlotSpace:space anchorPlotPoint:anchorPoint]; 
     annotation.contentLayer  = [textLayer autorelease]; 
     annotation.displacement  = CGPointMake(0.0, 0.0); 
     self.symbolTextAnnotation = annotation; 

     [graph.plotAreaFrame.plotArea addAnnotation:[annotation autorelease]]; 
    } 
} 

#pragma mark Plot DataSource 

- (NSUInteger)numberOfRecordsForPlot:(nonnull CPTPlot *)plot 
{ 
    InfoBarView * barView = (id)[[self defaultLayerHostingView] superview]; 
    InfoController * controller = barView.controller; 
    GroupItem * group = controller.group; 

    return group.itemCount; 
} 

- (nullable id)numberForPlot:(nonnull CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{ 
    NSString * barID = (NSString *)[[(id)plot.identifier componentsSeparatedByString:@","] lastObject]; 
    InfoBarView * barView = (id)[[self defaultLayerHostingView] superview]; 
    InfoController * controller = barView.controller; 
    GroupItem * group = controller.group; 

    int fndx = [barID intValue]; 
    int sndx = index % group.itemCount; 
    Item * item = (Item *)[self.plotData objectAtIndex:sndx]; 

    SEL dataItem = NSSelectorFromString(kTargets[controller.barDataIndex]); 
    NSString * getName = kGetters[fndx]; 
    SEL getter = NSSelectorFromString(getName); 
    SEL fldD = @selector(fldD); 
    CGFloat runs, base=0, value=0; 
    DataItem * data; 
    id num=nil; 

    // First get which data data item we're after 
    data = [item performSelector:dataItem]; 
    runs = [[data performSelector:fldD] floatValue]; 

    // Now fetch its getter 
    switch (fieldEnum) 
    { 
     case CPTBarPlotFieldBarLocation: 
      num = item.numb; 
      break; 

     case CPTBarPlotFieldBarTip: 
      // Build base for this tip 
      for (int seg=0; seg < fndx; seg++) 
      { 
       value += [[data performSelector:NSSelectorFromString(kGetters[seg])] floatValue]; 
      } 

      // Add this 'tip' value unless it's the total 
      if (fndx == 3) 
       num = @(1.0f); 
      else 
      { 
       value += [[data performSelector:getter] floatValue]; 
       num = @(value/runs); 
      } 
      break; 

     case CPTBarPlotFieldBarBase: 
      // Calc base by sum prior fields 
      for (int seg=0; seg < fndx; seg++) 
      { 
       base += [[data performSelector:NSSelectorFromString(kGetters[seg])] floatValue]; 
      } 
      num = @(base/runs); 
    } 

    return num; 
} 

- (nullable id)valueForPlot:(nonnull CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{ 
    NSString * barID = (NSString *)[[(id)plot.identifier componentsSeparatedByString:@","] lastObject]; 
    InfoBarView * barView = (id)[[self defaultLayerHostingView] superview]; 
    InfoController * controller = barView.controller; 
    GroupItem * group = controller.group; 

    int fndx = [barID intValue]; 
    int sndx = index % group.itemCount; 
    Item * item = (Item *)[self.plotData objectAtIndex:sndx]; 

    SEL dataItem = NSSelectorFromString(kTargets[controller.barDataIndex]); 
    NSString * getName = kGetters[fndx]; 
    SEL getter = NSSelectorFromString(getName); 
    SEL fldD = @selector(fldD); 
    CGFloat runs, value=0; 
    DataItem * data; 
    id num=nil; 

    // First get which data block we're after 
    data = [item performSelector:dataItem]; 
    runs = [[data performSelector:fldD] floatValue]; 

    // Now fetch its getter 
    switch (fieldEnum) 
    { 
     case CPTBarPlotFieldBarLocation: 
      num = item.numb.squish; 
      break; 

     case CPTBarPlotFieldBarTip: 
      value = [[data performSelector:getter] floatValue]; 
      num = @(value); 
      break; 

     case CPTBarPlotFieldBarBase: 
      // Calc base by sum prior fields 
      for (int seg=0; seg < fndx; seg++) 
      { 
       value += [[data performSelector:NSSelectorFromString(kGetters[seg])] floatValue]; 
      } 
      num = @(value); 
    } 

    return num; 
} 

- (nullable NSString *)legendTitleForBarPlot:(nonnull CPTBarPlot *)plot recordIndex:(NSUInteger)index 
{ 
    NSString * barID = (NSString *)[[(id)plot.identifier componentsSeparatedByString:@","] lastObject]; 
    int fndx = [barID intValue]; 

    return kGetters[fndx]; 
} 

#pragma mark Plot Legend Delegate 

- (void)legend:(CPTLegend *)legend legendEntryForPlot:(CPTPlot *)plot wasSelectedAtIndex:(NSUInteger)index 
{ 
    NSLog(@"legend:%@ index:%lu", plot.identifier, index); 
} 

#pragma mark Plot Space Delegate 

#pragma mark Plot Space Delegate 

- (CPTPlotRange *)plotSpace:(CPTPlotSpace *)space 
     willChangePlotRangeTo:(CPTPlotRange *)newRange 
       forCoordinate:(CPTCoordinate)coordinate 
{ 
    CGFloat newLocation = newRange.location.floatValue; 
// CGFloat newLength = newRange.length.floatValue; 

    // Range change to +2 point on data boundary 
    if (CPTCoordinateX == coordinate) 
    { 
     if (newLocation < -0.5) 
     { 
      return [CPTPlotRange plotRangeWithLocation:@(-0.5) length:newRange.length]; 
     } 
     else 
     if (newLocation > (0.3)) 
     { 
      return [CPTPlotRange plotRangeWithLocation:@(0.3) length:newRange.length]; 
     } 
    } 

    if (CPTCoordinateY == coordinate) 
    { 
     if (newLocation < (-0.1)) 
     { 
      return [CPTPlotRange plotRangeWithLocation:@(-0.1) length:newRange.length]; 
     } 
     else 
     if (newLocation > (0.1)) 
     { 
      return [CPTPlotRange plotRangeWithLocation:@(0.1) length:newRange.length]; 
     } 
    } 
// CGRect chartBounds = self.defaultGraph.bounds; 
// NSLog(@"old:%@", NSStringFromRect(chartBounds)); 
// NSLog(@"new:%@ %@", (coordinate == CPTCoordinateX ? @"X" : @"Y"),[newRange description]); 
    return newRange; 
} 
@end 

@implementation InfoBarView 
@synthesize barChart; 
@synthesize x_title; 

- (void)awakeFromNib 
{ 
    // Get our orig scaling 
    [super awakeFromNib]; 

    self.barChart = [[[BarChart alloc] init] autorelease]; 
} 

- (void)drawRect:(NSRect)clip 
{ 
    CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; 
    NSImage * webImage = controller.group.track.webImage; 
    GroupItem * group = controller.group; 
    NSRect rect = [self frame]; 

    // Save state so we can restore later 
    CGContextSaveGState(context); 

    // Draw track image as our view's background 
    if (webImage) 
    { 
     [webImage drawInRect:rect fromRect:[webImage alignmentRect] 
        operation:NSCompositeSourceOver fraction:0.25]; 
    } 

    if (group && !barChart.graphs.count) 
    { 
     [barChart renderInView:self withTheme:nil animated:YES]; 
    } 

    CGContextRestoreGState(context); 
} 

@end 

だ - 描かれた境界rects、私は私たちの多くは、彼らから利益を得ることができると思います(私はIB年頃v3のからのものを欠場します)。

答えて

0

ステートメントx.labelFormatter = nil;は、自動軸ラベルを削除します。ラベルフォーマッタとラベルのテキストスタイルを指定すると、軸はラベル付けポリシーに基づいて自動的にティックとラベルを作成します。

+0

Hmm;その行は元のサンプルではありません; idkどこから取り出していますが、スローを取り除く: 'NSParameterAssert(idx slashlos

+0

その行は別のバーの例ですが、その行はカテゴリを追加することで修正できます: '[barPlotSpace addCategory:@" Percentage "forCoordinate:CPTCoordinateX]; [barPlotSpace addCategory:@ "Entries" forCoordinate:CPTCoordinateY]; '何らかの理由で私のプロットは1(高)ですか?すなわち、今1時に2時にバーなど? ' – slashlos

+0

データソースの方法も表示してください。カテゴリデータを使用する方法には問題があります。 –

関連する問題