前言
- 最近項(xiàng)目中要求使用柱狀圖來顯示數(shù)據(jù),但是要求在柱子上顯示不同的顏色,查找了很多第三方的庫,然而并沒有找到合適的,無奈之下只好自己進(jìn)行封裝.
- 參考資料
http://blog.csdn.net/nb_killer/article/details/51023948
http://www.cnblogs.com/nightcat/p/ios_01.html
PNChart 庫
效果圖
- 柱子的高度是到頂部的,由于柱子的顏色和View背景色一致了,無法看清,更改下背景色就能看到了,柱子的最大值是1440,可以根據(jù)自己需求進(jìn)行更改 這個(gè)屬性 MAX_TIME
![MKChart.gif](http://upload-images.jianshu.io/upload_images/2597026-70c5424b0f14cbef.gif)
本文主要參考了PNChart ,有興趣的同學(xué)可以去學(xué)習(xí)下
廢話不說了,直接上代碼主要分為3個(gè)類
MKBar: 是單個(gè)柱子,包括繪制和數(shù)據(jù)的分段處理
BarLayerView : 主要是繪制多個(gè)柱子,對(duì)柱子進(jìn)行更新等
ViewController : 展示界面
MKBar
MKBar.h
#import <UIKit/UIKit.h>
@interface MKBar : UIView
@property (nonatomic,copy)NSString *titleStr;//標(biāo)題
@property (nonatomic,strong)NSMutableArray *dataArr;//數(shù)據(jù) 注意數(shù)據(jù)格式
@end
MKBar.m
#define MAX_TIME 1440
#define RGB(r,g,b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
@interface MKBar ()
@property (nonatomic) CATextLayer* textLayer;//標(biāo)題Layer
@property (nonatomic,strong)NSMutableArray *barArr;//柱子上面進(jìn)度數(shù)據(jù)
@property (nonatomic,assign)float totalNum;//總的進(jìn)度時(shí)間
@property (nonatomic,strong)UILabel *titleLab;//下面標(biāo)題 也可以使用CATextLayer
@end
@implementation MKBar
-(instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
}
return self;
}
-(void)setTitleStr:(NSString *)titleStr
{
_titleStr = titleStr;
[self addSubview:self.titleLab];
//CABasicAnimation *fade = [self fadeAnimation];
//[self.textLayer addAnimation:fade forKey:nil];
//[self.layer addSublayer:self.textLayer];
}
-(void)setDataArr:(NSMutableArray *)dataArr
{
_dataArr = dataArr;
self.barArr = [self barProgressArr:_dataArr];
[self setProgress];
}
#pragma mark ---畫圖
-(void)setProgress
{
__block float a = 0;
//遍歷數(shù)組
[self.barArr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//畫路徑
UIBezierPath *beziPath = [UIBezierPath bezierPath];
beziPath.lineWidth = 0.0;//線的寬度
//起點(diǎn)坐標(biāo)
[beziPath moveToPoint:CGPointMake(15,self.bounds.size.height-20)];
//終點(diǎn)坐標(biāo)
[beziPath addLineToPoint:CGPointMake(15,(MAX_TIME-self.totalNum)/MAX_TIME*(self.bounds.size.height-20))];
beziPath.lineCapStyle = kCGLineCapRound;
beziPath.lineJoinStyle = kCGLineJoinRound;
[beziPath stroke];
//畫圖
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.strokeColor = [obj[@"strokeColor"]CGColor];
shapeLayer.lineWidth = 30.0;//寬度 目前是固定寬度 可以根據(jù)情況進(jìn)行修改
shapeLayer.strokeStart = a;//起始點(diǎn)
shapeLayer.strokeEnd = [obj[@"precent"] floatValue]+a;//結(jié)束點(diǎn)
a = shapeLayer.strokeEnd;//從上一個(gè)起始點(diǎn)開始畫圖
shapeLayer.path = beziPath.CGPath;//產(chǎn)生聯(lián)系
[self.layer addSublayer:shapeLayer];
//動(dòng)畫
CABasicAnimation*pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration=1.0f;
pathAnimation.timingFunction= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnimation.fromValue=@0.0f;
pathAnimation.toValue=@(1);
[shapeLayer addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
}];
}
#pragma mark ---處理進(jìn)度數(shù)據(jù)
-(NSMutableArray *)barProgressArr:(NSMutableArray *)dataArr
{
NSMutableArray *barProgArr = [[NSMutableArray alloc]initWithCapacity:0];
self.totalNum = 0.0;//總的時(shí)間
float value = 0.0;//每一段時(shí)間
NSString *boolStr;
//計(jì)算總時(shí)間
for (NSDictionary *dic in dataArr)
{
value = [dic[@"precent"] floatValue];
self.totalNum = self.totalNum + value;
}
//計(jì)算進(jìn)度值
for (NSDictionary *dic in dataArr)
{
value = [dic[@"precent"] floatValue];
boolStr = dic[@"strokeColor"];
NSMutableDictionary *progDic = [[NSMutableDictionary alloc]initWithCapacity:0];
//根據(jù)BOOL確定顏色 當(dāng)然也可以添加多種顏色
if ([boolStr isEqualToString:@"1"])
{
[progDic setObject:[UIColor redColor] forKey:@"strokeColor"];
}
else
{
[progDic setObject:RGB(83, 193, 124) forKey:@"strokeColor"];
}
//計(jì)算進(jìn)度 添加進(jìn)數(shù)組
[progDic setObject:@(value/self.totalNum) forKey:@"precent"];
[barProgArr addObject:progDic];
}
return barProgArr;
}
-(UILabel *)titleLab
{
if (!_titleLab)
{
_titleLab = [[UILabel alloc]initWithFrame:CGRectMake(0, self.bounds.size.height-20, self.bounds.size.width, 20)];
_titleLab.font = [UIFont systemFontOfSize:14.0];
_titleLab.textAlignment = NSTextAlignmentCenter;
_titleLab.textColor = [UIColor whiteColor];
_titleLab.text = self.titleStr;
}
return _titleLab;
}
#pragma mark ---可以使用CATextLayer
-(CATextLayer*)textLayer
{
if (!_textLayer) {
_textLayer = [[CATextLayer alloc]init];
_textLayer.string = self.titleStr;
_textLayer.frame = CGRectMake(0, self.bounds.size.height-20, self.bounds.size.width, 20);
[_textLayer setAlignmentMode:kCAAlignmentCenter];
[_textLayer setForegroundColor:[[UIColor whiteColor] CGColor]];
_textLayer.fontSize = 14.0;
}
return _textLayer;
}
//動(dòng)畫
-(CABasicAnimation*)fadeAnimation
{
CABasicAnimation* fadeAnimation = nil;
fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeAnimation.fromValue = [NSNumber numberWithFloat:0.0];
fadeAnimation.toValue = [NSNumber numberWithFloat:1.0];
fadeAnimation.duration = 2.0;
return fadeAnimation;
}
BarLayerView
BarLayerView.h
#import <UIKit/UIKit.h>
@interface BarLayerView : UIView
@property (nonatomic,strong)NSMutableArray *xArr;//X軸數(shù)據(jù)
@property (nonatomic,strong)NSMutableArray *dataArr;//進(jìn)度數(shù)據(jù)
@property (nonatomic,strong)NSMutableArray *barArr;//存放柱子的數(shù)組 用來刪除
-(void)strokeMKBarChart;//繪制
@end
BarLayerView.m
#import "BarLayerView.h"
#import "MKBar.h"
#define RGB(r,g,b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
@implementation BarLayerView
-(instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
self.barArr = [[NSMutableArray alloc]initWithCapacity:0];
}
return self;
}
-(void)setXArr:(NSMutableArray *)xArr
{
_xArr = xArr;
}
-(void)setDataArr:(NSMutableArray *)dataArr
{
_dataArr = dataArr;
}
-(void)strokeMKBarChart
{
//刪除所有的柱子
[self viewCleanupForCollection:self.barArr];
[self upDateMKBarChart];
}
//繪圖
-(void)upDateMKBarChart
{
CGFloat barInterval = (self.bounds.size.width-(30*(self.xArr.count+1)))/(self.xArr.count-1);
for (int a = 0; a < self.xArr.count; a++)
{
MKBar *bar = [[MKBar alloc]initWithFrame:CGRectMake(10+(barInterval+30)*a, 0, 30, self.bounds.size.height)];
bar.backgroundColor = RGB(54, 63, 86);
[bar setDataArr:self.dataArr[a]];
[bar setTitleStr:self.xArr[a]];
[self.barArr addObject:bar];//添加進(jìn)數(shù)組中,重繪時(shí)刪除,重新創(chuàng)建
[self addSubview:bar];
}
}
//刪除所有的柱子
- (void)viewCleanupForCollection:(NSMutableArray *)array
{
if (array.count) {
[array makeObjectsPerformSelector:@selector(removeFromSuperview)];
[array removeAllObjects];
}
}
ViewController
#import "ViewController.h"
#import "BarLayerView.h"
#import "MKBar.h"
#define RGB(r,g,b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
@interface ViewController ()
@property (nonatomic,strong)CAShapeLayer *shapeLayer;
@property (nonatomic,strong)BarLayerView *barLayerView;
@end
- (void)viewDidLoad {
[super viewDidLoad];
//測(cè)試數(shù)據(jù)
//單個(gè)柱子上的分段數(shù)據(jù)
NSMutableArray *arr = [[NSMutableArray alloc]initWithCapacity:0];
//需要展示幾段
[arr addObject:@{@"precent":@"200",@"strokeColor":@"1"}];
[arr addObject:@{@"precent":@"100",@"strokeColor":@"0"}];
[arr addObject:@{@"precent":@"200",@"strokeColor":@"1"}];
[arr addObject:@{@"precent":@"300",@"strokeColor":@"0"}];
[arr addObject:@{@"precent":@"200",@"strokeColor":@"1"}];
//柱子個(gè)數(shù)
NSMutableArray *dataArr = [[NSMutableArray alloc]initWithCapacity:0];
[dataArr addObject:arr];
[dataArr addObject:arr];
[dataArr addObject:arr];
[dataArr addObject:arr];
[dataArr addObject:arr];
[dataArr addObject:arr];
[dataArr addObject:arr];
//X軸數(shù)據(jù)
NSMutableArray *xArr = [[NSMutableArray alloc]initWithCapacity:0];
[xArr addObject:@"1"];
[xArr addObject:@"2"];
[xArr addObject:@"3"];
[xArr addObject:@"4"];
[xArr addObject:@"5"];
[xArr addObject:@"6"];
[xArr addObject:@"7"];
self.barLayerView = [[BarLayerView alloc]initWithFrame:CGRectMake(00, 100, self.view.bounds.size.width, 200)];
self.barLayerView.backgroundColor = RGB(54, 63, 86);
[self.barLayerView setDataArr:dataArr];//設(shè)置柱子進(jìn)度
[self.barLayerView setXArr:xArr];//設(shè)置XLable
[self.barLayerView strokeMKBarChart];//重繪
[self.view addSubview:self.barLayerView];
}
當(dāng)然Demo也有許多需要更改的地方,比如固定的寬度等等
如果感覺對(duì)您有幫助,請(qǐng)順手點(diǎn)個(gè)贊,哈哈....
原創(chuàng)文章,如果轉(zhuǎn)載,請(qǐng)注明出處,謝謝.