IOS绘制柱状图

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MPK_Github/article/details/80989013

1、创建单个Bar视图,可以继承base类,也可以继承UIVIew

#import "PKBaseChartView.h"


@interface PKBarChartView : PKBaseChartView

@property (assign, nonatomic) CGFloat lenght;

@property (copy, nonatomic) NSString *labelText;

@property (strong, nonatomic) UIColor *color;


- (void)drawBar;


@end


实现文件:

#import "PKBarChartView.h"


static const CGFloat defaultFontSize = 10.f;

static const CGFloat defaultFontSpace = 2;


@interface PKBarChartView ()<CAAnimationDelegate>

@property (assign, nonatomic) CGFloat fontSize;

@property (assign, nonatomic) CGFloat fontSpace;

@property (strong, nonatomic) UIColor *textColor;


@property (strong, nonatomic) CAShapeLayer *chartLayer;

@property (strong, nonatomic) CATextLayer *textLayer;


@end


@implementation PKBarChartView


#pragma mark - life cycle

-(instancetype)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self) {

        [self initDefalutAttributes];

    }

    return self;

}

-(instancetype)init

{

    self = [super init];

    if (self) {

        [self initDefalutAttributes];

    }

    return self;

}

- (void)initDefalutAttributes

{

    self.isAnimated = YES;

    self.fontSize = defaultFontSize;

    self.fontSpace = defaultFontSpace;

    self.textColor = [UIColor blackColor];

    self.color = [UIColor blueColor];

    self.chartLayer = [CAShapeLayer layer];

    self.chartLayer.lineCap = kCALineCapButt;

    self.chartLayer.strokeEnd = 1.0;

    [self.layer addSublayer:self.chartLayer];

    

    self.textLayer = [CATextLayer layer];

    self.textLayer.contentsScale = [UIScreen mainScreen].scale;

    self.textLayer.hidden = YES;

    [self.layer addSublayer:self.textLayer];

    

}

#pragma mark - public methods

-(void)drawBar

{

    [self buildPath];

    [self addAnimation];

    [self bulidTextLayer];

}

#pragma mark - private methods

- (void)buildPath

{

    self.chartLayer.lineWidth = CGRectGetWidth(self.frame);

    self.chartLayer.strokeColor = self.color.CGColor;

    self.chartLayer.fillColor = [UIColor clearColor].CGColor;

    CGPoint beginPoint = CGPointMake(CGRectGetWidth(self.frame) / 2.0, CGRectGetHeight(self.frame));

    CGPoint endPoint = CGPointMake(CGRectGetWidth(self.frame) / 2.0, CGRectGetHeight(self.frame) - self.lenght);

    UIBezierPath *path = [UIBezierPath bezierPath];

    path.lineCapStyle = kCGLineCapRound;

    path.lineJoinStyle = kCGLineJoinRound;

    [path moveToPoint:beginPoint];

    [path addLineToPoint:endPoint];

    self.chartLayer.path = path.CGPath;

}

- (void)addAnimation

{

    if (self.isAnimated) {

        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];

        animation.duration = 1.5;

        animation.fromValue = @(0);

        animation.toValue = @(1);

        animation.delegate = self;

        [self.chartLayer addAnimation:animation forKey:@"barAnimation"];

    }

}

- (void)bulidTextLayer

{

    CGFloat topMargin = CGRectGetHeight(self.frame) - self.lenght;

    self.textLayer.frame = CGRectMake(-CGRectGetWidth(self.frame), topMargin - self.fontSize - self.fontSpace, CGRectGetWidth(self.frame) * [UIScreen mainScreen].scale, self.fontSize);

    self.textLayer.alignmentMode = kCAAlignmentCenter;

    self.textLayer.wrapped = YES;

    self.textLayer.foregroundColor = self.textColor.CGColor;

    UIFont *font = [UIFont systemFontOfSize:self.fontSize];

    CFStringRef fontName= (__bridge_retained CFStringRef)font.fontName;

    CGFontRef fontRef = CGFontCreateWithFontName(fontName);

    self.textLayer.font = fontRef;

    self.textLayer.fontSize = font.pointSize;

    CGFontRelease(fontRef);

    self.textLayer.string = self.labelText;

}

#pragma mark - CAAnimationDelegate

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

{

    self.textLayer.hidden = NO;

}

@end



//定义柱状图,继承坐标系视图

#import "PKBaseLineChartView.h"

#import "PKBarChartItem.h"


@interface PKBarGraphChartView : PKBaseLineChartView

@property (strong, nonatomic) NSMutableArray<PKBarChartItem *> *values;


- (void)updateBarChartWithArray:(NSArray *)array;


@end


//实现文件

#import "PKBarGraphChartView.h"

#import "PKBarChartView.h"


@interface PKBarGraphChartView ()

@property (strong, nonatomic) NSMutableArray *barArray;


@end


@implementation PKBarGraphChartView


#pragma mark - life cycle

-(instancetype)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self) {

        [self initDefaultAttr];

    }

    return self;

}

- (void)initDefaultAttr

{

    

}

#pragma mark - public methods

-(void)updateBarChartWithArray:(NSArray *)array

{

    if (array.count == 0) {

        return;

    }

    [self.values removeAllObjects];

    [self.values addObjectsFromArray:array];

    [self drawChart];

}

-(void)drawChart

{

    [super drawChart];

    [self removeBarView];

    [self addBars];

}

#pragma mark - private method

- (void)removeBarView

{

    for (PKBarChartView *view in self.barArray) {

        [view removeFromSuperview];

    }

    [self.barArray removeAllObjects];

}

- (void)addBars

{

    CGFloat margin = [self calculateBarMarginAndBarWidth];

    CGFloat beginX = self.ylabelWidth;

    for (int index = 0; index < self.values.count; index++) {

        PKBarChartItem *item = self.values[index];

        CGFloat max = [[item.values valueForKeyPath:@"@max.floatValue"] floatValue];

        CGPoint position = CGPointMake(beginX + margin, self.topMargin);

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

            CGFloat value = [item.values[item.values.count - 1 - i] floatValue];

            CGFloat percentage = value / max;

            CGFloat xPositon = position.x + i * self.chartWidth / item.values.count;

            CGFloat yPositon = position.y;

            [self bulidBarWithX:xPositon y:yPositon item:item percentage:percentage value:value];

        }

        beginX += item.width;

    }

}

- (void)bulidBarWithX:(CGFloat)x y:(CGFloat)y item:(PKBarChartItem *)item percentage:(CGFloat)percentage value:(CGFloat)value

{

    PKBarChartView *bar = [[PKBarChartView alloc] initWithFrame:CGRectMake(x, y, item.width, self.chartHeight)];

    bar.lenght = self.chartHeight * percentage;

    bar.color = item.color;

    bar.labelText = [NSString stringWithFormat:@"%.2f",value];

    [self addSubview:bar];

    [self.barArray addObject:bar];

    [bar drawBar];

}

- (CGFloat)calculateBarMarginAndBarWidth

{

    //垂直方向

    CGFloat labelHeight = self.chartWidth / self.xLabelTextArray.count;

    CGFloat totalHeight = 0;

    CGFloat scale = 1;

    for (PKBarChartItem *item in self.values) {

        totalHeight += item.width;

    }

    

    if (totalHeight > labelHeight) {

        scale = labelHeight / totalHeight;

    }

    

    for (PKBarChartItem *model in self.values) {

        model.width = model.width * scale;

    }

    return (labelHeight - totalHeight * scale) / 2.0;

}

#pragma mark -getter and setter

-(NSMutableArray<PKBarChartItem *> *)values

{

    if (!_values) {

        _values = [NSMutableArray array];

    }

    return _values;

}

-(NSMutableArray *)barArray

{

    if (!_barArray) {

        _barArray = [NSMutableArray array];

    }

    return _barArray;

}

@end


//mode类为

#import <Foundation/Foundation.h>

#import <UIKit/UIKit.h>


@interface PKBarChartItem : NSObject

@property (strong, nonatomic) UIColor *color;

@property (assign, nonatomic) CGFloat width;

@property (strong, nonatomic) NSArray *values;


- (instancetype)initWithColor:(UIColor *)color width:(CGFloat)width values:(NSArray *)values;


@end


猜你喜欢

转载自blog.csdn.net/MPK_Github/article/details/80989013