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