有時候我們在處理一些數據的時候,需要用到柱狀圖,折線圖和餅狀圖等來呈現數據,讓用戶能夠對數據更加清晰明了化。下面我們來看一下簡單的餅狀圖的實現。
#import "NSObject+XuSong.h" **NSObject+XuSong.h** /** * N秒後執行動作(不阻塞主線程) * * @param seconds 幾秒 * @param actions 幾秒後執行的動作 */ - (void)dispatch_after_withSeconds:(float)seconds actions:(void(^)(void))actions; **NSObject+XuSong.m** - (void)dispatch_after_withSeconds:(float)seconds actions:(void(^)(void))actions{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(seconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ actions(); }); #import "NSString+XuSong.h" **NSString+XuSong.h** /** * 計算字符串寬度(指當該字符串放在view時的自適應寬度) * * @param size 填入預留的大小 * @param font 字體大小 * * @return 返回CGRect */ - (CGRect)stringWidthRectWithSize:(CGSize)size fontOfSize:(CGFloat)font; **NSString+XuSong.m** - (CGRect)stringWidthRectWithSize:(CGSize)size fontOfSize:(CGFloat)font{ NSDictionary * attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:font]}; return [self boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil]; } #import "UIColor+XuSong.h" **UIColor+XuSong.h** @interface UIColor (XuSong) @property (nonatomic, assign, readonly) CGFloat red; @property (nonatomic, assign, readonly) CGFloat green; @property (nonatomic, assign, readonly) CGFloat blue; @property (nonatomic, assign, readonly) CGFloat alpha; @end **UIColor+XuSong.m** @implementation UIColor (XuSong) - (NSDictionary *)getRGBDictionaryByColor{ CGFloat r=0,g=0,b=0,a=0; if ([self respondsToSelector:@selector(getRed:green:blue:alpha:)]) { [self getRed:&r green:&g blue:&b alpha:&a]; } else { const CGFloat *components = CGColorGetComponents(self.CGColor); r = components[0]; g = components[1]; b = components[2]; a = components[3]; } r = r * 255; g = g * 255; b = b * 255; return @{@"R":@(r), @"G":@(g), @"B":@(b), @"A":@(a)}; } - (CGFloat)red{ NSDictionary * dict = [self getRGBDictionaryByColor]; return [dict[@"R"] floatValue]; } - (CGFloat)green{ NSDictionary * dict = [self getRGBDictionaryByColor]; return [dict[@"G"] floatValue]; } - (CGFloat)blue{ NSDictionary * dict = [self getRGBDictionaryByColor]; return [dict[@"B"] floatValue]; } - (CGFloat)alpha{ NSDictionary * dict = [self getRGBDictionaryByColor]; return [dict[@"A"] floatValue]; } @end #import "UIView+XuSong.h" **UIView+XuSong.h** /** * 自定義邊框 * * @param cornerRadius 角落半徑 * @param borderWidth 邊框寬度 * @param color 邊框顏色 */ -(void)setBorderCornerRadius:(CGFloat)cornerRadius andBorderWidth:(CGFloat)borderWidth andBorderColor:(UIColor *)color; **UIView+XuSong.m** -(void)setBorderCornerRadius:(CGFloat)cornerRadius andBorderWidth:(CGFloat)borderWidth andBorderColor:(UIColor *)color{ self.layer.cornerRadius = cornerRadius; self.layer.borderWidth = borderWidth; self.layer.borderColor = color.CGColor; }
**ZFChart.h** #import "ZFConst.h" #import "ZFPieChart.h" #import "ZFColor.h" **ZFColor.h** #define ZFBlack [UIColor blackColor] #define ZFDarkGray [UIColor darkGrayColor] #define ZFLightGray [UIColor lightGrayColor] #define ZFWhite [UIColor whiteColor] #define ZFGray [UIColor grayColor] #define ZFRed [UIColor redColor] #define ZFGreen [UIColor greenColor] #define ZFBlue [UIColor blueColor] #define ZFCyan [UIColor cyanColor] #define ZFYellow [UIColor yellowColor] #define ZFMagenta [UIColor magentaColor] #define ZFOrange [UIColor orangeColor] #define ZFPurple [UIColor purpleColor] #define ZFBrown [UIColor brownColor] #define ZFClear [UIColor clearColor] **ZFConst.h** #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width #define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height #define ADAPTATION_WIDTH7(Width) [UIScreen mainScreen].bounds.size.width * (Width) / 375 #define IMGNAME(name) [UIImage imageNamed:name] /** * 直接填寫小數 */ #define ZFDecimalColor(r, g, b, a) [UIColor colorWithRed:r green:g blue:b alpha:a] /** * 直接填寫整數 */ #define ZFColor(r, g, b, a) [UIColor colorWithRed:r / 255.f green:g / 255.f blue:b / 255.f alpha:a] /** * 隨機顏色 */ #define ZFRandomColor ZFColor(arc4random() % 256, arc4random() % 256, arc4random() % 256, 1) #define NAVIGATIONBAR_HEIGHT 64.f #define TABBAR_HEIGHT 49.f /** * 角度求三角函數sin值 * @param a 角度 */ #define ZFSin(a) sin(a / 180.f * M_PI) /** * 角度求三角函數cos值 * @param a 角度 */ #define ZFCos(a) cos(a / 180.f * M_PI) /** * 角度求三角函數tan值 * @param a 角度 */ #define ZFTan(a) tan(a / 180.f * M_PI) /** * 弧度轉角度 * @param radian 弧度 */ #define ZFAngle(radian) (radian / M_PI * 180.f) /** * 角度轉弧度 * @param angle 角度 */ #define ZFRadian(angle) (angle / 180.f * M_PI) /** * 坐標軸起點x值 */ #define ZFAxisLineStartXPos 50.f /** * y軸label tag值 */ #define YLineValueLabelTag 100 /** * x軸item寬度 */ #define XLineItemWidth 25.f /** * x軸item間隔 */ #define XLineItemGapLength 20.f #warning message - 此屬性最好不要隨意修改 /** * 坐標y軸最大上限值到箭頭的間隔距離 (此屬性最好不要隨意修改) */ #define ZFAxisLineGapFromYLineMaxValueToArrow 20.f
**ZFTranslucencePath.h** #import#import @interface ZFTranslucencePath : CAShapeLayer + (instancetype)layerWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise; - (instancetype)initWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise; @end **ZFTranslucencePath.m** @implementation ZFTranslucencePath + (instancetype)layerWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise{ return [[ZFTranslucencePath alloc] initWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:clockwise]; } - (instancetype)initWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise{ self = [super init]; if (self) { self.fillColor = nil; self.opacity = 0.5f; self.path = [self translucencePathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:clockwise].CGPath; } return self; } - (UIBezierPath *)translucencePathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise{ UIBezierPath * bezierPath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:clockwise]; return bezierPath; } @end
**ZFPieChart.h** #importtypedef enum{ /** * 保留2位小數形式(默認) */ kPercentTypeDecimal = 0, /** * 取整數形式(四捨五入) */ kPercentTypeInteger = 1 }kPercentType; @interface ZFPieChart : UIView /** 標題 */ @property (nonatomic, copy) NSString * title; /** 數值數組 (存儲的是NSString類型) */ @property (nonatomic, strong) NSMutableArray * valueArray; /** 名字數組 (存儲的是NSString類型) */ @property (nonatomic, strong) NSMutableArray * nameArray; /** 顏色數組 (存儲的是UIColor類型) */ @property (nonatomic, strong) NSMutableArray * colorArray; /** kPercentType類型 */ @property (nonatomic, assign) kPercentType percentType; /** 顯示詳細信息(默認為YES) */ @property (nonatomic, assign) BOOL isShowDetail; /** 顯示百分比(默認為YES) */ @property (nonatomic, assign) BOOL isShowPercent; #pragma mark - public method /** * 重繪 */ - (void)strokePath; @end **ZFPieChart.m** #import "ZFPieChart.h" #import "ZFConst.h" #import "NSObject+XuSong.h" #import "NSString+XuSong.h" #import "UIColor+XuSong.h" #import "UIView+XuSong.h" #import "ZFTranslucencePath.h" #import "Masonry.h" #define PercentLabelTag 100 #define DetailBackgroundTag 500 @interface ZFPieChart() /** 總數 */ @property (nonatomic, assign) CGFloat totalValue; /** 半徑 */ @property (nonatomic, assign) CGFloat radius; /** 半徑最大上限 */ @property (nonatomic, assign) CGFloat maxRadius; /** 記錄每個圓弧開始的角度 */ @property (nonatomic, assign) CGFloat startAngle; /** 動畫總時長 */ @property (nonatomic, assign) CFTimeInterval totalDuration; /** 圓環線寬 */ @property (nonatomic, assign) CGFloat lineWidth; /** 記錄valueArray當前元素的下標 */ @property (nonatomic, assign) NSInteger index; /** 記錄當前path的中心點 */ @property (nonatomic, assign) CGPoint centerPoint; /** 半透明Path延伸長度 */ @property (nonatomic, assign) CGFloat extendLength; /** 記錄圓環中心 */ @property (nonatomic, assign) CGPoint pieCenter; /** 記錄初始高度 */ @property (nonatomic, assign) CGFloat originHeight; /** 存儲每個圓弧動畫開始的時間 */ @property (nonatomic, strong) NSMutableArray * startTimeArray; /** 記錄每個path startAngle 和 endAngle, 數組裡存的是NSDictionary */ @property (nonatomic, strong) NSMutableArray * angelArray; /** 標題Label */ @property (nonatomic, strong) UILabel * titleLabel; /** 數值Label */ @property (nonatomic, strong) UILabel * valueLabel; @end @implementation ZFPieChart - (NSMutableArray *)startTimeArray{ if (!_startTimeArray) { _startTimeArray = [NSMutableArray array]; } return _startTimeArray; } - (NSMutableArray *)angelArray{ if (!_angelArray) { _angelArray = [NSMutableArray array]; } return _angelArray; } /** * 初始化變量 */ - (void)commonInit{ _maxRadius = self.frame.size.width > self.frame.size.height ? self.frame.size.height : self.frame.size.width; _radius = _maxRadius * 0.27; _lineWidth = _radius; _totalDuration = 0.75f; _startAngle = ZFRadian(-90); _extendLength = 10.f; _originHeight = self.frame.size.height; _pieCenter = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2); _isShowDetail = YES; _isShowPercent = YES; } - (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { [self commonInit]; //數值Label self.valueLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, _radius/1.4, _radius/1.4)]; self.valueLabel.font = [UIFont boldSystemFontOfSize:13.f]; self.valueLabel.textAlignment = NSTextAlignmentCenter; self.valueLabel.textColor = [UIColor blackColor]; self.valueLabel.numberOfLines = 0; self.valueLabel.center = self.pieCenter; [self addSubview:self.valueLabel]; } return self; } /** * 添加詳情 */ - (void)addUI{ CGFloat valueMoney = 0.0; for (NSInteger i = 0; i < self.valueArray.count; i++) { //裝載容器 UIView * background = [[UIView alloc] initWithFrame:CGRectMake(0, self.frame.size.height + ADAPTATION_HEIGHT7(50) * i, self.frame.size.width, ADAPTATION_HEIGHT7(50))]; background.tag = DetailBackgroundTag + i; [self addSubview:background]; UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showTranslucencePathAction:)]; [background addGestureRecognizer:tap]; //線條 UIView *lineView = [[UIView alloc] init]; lineView.backgroundColor = [UIColor lightGrayColor]; [background addSubview:lineView]; [lineView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(background); make.left.equalTo(background).offset(10); make.right.equalTo(background); make.height.mas_offset(1); }]; UIImageView *colorImage = [[UIImageView alloc] init]; colorImage.image = IMGNAME(_nameArray[i]); [background addSubview:colorImage]; [colorImage mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(background); make.left.equalTo(background).offset(20); make.size.mas_equalTo(CGSizeMake(ADAPTATION_WIDTH7(35), ADAPTATION_WIDTH7(35))); }]; //名稱 UILabel *nameLabel = [[UILabel alloc] init]; nameLabel.text = _nameArray[i]; nameLabel.font = [UIFont boldSystemFontOfSize:18]; nameLabel.textAlignment = NSTextAlignmentLeft; [background addSubview:nameLabel]; [nameLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(background); make.left.equalTo(colorImage.mas_right).offset(15); make.size.mas_equalTo(CGSizeMake(60, 30)); }]; //數值 UILabel *valueLabel = [[UILabel alloc] init]; valueLabel.font = [UIFont systemFontOfSize:16]; valueLabel.text = [NSString stringWithFormat:@"%@元",_valueArray[i]]; valueLabel.textAlignment = NSTextAlignmentCenter; [background addSubview:valueLabel]; [valueLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(background); make.centerY.equalTo(background); make.size.mas_equalTo(CGSizeMake(150, 30)); }]; valueMoney += [_valueArray[i] floatValue]; self.valueLabel.text = [NSString stringWithFormat:@"總金額%.2f",valueMoney]; //百分比 UILabel *percentLabel = [[UILabel alloc] init]; percentLabel.text = [self getPercent:i]; percentLabel.font = [UIFont systemFontOfSize:16]; percentLabel.textAlignment = NSTextAlignmentRight; [background addSubview:percentLabel]; [percentLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(background); make.right.equalTo(background).offset(-15); make.size.mas_equalTo(CGSizeMake(80, 30)); }]; } //重設self.frame的值 UILabel * lastLabel = (UILabel *)[self viewWithTag:DetailBackgroundTag + self.valueArray.count - 1]; self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, CGRectGetMaxY(lastLabel.frame) + 20); } #pragma mark - Arc(圓弧) /** * 填充 * * @return UIBezierPath */ - (UIBezierPath *)fill{ //需要多少度的圓弧 CGFloat angle = [self countAngle:[_valueArray[_index] floatValue]]; UIBezierPath * bezier = [UIBezierPath bezierPathWithArcCenter:_pieCenter radius:_radius startAngle:_startAngle endAngle:_startAngle + angle clockwise:YES]; self.centerPoint = [self getBezierPathCenterPointWithStartAngle:_startAngle endAngle:_startAngle + angle]; //記錄開始角度和結束角度 NSDictionary * dict = @{@"startAngle":@(_startAngle), @"endAngle":@(_startAngle + angle)}; [self.angelArray addObject:dict]; _startAngle += angle; return bezier; } /** * CAShapeLayer * * @return CAShapeLayer */ - (CAShapeLayer *)shapeLayer{ CAShapeLayer * layer = [CAShapeLayer layer]; layer.fillColor = nil; layer.strokeColor = [_colorArray[_index] CGColor]; layer.lineWidth = _lineWidth; layer.path = [self fill].CGPath; CABasicAnimation * animation = [self animation]; [layer addAnimation:animation forKey:nil]; return layer; } #pragma mark - 動畫 /** * 填充動畫過程 * * @return CABasicAnimation */ - (CABasicAnimation *)animation{ CABasicAnimation * fillAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; fillAnimation.duration = [self countDuration:_index]; fillAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; fillAnimation.fillMode = kCAFillModeForwards; fillAnimation.removedOnCompletion = NO; fillAnimation.fromValue = @(0.f); fillAnimation.toValue = @(1.f); return fillAnimation; } #pragma mark - 清除控件 /** * 清除之前所有子控件 */ - (void)removeAllSubLayers{ [self.angelArray removeAllObjects]; self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, _originHeight); NSArray * subLayers = [NSArray arrayWithArray:self.layer.sublayers]; for (CALayer * layer in subLayers) { if (layer != self.titleLabel.layer && layer != self.valueLabel.layer) { [layer removeAllAnimations]; [layer removeFromSuperlayer]; } } for (UIView * view in self.subviews) { if (view != self.titleLabel && view != self.valueLabel) { [view removeFromSuperview]; } } } /** * 移除半透明Path */ - (void)removeZFTranslucencePath{ NSMutableArray * sublayers = [NSMutableArray arrayWithArray:self.layer.sublayers]; for (CALayer * layer in sublayers) { if ([layer isKindOfClass:[ZFTranslucencePath class]]) { [layer removeFromSuperlayer]; } } } #pragma mark - 半透明Path /** * 半透明Path * * @param startAngle 開始角度 * @param endAngle 結束角度 * @param index 下標 * * @return ZFTranslucencePath */ - (ZFTranslucencePath *)translucencePathShapeLayerWithStartAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle index:(NSInteger)index{ ZFTranslucencePath * layer = [ZFTranslucencePath layerWithArcCenter:_pieCenter radius:_radius + _extendLength startAngle:startAngle endAngle:endAngle clockwise:YES]; layer.strokeColor = [_colorArray[index] CGColor]; layer.lineWidth = _lineWidth + _extendLength; return layer; } #pragma mark - public method /** * 重繪 */ - (void)strokePath{ self.userInteractionEnabled = NO; [self removeAllSubLayers]; _startAngle = ZFRadian(-90); for (NSInteger i = 0; i < _valueArray.count; i++) { [self dispatch_after_withSeconds:[self.startTimeArray[i] floatValue] actions:^{ _index = i; CAShapeLayer * shapeLayer = [self shapeLayer]; [self.layer addSublayer:shapeLayer]; _isShowPercent == YES?[self creatPercentLabel]:nil; }]; } [self dispatch_after_withSeconds:_totalDuration actions:^{ self.userInteractionEnabled = YES; }]; _isShowDetail == YES?[self addUI]:nil; } #pragma mark - UIResponder - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [super touchesBegan:touches withEvent:event]; UITouch * touch = [touches anyObject]; CGPoint point = [touch locationInView:self]; if (point.y > _originHeight / 8.f * 7 + 30) { return; } //求弧度 CGFloat x = (point.x - _pieCenter.x); CGFloat y = (point.y - _pieCenter.y); CGFloat radian = atan2(y, x); //當超過180度時,要加2π if (y < 0 && x < 0) { radian = radian + ZFRadian(360); } //判斷點擊位置的角度在哪個path范圍上 for (NSInteger i = 0; i < self.angelArray.count; i++) { NSDictionary * dict = self.angelArray[i]; CGFloat startAngle = [dict[@"startAngle"] floatValue]; CGFloat endAngle = [dict[@"endAngle"] floatValue]; if (radian >= startAngle && radian < endAngle) { [self removeZFTranslucencePath]; [self.layer addSublayer:[self translucencePathShapeLayerWithStartAngle:startAngle endAngle:endAngle index:i]]; UILabel * percentLabel = [self viewWithTag:PercentLabelTag + i]; [self bringSubviewToFront:percentLabel]; self.valueLabel.text = _valueArray[i]; return; } } } /** * 顯示半透明Path Action * * @param sender UITapGestureRecognizer */ - (void)showTranslucencePathAction:(UITapGestureRecognizer *)sender{ NSInteger index = sender.view.tag - DetailBackgroundTag; NSDictionary * dict = self.angelArray[index]; CGFloat startAngle = [dict[@"startAngle"] floatValue]; CGFloat endAngle = [dict[@"endAngle"] floatValue]; [self removeZFTranslucencePath]; [self.layer addSublayer:[self translucencePathShapeLayerWithStartAngle:startAngle endAngle:endAngle index:index]]; UILabel * percentLabel = [self viewWithTag:PercentLabelTag + index]; [self bringSubviewToFront:percentLabel]; self.valueLabel.text = _valueArray[index]; } #pragma mark - 獲取每個item所占百分比 /** * 計算每個item所占角度大小 * * @param value 每個item的value * * @return 返回角度大小 */ - (CGFloat)countAngle:(CGFloat)value{ //計算百分比 CGFloat percent = value / _totalValue; //需要多少度的圓弧 CGFloat angle = M_PI * 2 * percent; return angle; } #pragma mark - 計算每個圓弧執行動畫持續時間 /** * 計算每個圓弧執行動畫持續時間 * * @param index 下標 * * @return CFTimeInterval */ - (CFTimeInterval)countDuration:(NSInteger)index{ if (_totalDuration < 0.1f) { _totalDuration = 0.1f; } float count = _totalDuration / 0.1f; CGFloat averageAngle = M_PI * 2 / count; CGFloat time = [self countAngle:[_valueArray[index] floatValue]] / averageAngle * 0.1; return time; } #pragma mark - 獲取每個path的中心點 /** * 獲取每個path的中心點 * * @return CGFloat */ - (CGPoint)getBezierPathCenterPointWithStartAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle{ //一半角度(弧度) CGFloat halfAngle = (endAngle - startAngle) / 2; //中心角度(弧度) CGFloat centerAngle = halfAngle + startAngle; //中心角度(角度) CGFloat realAngle = ZFAngle(centerAngle); CGFloat center_xPos = ZFCos(realAngle) * _radius + _pieCenter.x; CGFloat center_yPos = ZFSin(realAngle) * _radius + _pieCenter.y; return CGPointMake(center_xPos, center_yPos); } #pragma mark - 添加百分比Label /** * 添加百分比Label */ - (void)creatPercentLabel{ NSString * string = [self getPercent:_index]; CGRect rect = [string stringWidthRectWithSize:CGSizeMake(0, 0) fontOfSize:9.f]; UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, rect.size.width, rect.size.height)]; if ([string isEqualToString:@"0.00%"]) { label.text = @""; }else { label.text = string; } label.alpha = 0.f; label.textAlignment = NSTextAlignmentCenter; label.font = [UIFont boldSystemFontOfSize:9.f]; label.center = self.centerPoint; label.tag = PercentLabelTag + _index; [self addSubview:label]; [UIView animateWithDuration:[self countDuration:_index] animations:^{ label.alpha = 1.f; }]; //獲取r,g,b三色值 CGFloat red = [_colorArray[_index] red]; CGFloat green = [_colorArray[_index] green]; //path顏色為深色時,更改文字顏色 if ((red < 180.f && green < 180.f)) { label.textColor = [UIColor whiteColor]; } } /** * 計算百分比 * * @return NSString */ - (NSString *)getPercent:(NSInteger)index{ CGFloat percent = [_valueArray[index] floatValue] / _totalValue * 100; NSString * string; if (self.percentType == kPercentTypeDecimal) { string = [NSString stringWithFormat:@"%.2f%%",percent]; }else if (self.percentType == kPercentTypeInteger){ string = [NSString stringWithFormat:@"%d%%",(int)roundf(percent)]; } return string; } #pragma mark - 重寫setter,getter方法 - (void)setValueArray:(NSMutableArray *)valueArray{ _valueArray = valueArray; _totalValue = 0; [self.startTimeArray removeAllObjects]; CFTimeInterval startTime = 0.f; //計算總數 for (NSInteger i = 0; i < valueArray.count; i++) { _totalValue += [valueArray[i] floatValue]; } //計算每個path的開始時間 for (NSInteger i = 0; i < valueArray.count; i++) { [self.startTimeArray addObject:[NSNumber numberWithDouble:startTime]]; CFTimeInterval duration = [self countDuration:i]; startTime += duration; } } @end
**#import "ViewController.h"** #import@interface ViewController : UIViewController @end **#import "ViewController.m"** #import "ViewController.h" #import "ZFChart.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; ZFPieChart *pieChart = [[ZFPieChart alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_WIDTH)]; pieChart.valueArray = [NSMutableArray arrayWithArray:@"410", @"510", @"380", @"420", @"260",nil]; pieChart.nameArray = [NSMutableArray arrayWithObjects:@"購物", @"美食", @"住房", @"交通", @"娛樂", nil]; pieChart.colorArray = [NSMutableArray arrayWithObjects:ZFColor(253, 118, 152, 1), ZFColor(254, 223, 219, 1), ZFColor(254, 206, 103, 1), ZFColor(81, 146, 218, 1), ZFColor(112, 182, 146, 1), nil]; [self.view addSubview:pieChart]; [self.pieChart strokePath]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
餅狀圖效果圖。本文的Demo是借鑒自網上,非博主純原創。敬請諒解。