• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

iOS Objective-C 自定义饼状图

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

前些天项目中使用了饼状图,现在开发完做下记录。

//

//  PieChartView.h

#import <UIKit/UIKit.h>

@protocol PieChartViewDelegate

@required

-(NSInteger)getChartRows;

-(NSString*)getChartName:(NSInteger)row;

-(CGFloat)getChartRate:(NSInteger)row;

-(void)didSelectChartView:(NSInteger)row;

@end

@interface PieChartView : UIView

@property(nonatomic,weak)id<PieChartViewDelegate> delegate;

@end

//

//  PieChartView.m

//  NbanClient

//


#import "PieChartView.h"


static NSArray *chartColors;

@interface PieChartView()<CAAnimationDelegate>

{

    NSInteger _currentIndex;

    BOOL _isShowAnimate;//判断自身是否处于外部

    UIView *_circleView;//中心圆形

}

@property(nonatomic,copy)NSArray *chartColors;

@property(nonatomic,strong)NSMutableArray *chartRanColors;

@property(nonatomic,strong)NSMutableArray *chartPaths;

@property(nonatomic,strong)NSMutableArray *chartLinePaths;

@property(nonatomic,strong)NSMutableArray<UILabel*> *chartLabels;

@property(nonatomic,strong)NSMutableArray<NSNumber*> *labelWidths;

@property(nonatomic,strong)CAShapeLayer*  animateBackLayer;


@end


@implementation PieChartView


- (instancetype)init

{

    self = [super init];

    if (self) {

        self.backgroundColor = UIColorFromRGB(0xf2f2f2);

        

        UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(taphandle:)];

        [self addGestureRecognizer:gesture];

        _chartPaths = [[NSMutableArray alloc]init];

        _chartLinePaths = [[NSMutableArray alloc]init];

        _chartRanColors = [[NSMutableArray alloc]init];

        _chartLabels = [[NSMutableArray alloc]init];

        _labelWidths = [[NSMutableArray alloc]init];

    }

    return self;

}


- (void)drawRect:(CGRect)rect {

    [_chartLinePaths removeAllObjects];

    [_chartPaths removeAllObjects];

    [_chartRanColors removeAllObjects];

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetStrokeColorWithColor(context, [UIColorFromRGB(0xffffff) CGColor]);

    CGContextSetFillColorWithColor(context, [UIColorFromRGB(0xffffff) CGColor]);

    CGContextAddRect(context, CGRectMake(AdapterW(16), 0, screen_width-AdapterW(32), rect.size.height));

    CGContextDrawPath(context, kCGPathFillStroke);

    if (_delegate) {

        NSInteger count = [_delegate getChartRows];

        NSMutableArray *currentChartColors = [[NSMutableArray alloc]initWithArray:self.chartColors];

        CGFloat allRate = 0;

        for (int i = 0; i<count; i++) {

            if ([currentChartColors count] == 0) {

                currentChartColors = [[NSMutableArray alloc]initWithArray:self.chartColors];

            }

            UIBezierPath *path = [UIBezierPath bezierPath];

            NSInteger ran =  random()%[currentChartColors count];

            [_chartRanColors addObject:currentChartColors[ran]];

            CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);

            CGContextSetFillColorWithColor(context, [currentChartColors[ran] CGColor]);

            CGFloat rate = [_delegate getChartRate:i];

            [path moveToPoint:self.center];

            [path addArcWithCenter:self.center radius:75 startAngle:M_PI*2*allRate endAngle:M_PI*2*(rate+allRate) clockwise:YES];

           // CGContextMoveToPoint(context, rect.size.width/2, rect.size.height/2);

            //CGContextAddArc(context, rect.size.width/2, rect.size.height/2, 75, M_PI*2*allRate, M_PI*2*(rate+allRate), NO);

            [path closePath];

            CGContextAddPath(context, [path CGPath]);

            CGContextDrawPath(context, kCGPathFillStroke);

            [_chartPaths addObject:path];

            UIBezierPath *linePath = [UIBezierPath bezierPath];

            CGContextSetStrokeColorWithColor(context, [currentChartColors[ran] CGColor]);

            CGPoint midPoint = [self getArcMidPoint:rate/2+allRate];

            CGPoint endPoint = [self getArcEndMidPoint:rate/2+allRate district:[self isDistrctLine:rate/2+allRate] endRadius:20];

            [linePath moveToPoint:CGPointMake(midPoint.x, midPoint.y)];

            //CGContextMoveToPoint(context, midPoint.x, midPoint.y);

            if([self isDistrctLine:rate/2+allRate]){

                [linePath addLineToPoint:endPoint];

               // CGContextAddLineToPoint(context, endPoint.x, endPoint.y);

            }

            else {

                CGPoint controlPoint = [self getArcControlMidPoint:rate/2+allRate];

                [linePath addQuadCurveToPoint:endPoint controlPoint:controlPoint];

                //CGContextAddQuadCurveToPoint(context, controlPoint.x, controlPoint.y, endPoint.x, endPoint.y);

            }

            CGContextAddPath(context, [linePath CGPath]);

            CGContextStrokePath(context);

            [_chartLinePaths addObject:linePath];

    

            CGFloat rateWidth = [[APPManager defaultManager] getTextWidth:[NSString stringWithFormat:@"%.2f%%",[_delegate getChartRate:i]*100] setHeight:20 setFont:[UIFont systemFontOfSize:AdapterF(9)]];

            NSString *name = [NSString stringWithFormat:@"%@\n%.2f%%",[_delegate getChartName:i],[_delegate getChartRate:i]*100];

            CGFloat labelWidth = [[APPManager defaultManager] getTextWidth:name setHeight:20 setFont:[UIFont systemFontOfSize:AdapterF(9)]];

            if (labelWidth<rateWidth) {

                labelWidth = rateWidth;

            }

            if (midPoint.x>endPoint.x) {

                if (endPoint.x-8<labelWidth) {

                    labelWidth = endPoint.x-8;

                }

            }

            else {

                if (self.frame.size.width-endPoint.x-8<labelWidth) {

                    labelWidth = self.frame.size.width-endPoint.x-8;

                }

            }

            [_labelWidths addObject:[NSNumber numberWithFloat:labelWidth]];

            UILabel*label = [[UILabel alloc]init];

            //label.backgroundColor = UIColorFromRGB(0xff0000);

            label.textColor = UIColorFromRGB(0x999999);

            label.font = [UIFont systemFontOfSize:AdapterF(8)];

            label.text = name;

            label.textAlignment = NSTextAlignmentCenter;

            label.numberOfLines = 0;

            [self addSubview:label];

            [label mas_makeConstraints:^(MASConstraintMaker *make) {

                if (midPoint.x>endPoint.x) {

                    make.right.mas_equalTo(-(self.frame.size.width-endPoint.x)-8);

                    

                    //make.left.mas_equalTo(0);

                }

                else {

                    make.left.mas_equalTo(endPoint.x+8);

                   // make.right.mas_equalTo(0);

                }

                make.top.mas_equalTo(endPoint.y-10);

                make.height.mas_equalTo(25);

                make.width.mas_equalTo(labelWidth);

            }];

            [_chartLabels addObject:label];

            allRate = allRate + rate;

            [currentChartColors removeObjectAtIndex:ran];

        }

        UIView *circleView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 13, 13)];

        circleView.layer.cornerRadius = 6.5;

        circleView.backgroundColor = [UIColor whiteColor];

        circleView.center = self.center;

        [self addSubview:circleView];

        [circleView bringSubviewToFront:circleView];

//        CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);

//        CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]);

//        CGContextAddArc(context, rect.size.width/2, rect.size.height/2, 6.5, 0, M_PI*2, NO);

//        CGContextDrawPath(context, kCGPathFillStroke);

        

    }

    

    

}

- (NSArray*)chartColors{

    if (!_chartColors) {

         _chartColors = [[NSArray alloc]initWithObjects:UIColorFromRGB(0xFFEF6B),UIColorFromRGB(0xFF814A),UIColorFromRGB(0x56CA77),UIColorFromRGB(0xFFA6F9),UIColorFromRGB(0x45A3FC),UIColorFromRGB(0xA6A9FF),UIColorFromRGB(0x47CBCA),UIColorFromRGB(0xFFC491),UIColorFromRGB(0xF0657D),UIColorFromRGB(0xCC8CF5),UIColorFromRGB(0xB7E89E),UIColorFromRGB(0xFF7F74), nil];

    }

    return _chartColors;

}


/**

 获取扇形上中点坐标


 @param arc 占有率

 @return 坐标 CGPoint

 */

- (CGPoint)getArcMidPoint:(float)arc

{

    CGFloat angle = M_PI*2.0*arc;//将进度转换成弧度

    float radius = 75;//半径

    int index = (angle)/M_PI_2;//用户区分在第几象限内

    float needAngle = angle - index*M_PI_2;//用于计算正弦/余弦的角度

    float x = 0,y = 0;

    switch (index) {

        case 3:

          //  NSLog(@"第一象限");

            x = self.frame.size.width/2 + sinf(needAngle)*radius;

            y = self.frame.size.height/2 - cosf(needAngle)*radius;

            break;

        case 0:

           // NSLog(@"第二象限");

            x = self.frame.size.width/2  + cosf(needAngle)*radius;

            y = self.frame.size.height/2 + sinf(needAngle)*radius;

            break;

        case 1:

          //  NSLog(@"第三象限");

            x = self.frame.size.width/2 - sinf(needAngle)*radius;

            y = self.frame.size.height/2  + cosf(needAngle)*radius;

            break;

        case 2:

          //  NSLog(@"第四象限");

            x = self.frame.size.width/2 - cosf(needAngle)*radius;

            y = self.frame.size.height/2 - sinf(needAngle)*radius;

            break;

            

        default:

            break;

    }

    return  CGPointMake(x, y);

}

/**

 获取扇形上直线坐标

 

 @param arc 占有率

 @return 坐标 CGPoint

 */

- (CGPoint)getArcEndMidPoint:(float)arc district:(BOOL)isDistrict endRadius:(CGFloat)endRadius

{

    CGFloat angle = M_PI*2.0*arc;//将进度转换成弧度

    float radius = 75+endRadius;//半径

    int index = (angle)/M_PI_2;//用户区分在第几象限内

    float needAngle = angle - index*M_PI_2;//用于计算正弦/余弦的角度

    float x = 0,y = 0;

    switch (index) {

        case 3:

           // NSLog(@"第一象限");

            if (isDistrict) {

                x = self.frame.size.width/2 + sinf(needAngle)*radius;

                y = self.frame.size.height/2 - cosf(needAngle)*radius;

            }

            else {

                x = self.


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap