转自http://blog.youkuaiyun.com/xj2014/article/details/41791513
前言
在讲述绘制散点图那篇已经详细说明了宿主View、图表CPTXYGraph、绘图空间、坐标系、以及图例的创建过程。当然在绘制饼状图中是不需要坐标系的。效果图如下:
数据源与填充色:
- NSMutableArray *dataSource = [NSMutableArray arrayWithCapacity:10];
- for (int i = 0; i < 6; i++) {
- [dataSource addObject:@(arc4random()%10)];
- }
- for (int i = 0; i < 6; i++) {
- CGFloat scale = [dataSource[i] floatValue] / [[dataSource valueForKeyPath:@"@sum.self"] floatValue];
- [dataSource replaceObjectAtIndex:i withObject:@(scale)];
- }
- self.dataSource = dataSource;
- _sliceFills = @[[CPTColor greenColor],
- [CPTColor lightGrayColor],
- [CPTColor cyanColor],
- [CPTColor yellowColor],
- [CPTColor magentaColor],
- [CPTColor purpleColor]];
由于在绘制饼状图的过程中是不需要坐标轴的,所以我们要去除坐标系,如果不去除坐标系,我们将会看到,坐标轴的黑色轴线。
- // 饼图不需要显示坐标轴
- _hostView.hostedGraph.axisSet = nil;
饼状图(CPTPiePlot)创建
CPTPiePlot用于创建饼状图,继承于CPTPlot。
- #pragma mark 创建平面图,饼图
- - (void)createPlots
- {
- // 饼图初始化
- CPTPieChart *piePlot = [[CPTPieChart alloc] init];
- // 添加图形到绘图空间
- [_hostView.hostedGraph addPlot:piePlot];
- // 标识,根据此@ref identifier来区分不同的plot
- piePlot.identifier = @"PieChart";
- // 指定饼图的数据源。数据源必须实现 CPTPieDataSource 委托
- piePlot.dataSource = self;
- // 指定饼图的事件委托。委托必须实现 CPTPieChartDelegate 中定义的方法
- piePlot.delegate = self;
- // 饼图设置
- {
- // 饼图的半径
- piePlot.pieRadius = CPTFloat(200);
- // 内部圆
- piePlot.pieInnerRadius = CPTFloat(10);
- // 开始绘制的位置,第1片扇形的起始角度,默认是PI/2
- piePlot.startAngle = 0;
- // 绘制的方向:正时针、反时针
- piePlot.sliceDirection = CPTPieDirectionClockwise;
- // 边线的样式
- piePlot.borderLineStyle= nil;
- // 饼图的重心(旋转时以此为中心)坐标(x,y),以相对于饼图直径的比例表示(0-1)之间。默认和圆心重叠(0.5,0.5)
- piePlot.centerAnchor = CGPointMake(0.5, 0.5);
- // 覆盖色
- //CPTGradient *gradient = [[CPTGradient alloc]init];
- // 剃度效果
- //gradient.gradientType = CPTGradientTypeRadial;
- // 设置颜色变换的颜色和位置
- //gradient = [gradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.1] atPosition:0.9];
- //gradient = [gradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.5] atPosition:0.5];
- //gradient = [gradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.3] atPosition:0.9];
- //piePlot.overlayFill = [CPTFill fillWithGradient:gradient];
- }
- // 扇形上的标签文字设置
- {
- // 是否顺着扇形的方向
- piePlot.labelRotationRelativeToRadius = YES;
- // 偏移量
- piePlot.labelOffset = -(piePlot.pieRadius - piePlot.pieInnerRadius) * 0.6;
- }
- // 添加动画
- CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
- fadeInAnimation.duration = 3.0f;
- fadeInAnimation.removedOnCompletion = NO;
- fadeInAnimation.fillMode = kCAFillModeForwards;
- fadeInAnimation.toValue = [NSNumber numberWithFloat:1.0];
- piePlot.opacity = 0.f;
- [piePlot addAnimation:fadeInAnimation forKey:@"animateOpacity"];
- }
CPTPiePlotDataSource数据源方法
- #pragma mark 询问有多少个扇形
- - (NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
- {
- return self.dataSource.count;
- }
- #pragma mark 询问扇形的数据值
- - (NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)idx
- {
- NSNumber *num = self.dataSource[idx];
- return num;
- }
- #pragma mark 扇形颜色
- - (CPTFill *)sliceFillForPieChart:(CPTPieChart *)pieChart recordIndex:(NSUInteger)idx
- {
- CPTFill *color = [CPTFill fillWithColor:_sliceFills[idx]];
- return color;
- }
- #pragma mark 扇形名称
- - (CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)idx
- {
- CPTTextLayer *label = [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:@"饼图-%d",(int)(idx + 1)]];
- CPTMutableTextStyle *textStyle =[label.textStyle mutableCopy];
- textStyle.color = [CPTColor blackColor];
- textStyle.fontSize = CPTFloat(17);
- label.textStyle = textStyle;
- return label;
- }
- #pragma mark 剥离扇形
- - (CGFloat)radialOffsetForPieChart:(CPTPieChart *)pieChart recordIndex:(NSUInteger)idx
- {
- return idx == 2 ? 10 : 0;
- }
- #pragma mark 图例名称 返回nil则不显示该索引下的图例
- - (NSString *)legendTitleForPieChart:(CPTPieChart *)pieChart recordIndex:(NSUInteger)idx
- {
- NSString *legendTitle = [NSString stringWithFormat:@"饼图-%d",(int)(idx + 1)];
- return legendTitle;
- }
CPTPiePlotDelegate委托方法
- #pragma mark 选中扇形的操作
- - (void)pieChart:(CPTPieChart *)plot sliceWasSelectedAtRecordIndex:(NSUInteger)idx withEvent:(UIEvent *)event
- {
- }
图例(CPTLegend)的创建
由于在饼状图中的图例就是每一个扇形,所以我们只可以用以下的方法创建索引。
- CPTLegend *legend = [CPTLegend legendWithPlots:_hostView.hostedGraph.allPlots];
- CPTLegend *legend = [CPTLegend legendWithGraph:_hostView.hostedGraph]
饼状图的一些求值方法
- // 获取某个索引下扇形的中间的弧度
- CGFloat medianAngle = [piePlot medianAngleForPieSliceIndex:0];
- // 计算某个弧度下的扇形索引
- NSInteger sliceIndex = [piePlot pieSliceIndexAtAngle:CPTFloat(0)];