前言
在讲述绘制散点图那篇已经详细说明了宿主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)];