向 CorePlot 切片添加图例

Adding legend to CorePlot slice

我希望能够为图表切片添加图例。我该怎么做?

我尝试实现了以下两种方法,但我认为不对;

- (NSString *) legendTitleForPieChart:(CPTPieChart *)pieChart
                          recordIndex:(NSUInteger)idx{
    return @"Legend";
}

- (NSAttributedString *) attributedLegendTitleForPieChart:      (CPTPieChart *)     pieChart
                                              recordIndex:      (NSUInteger)    idxv{

    return [[NSAttributedString alloc] initWithString:@"Attributed"];
}

这里是官方的 CorePlot 协议文档:

https://core-plot.googlecode.com/hg/documentation/html/iOS/protocol_c_p_t_pie_chart_data_source-p.html#a6a85e1a9e613eb65267abfb8a884434a


编辑:我的代码

// .h
@interface MyViewController : UIViewController<CPTPlotSpaceDelegate,CPTPieChartDelegate,CPTLegendDelegate,CPTPlotDataSource>

- (void) initializeAll;
- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil data:(NSMutableArray*)dataPoints;

 // .m

#import “MyViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface MyViewController ()
@property (weak, nonatomic) IBOutlet CPTGraphHostingView * pieChartgraphHostView;
@property (strong, nonatomic) CPTGraph* pieChartGraph;
@property (strong, nonatomic) CPTPieChart* pieChart;
@end

@implementation MyViewController

@synthesize data;

@synthesize pieChart, pieChartGraph;


- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil data:(NSMutableArray*)dataPoints{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.data = dataPoints;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // Do any additional setup after loading the view from its nib.
    [self initializeGraph];
    [self updateViewData];
    [self configureChart];
}

- (void) initializeGraph{
    if (self.data == nil) {
        NSLog(@"Error, should not use this without assigning data");
    }

    // Create a CPTGraph object and add to hostView
    self.graph = [[CPTXYGraph alloc] initWithFrame:self.graphHostView.bounds];
    self.graphHostView.hostedGraph = self.graph;
    ////////////////////


    CPTMutableTextStyle *titleStyle = [CPTMutableTextStyle textStyle];
    titleStyle.color = [CPTColor blackColor];
    titleStyle.fontName = @"Helvetica";
    titleStyle.fontSize = 12.0f;

    // Axes
    // Label x axis with a fixed interval policy
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
    CPTXYAxis *x          = axisSet.xAxis;
    x.separateLayers              = NO;
    x.title                       = @"X Axis";
    x.titleTextStyle              = titleStyle;
    x.delegate                    = self;


    CPTXYAxis *y = axisSet.yAxis;
    y.labelingPolicy        = CPTAxisLabelingPolicyAutomatic;
    y.separateLayers        = YES;
    y.majorTickLocations = [NSSet setWithObjects:
                            [NSDecimalNumber numberWithDouble:0],
                            [NSDecimalNumber numberWithDouble:300],
                            nil];

    y.title                 = @"Y Axis";
    y.titleTextStyle        = titleStyle;
    y.delegate              = self;


    CPTFill *whitebandFill = [CPTFill fillWithColor:[[CPTColor whiteColor] colorWithAlphaComponent:0.5]];
    CPTFill *greenbandFill = [CPTFill fillWithColor:[[CPTColor greenColor] colorWithAlphaComponent:0.5]];
    CPTFill *redbandFill = [CPTFill fillWithColor:[[CPTColor redColor] colorWithAlphaComponent:0.75]];

    [y addBackgroundLimitBand:[CPTLimitBand limitBandWithRange:[CPTPlotRange plotRangeWithLocationDecimal:CPTDecimalFromDouble(0.0) lengthDecimal:CPTDecimalFromDouble(500.0)] fill:whitebandFill]];
    [y addBackgroundLimitBand:[CPTLimitBand limitBandWithRange:[CPTPlotRange plotRangeWithLocationDecimal:CPTDecimalFromDouble(500.0) lengthDecimal:CPTDecimalFromDouble(750.0)] fill:greenbandFill]];

    [y addBackgroundLimitBand:[CPTLimitBand limitBandWithRange:[CPTPlotRange plotRangeWithLocationDecimal:CPTDecimalFromDouble(750.0) lengthDecimal:CPTDecimalFromDouble(1024.0)] fill:redbandFill]];

    // Add the y2 axis to the axis set
    self.graph.axisSet.axes = @[x, y];


    /////////////////////
    // Get the (default) plotspace from the graph so we can set its x/y ranges
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) self.graph.defaultPlotSpace;

    // Note that these CPTPlotRange are defined by START and LENGTH (not START and END) !!

    [plotSpace setYRange: [CPTPlotRange plotRangeWithLocation:[NSNumber numberWithInt:0] length:[NSNumber numberWithInt:1024]]];

    NSLog(@"creating x range for %lu data points", (unsigned long)[self.data count]);
    [plotSpace setXRange: [CPTPlotRange plotRangeWithLocation:[NSNumber numberWithInt:0] length:[NSNumber numberWithInt:[self.data count]]]];

    // Create the plot (we do not define actual x/y values yet, these will be supplied by the datasource...)
    self.plot = [[CPTScatterPlot alloc] initWithFrame:CGRectZero];


    // Let's keep it simple and let this class act as datasource (therefore we implemtn <CPTPlotDataSource>)
    self.plot.dataSource = self;
    self.plot.delegate = self;

    // Finally, add the created plot to the default plot space of the CPTGraph object we created before
    [self.graph addPlot:self.plot toPlotSpace:self.graph.defaultPlotSpace];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}



-(void)configureChart {
    // 1 - Get reference to graph

    pieChartGraph = [[CPTXYGraph alloc] initWithFrame:self.pieChartgraphHostView.bounds];
    self.pieChartgraphHostView.hostedGraph = pieChartGraph;
    pieChartGraph.plotAreaFrame.masksToBorder = NO;
    pieChartGraph.axisSet = nil;
    pieChart.title = @"My pie chart";

    // 2 - Create chart
    pieChart = [[CPTPieChart alloc] init];
    pieChart.dataSource = self;
    pieChart.delegate = self;
    pieChart.pieRadius = (self.pieChartgraphHostView.bounds.size.height * 0.9) / 2;

    pieChartGraph.delegate = self;

    pieChart.identifier = pieChartGraph.title;
    pieChart.startAngle = CPTFloat(M_PI_4);
    pieChart.sliceDirection = CPTPieDirectionClockwise;
    pieChart.borderLineStyle = [CPTLineStyle lineStyle];
    // 3 - Create gradient

    CPTGradient *overlayGradient = [[CPTGradient alloc] init];
    overlayGradient.gradientType = CPTGradientTypeRadial;
    overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.0] atPosition:0.9];
    overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.4] atPosition:1.0];
    pieChart.overlayFill = [CPTFill fillWithGradient:overlayGradient];

    // 4 - Add chart to graph
    pieChart.pieRadius = pieChart.pieRadius / 2.3;
    [pieChartGraph addPlot:pieChart];

    self.dataForChart = [@[@20.0, @30.0, @25.0, @25.0] mutableCopy];
}

-(void)setRoundedView:(UIView *)roundedView toDiameter:(float)newSize;
{
    CGPoint saveCenter = roundedView.center;
    CGRect newFrame = CGRectMake(roundedView.frame.origin.x, roundedView.frame.origin.y, newSize, newSize);
    roundedView.frame = newFrame;
    roundedView.layer.cornerRadius = newSize / 2.0;
    roundedView.center = saveCenter;
}


-(void)configureLegend {
    // 1 - Get graph instance
    CPTGraph *graph = self.graphHostView.hostedGraph;
    // 2 - Create legend
    CPTLegend *theLegend = [CPTLegend legendWithGraph:graph];
    // 3 - Configure legen
    theLegend.numberOfColumns = 1;
    theLegend.fill = [CPTFill fillWithColor:[CPTColor whiteColor]];
    theLegend.borderLineStyle = [CPTLineStyle lineStyle];
    theLegend.cornerRadius = 5.0;
    // 4 - Add legend to graph
    graph.legend = theLegend;
    graph.legendAnchor = CPTRectAnchorRight;
    CGFloat legendPadding = -(self.view.bounds.size.width / 8);
    graph.legendDisplacement = CGPointMake(legendPadding, 0.0);
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

#pragma mark -
#pragma mark Plot Data Source Methods

- (NSString *) legendTitleForPieChart:(CPTPieChart *)pieChart
                          recordIndex:(NSUInteger)idx{
    return @"Legend";
}

/**
- (NSAttributedString *) attributedLegendTitleForPieChart:      (CPTPieChart *)     pieChart
                                              recordIndex:      (NSUInteger)    idxv{

    return [[NSAttributedString alloc] initWithString:@"Attributed"];
}**/

-(NSAttributedString *)attributedLegendTitleForPieChart:(CPTPieChart *)pieChart recordIndex:(NSUInteger)index
{
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
    UIColor *sliceColor = [CPTPieChart defaultPieSliceColorForIndex:index].uiColor;
    UIFont *labelFont   = [UIFont fontWithName:@"Helvetica" size:12.0 * CPTFloat(0.5)];
#else
    NSColor *sliceColor = [CPTPieChart defaultPieSliceColorForIndex:index].nsColor;
    NSFont *labelFont   = [NSFont fontWithName:@"Helvetica" size:12.0 * CPTFloat(0.5)];
#endif

    NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"Pie Slice %lu", (unsigned long)index]];
    [title addAttribute:NSForegroundColorAttributeName
                  value:sliceColor
                  range:NSMakeRange(4, 5)];

    [title addAttribute:NSFontAttributeName
                  value:labelFont
                  range:NSMakeRange(0, title.length)];

    return title;
}

@end

标题、图例和标签不会显示。

您只需要其中一种方法。如果您需要像示例图像中那样的样式文本,请使用属性标题,否则任何一种方法都可以使用。这些方法应该在绘图的数据源中实现。