前几天有一个需求是制作一个统计工资的饼状图,但是和一般的饼状图不同的是要求该饼状图中心需要有两条文字,功能需求就是这样,先上一张效果图:
因为咱们的饼状图本身只是一个View ,在调用的时候一定是在一个ViewController 里面的,所以我们需要传值,这里我选择用代理:
@protocol PDChartViewDataSource;
@interface PDChartView : UIView
@property(nonatomic, assign) id<PDChartViewDataSource> dataSource;
接下来的任务就是要确定一下我们需要通过代理向Controller中传入什么东西。
1. slice 的片数
2.每个slice 所占的比例
3.slice的颜色
4. 内部中心圆的半径(没有中间View需求的可以不传)
所以就有了以下一段代码
/**chart中slice的个数*/
- (NSInteger)numberOfSlicesInPDChartView;
/**chart中单个slice所占的比重*/
- (CGFloat)valueForChartViewSliceAtIndex:(NSUInteger)index;
/**chart中单个slice的color*/
- (UIColor *)colorForChartViewSliceAtIndex:(NSUInteger)index;
/**chart内部中心圆的半径*/
- (CGFloat)centerCircleRadius:(PDChartView *)charView width:(CGFloat)innerWidth;
这样我们在 h 文件中操作的东西就够了
m文件中首先我们要重写初始化方法,并在该方法中把中间的View 和饼状图的轮廓大小约束出来 ,为下一步绘制饼状图内部做准备
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
midView = [[UIView alloc] init];
midView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:midView];
numLabel = [[UILabel alloc] init];
numLabel.translatesAutoresizingMaskIntoConstraints = NO;
numLabel.font = [UIFont systemFontOfSize:12];
[numLabel setTextColor:[UIColor darkGrayColor]];
numLabel.textAlignment = NSTextAlignmentCenter;
[midView addSubview:numLabel];
totalLabel = [[UILabel alloc] init];
totalLabel.translatesAutoresizingMaskIntoConstraints = NO;
totalLabel.font = [UIFont systemFontOfSize:12];
[totalLabel setTextColor:[UIColor darkGrayColor]];
totalLabel.textAlignment = NSTextAlignmentCenter;
[midView addSubview:totalLabel];
[midView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.mas_centerX);
make.centerY.mas_equalTo(self.mas_centerY);
}];
NSArray *vs = @[
@"H:|[numLabel]|",
@"H:|[totalLabel]|",
@"V:|-[numLabel]-(5)-[totalLabel]-|",
];
for (int i = 0; i <vs.count; i++) {
[midView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vs[i]
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(midView,numLabel,totalLabel)]];
}
}
return self;
}
实现代理方法
#pragma mark - draw circle
- (void)drawWithContext:(CGContextRef)context circleCenterX:(CGFloat)x circleCenterY:(CGFloat)y radius:(CGFloat)circleRadius start:(CGFloat)start end:(CGFloat)end innerWidth:(CGFloat)width color:(UIColor *)color {
CGContextAddArc(context, x, y, circleRadius, start, end, 0);
CGContextSetStrokeColorWithColor(context, color.CGColor);
CGContextSetLineWidth(context, width);
CGContextStrokePath(context);
}
#pragma mark - draw line
- (void)drawLineWithContext:(CGContextRef)context width:(CGFloat)width startPointX:(CGFloat)x startPointY:(CGFloat)y endPointX:(CGFloat)endX endPointY:(CGFloat)endY color:(UIColor *)color {
CGContextSetLineWidth(context, width);
CGContextMoveToPoint(context, x, y);
CGContextAddLineToPoint(context, endX, endY);
CGContextSetStrokeColorWithColor(context, color.CGColor);
CGContextStrokePath(context);
}
#pragma - sideLabel
- (void)sideLabel:(CGRect)frame val:(int)val {
UILabel *label = [[UILabel alloc] initWithFrame:frame];
label.font = [UIFont systemFontOfSize:(13)];
[label setTextColor:[UIColor redColor]];
label.text = [NSString stringWithFormat:@"%d%%", val];
[self addSubview:label];
[labelArray addObject:label];
}
具体的绘制方法在drawRect 中绘制(代码量太大就不粘贴了)
最后就是我们的调用了
//
// ViewController.m
// TestNetWork
//
// Created by Mac on 16/7/25.
// Copyright © 2016年 Mac. All rights reserved.
//
#import "ViewController.h"
#import "testViewController.h"
#import "PDChartView.h"
#define KChartColorBlue_R66G169B238 [UIColor colorWithRed:0.259 green:0.663 blue:0.933 alpha:1.000]
#define KChartColorGreen_R78G201B72 [UIColor colorWithRed:0.306 green:0.788 blue:0.282 alpha:1.000]
#define KChartColorOrange_R250G157B58 [UIColor colorWithRed:0.980 green:0.616 blue:0.227 alpha:1.000]
#define KChartColorRed_R240G89B89 [UIColor colorWithRed:0.941 green:0.349 blue:0.349 alpha:1.000]
#define KChartColorGray_R226G226B226 [UIColor colorWithWhite:0.886 alpha:1.000]
@interface ViewController ()<PDChartViewDataSource>{
NSMutableArray *arr;
}
@property(nonatomic,strong) PDChartView *pipeView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
arr = [NSMutableArray array];
[arr addObject:@"50"];
[arr addObject:@"80"];
[arr addObject:@"160"];
[arr addObject:@"30"];
[arr addObject:@"16"];
[self initPipeView];
}
- (void)initPipeView {
self.pipeView = [[PDChartView alloc] initWithFrame:CGRectMake(50, 100,250, 250)];
self.pipeView.dataSource = self;
[self.view addSubview:self.pipeView];
self.pipeView.contentMode = UIViewContentModeRedraw;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark datasource
- (NSInteger)numberOfSlicesInPDChartView {
return 5;
}
- (UIColor *)colorForChartViewSliceAtIndex:(NSUInteger)index {
UIColor *color;
switch (index) {
case 0:
color = KChartColorBlue_R66G169B238;
break;
case 1:
color = KChartColorGreen_R78G201B72;
break;
case 2:
color = KChartColorOrange_R250G157B58;
break;
case 3:
color = KChartColorRed_R240G89B89;
break;
case 4:
color = KChartColorGray_R226G226B226;
break;
}
return color;
}
- (CGFloat)valueForChartViewSliceAtIndex:(NSUInteger)index {
NSString *numStr = arr[index];
return [numStr doubleValue];
}
- (CGFloat)centerCircleRadius:(PDChartView *)charView width:(CGFloat)innerWidth {
return 40;
}
@end
这里不细说了,无非就是调用代理方法等等基本操作,到这里我们就完成了饼状图的绘制。。