效果图.png效果图如下:
主要代码如下 :
//用法实例
- (void)viewDidLoad {
[super viewDidLoad];
chart = [[ZYChartView alloc]initWithFrame:CGRectMake(20, 174, [UIScreen mainScreen].bounds.size.width-40, 200) delegate:self withType:Type_Line];
[self.view addSubview:chart];
}
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, TypeChart) {
Type_Line,
Type_Bar,
};
@class ZYChartView;
@protocol ZYChartViewDelegate <NSObject>
@required
- (NSArray<NSString*>*)zyChartViewLables;
@optional
@end
@interface ZYChartView : UIView
- (instancetype)initWithFrame:(CGRect)frame delegate:(id<ZYChartViewDelegate>)deleagte withType:(TypeChart)type;
@end
//
// ZYChartView.m
// UIChartTest
//
// Created by JonkeyChen on 16/11/9.
// Copyright © 2016年 oneyd.me. All rights reserved.
//
#import "ZYChartView.h"
#import "UIColor+Extension.h"
#import "ZYShapelayer.h"
#import "ZYScrollView.h"
#define xLabelsWidth 40 //底部文字显示宽度
#define xLabelsHeight 16 //底部文字高度
#define yLineNumber 5 //水平横线条数
#define yColumnWidth 15 //柱状图宽度
@interface ZYChartView ()<UIScrollViewDelegate,ZYScrollViewDelegate>
@property (nonatomic,assign) id<ZYChartViewDelegate> deleagte;
@property (nonatomic,assign) TypeChart chartType;
@property (nonatomic,strong) ZYScrollView *scrollView;
@property (nonatomic,strong) NSArray<NSString*> *xLabelsArray;//底部标题
@property (nonatomic,strong) NSArray<NSNumber*> *xLabelValues;//柱状图数据
@property (nonatomic,strong) NSArray<NSArray<NSNumber*>*> *yLabelValues;//折线图数据
@property (nonatomic,strong) NSMutableArray<NSValue*> *touchPoints;//每列竖直范围数组
@property (nonatomic,strong) CAShapeLayer *vertricalLine;//点击事的竖线
@property (nonatomic,assign) CGFloat originY;
@end
@implementation ZYChartView
- (instancetype)initWithFrame:(CGRect)frame delegate:(id<ZYChartViewDelegate>)deleagte withType:(TypeChart)type{
_deleagte = deleagte ;
_chartType = type ;
if (self = [super initWithFrame:frame]) {
[self setUpConfigure];
}
return self;
}
- (void)setUpConfigure {
if (!_xLabelsArray) {
_touchPoints = [[NSMutableArray alloc]init];
_xLabelsArray = @[@"1月",@"2月",@"3月",@"4月",
@"5月",@"6月",@"7月",@"8月",
@"9月",@"10月",@"11月",@"12月"];
}
if (!_xLabelValues) {
//柱状图数据
_xLabelValues = @[@20, @25,@19,@34,
@100,@79,@5, @200,
@100,@87,@54,@99];
}
if (!_yLabelValues) {
//折线图数据
_yLabelValues = @[
@[@30, @20,@19,@34,
@100,@90,@100, @66,
@100,@87,@54,@88],
@[@20, @30,@29,@14,
@90,@80,@110, @102,
@110,@97,@14,@90],
];
}
if (!_vertricalLine) {
//点击的竖线
_vertricalLine = [CAShapeLayer layer];
_vertricalLine.lineWidth = 1;
_vertricalLine.fillColor = [UIColor redColor].CGColor;
_vertricalLine.strokeColor = [UIColor redColor].CGColor;
[_scrollView.layer addSublayer:_vertricalLine];
}
CGFloat maxValueColum = 0 ;
if (!_scrollView) {
CGFloat paddingHeight = 0;
//计算柱状图最大最小值
for (int i= 0; i < _xLabelValues.count; i++) {
if (maxValueColum <= [_xLabelValues[i] intValue]) {
maxValueColum = [_xLabelValues[i] intValue];
}
}
_scrollView = [[ZYScrollView alloc]init];
_scrollView.frame = CGRectMake(0, 0,CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
_scrollView.contentSize = CGSizeMake(xLabelsWidth * _xLabelsArray.count, CGRectGetHeight(self.bounds));
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.didDeelgate = self;
[self addSubview:_scrollView];
//底部标签
_originY = CGRectGetHeight(_scrollView.frame) - xLabelsHeight;
for (int i = 0 ; i < _xLabelsArray.count; i++) {
UILabel *xLabel = [[UILabel alloc]init];
xLabel.frame = CGRectMake(0 + xLabelsWidth*i, _originY, xLabelsWidth, xLabelsHeight);
xLabel.font = [UIFont systemFontOfSize:10];
xLabel.textAlignment = NSTextAlignmentCenter;
xLabel.text = _xLabelsArray[i];
xLabel.textColor = [UIColor nomoarlBlack];
[_scrollView addSubview:xLabel];
[_touchPoints addObject:[NSValue valueWithCGRect:CGRectMake(xLabelsWidth*i, 0, xLabelsWidth, _originY)]];
}
//竖线--网格
for (int i = 0; i < _xLabelsArray.count; i++) {
UIBezierPath *beizerPath = [UIBezierPath bezierPath];
[beizerPath moveToPoint:CGPointMake(xLabelsWidth/2.0+xLabelsWidth*i, 0)];
[beizerPath addLineToPoint:CGPointMake(xLabelsWidth/2.0+xLabelsWidth*i, _originY)];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = beizerPath.CGPath;
shapeLayer.fillColor = [UIColor lightGrayColor].CGColor;
shapeLayer.strokeColor = [UIColor lightGrayColor].CGColor;
shapeLayer.lineWidth = 0.5;
[_scrollView.layer addSublayer:shapeLayer];
}
//横线--网格
paddingHeight = _originY/yLineNumber;
for (int i = 0; i < yLineNumber; i++) {
UIBezierPath *beizerPath = [UIBezierPath bezierPath];
[beizerPath moveToPoint:CGPointMake(xLabelsWidth/2.0, i*paddingHeight+paddingHeight)];
[beizerPath addLineToPoint:CGPointMake(_scrollView.contentSize.width-xLabelsWidth/2.0,i*paddingHeight+paddingHeight)];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = beizerPath.CGPath;
shapeLayer.fillColor = [UIColor lightGrayColor].CGColor;
shapeLayer.strokeColor = [UIColor lightGrayColor].CGColor;
shapeLayer.lineWidth = 0.5;
[_scrollView.layer addSublayer:shapeLayer];
}
}
//柱状图
for (int i = 0; i < _xLabelValues.count ; i++) {
//柱子高度
CGFloat heigth = ([_xLabelValues[i] intValue]/maxValueColum)*_originY;
UIBezierPath *beizerPath = [UIBezierPath bezierPath];
[beizerPath moveToPoint:CGPointMake(xLabelsWidth/2.0+xLabelsWidth*i, _originY + 0.5)];
[beizerPath addLineToPoint:CGPointMake(xLabelsWidth/2.0+xLabelsWidth*i,_originY - heigth)];
ZYShapelayer *shapeLayer = [ZYShapelayer layer];
shapeLayer.path = beizerPath.CGPath;
shapeLayer.fillColor = [UIColor blueColor].CGColor;
shapeLayer.strokeColor = [UIColor blueColor].CGColor;
shapeLayer.lineWidth = yColumnWidth;
[_scrollView.layer addSublayer:shapeLayer];
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration = 1.5;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnimation.fromValue = @0.0;
pathAnimation.toValue = @1.0;
pathAnimation.autoreverses = NO;
[shapeLayer addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
shapeLayer.strokeEnd = 2.0;
}
//折线图
for (int i = 0; i < _yLabelValues.count; i++) {
CGFloat maxVlaueLine = 0 ;
//计算线形图最大最小值
for (int j = 0 ; j < _yLabelValues[i].count; j++) {
if (maxVlaueLine <= [_yLabelValues[i][j] intValue]) {
maxVlaueLine = [_yLabelValues[i][j] intValue];
}
}
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
for (int j = 0; j < _yLabelValues[i].count; j ++) {
CGFloat heigth = ([_yLabelValues[i][j] integerValue]/maxVlaueLine)*_originY;
CGPoint point = CGPointMake(xLabelsWidth/2.0+xLabelsWidth*j,_originY - heigth);
if (j == 0) {
[bezierPath moveToPoint:point];
} else {
[bezierPath addLineToPoint:point];
}
}
ZYShapelayer *shapeLayer = [ZYShapelayer layer];
shapeLayer.path = bezierPath.CGPath;
shapeLayer.strokeColor = i==0?[UIColor zyRed].CGColor:[UIColor yellow].CGColor; // 线的颜色
shapeLayer.fillColor = [UIColor clearColor].CGColor; // 填充色
shapeLayer.lineWidth = 2;
[_scrollView.layer addSublayer:shapeLayer];
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration = 1.5;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnimation.fromValue = @0.0;
pathAnimation.toValue = @1.0;
pathAnimation.autoreverses = NO;
[shapeLayer addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
shapeLayer.strokeEnd = 2.0;
}
}
///点击网格内的空白处
- (void)zyScrollView:(ZYScrollView *)scrollView withDidPoint:(CGPoint)point {
for (int i = 0; i < _touchPoints.count; i++) {
CGRect value = [_touchPoints[i] CGRectValue];
if (CGRectContainsPoint(value, point)) {
[_vertricalLine removeFromSuperlayer];
UIBezierPath *beizerPath = [UIBezierPath bezierPath];
[beizerPath moveToPoint:CGPointMake(xLabelsWidth/2.0+xLabelsWidth*i, 0)];
[beizerPath addLineToPoint:CGPointMake(xLabelsWidth/2.0+xLabelsWidth*i, _originY)];
_vertricalLine.path = beizerPath.CGPath;
[_scrollView.layer addSublayer:_vertricalLine];
}
}
}
@end
网友评论