You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
376 lines
13 KiB
376 lines
13 KiB
// |
|
// FBYLineGraphContentView.m |
|
// FBYDataDisplay-iOS |
|
// |
|
// Created by fby on 2018/1/18. |
|
// Copyright © 2018年 FBYDataDisplay-iOS. All rights reserved. |
|
// |
|
|
|
#import "FBYLineGraphContentView.h" |
|
|
|
#import "FBYLineGraphColorView.h" |
|
|
|
// Tag 基初值 |
|
#define BASE_TAG_COVERVIEW 100 |
|
#define BASE_TAG_CIRCLEVIEW 200 |
|
#define BASE_TAG_POPBTN 300 |
|
|
|
@interface FBYLineGraphContentView() { |
|
//存点位置的数组 |
|
NSMutableArray *pointArray; |
|
NSInteger lastSelectedIndex; |
|
//暂存的Rect; |
|
CGRect _tempRect; |
|
} |
|
|
|
/// 存点的点击View 的数组 |
|
@property(nonatomic, strong) NSMutableArray<UIView*> *pointTapViewArray; |
|
@end |
|
|
|
@implementation FBYLineGraphContentView |
|
|
|
-(UIColor *)MainColor{ |
|
if(!_MainColor){ |
|
_MainColor = [UIColor colorWithRed:255/255.0 green:69/255.0 blue:0/255.0 alpha:1]; |
|
} |
|
return _MainColor; |
|
} |
|
- (void)setMaxValue:(CGFloat)maxValue { |
|
_maxValue = maxValue; |
|
} |
|
|
|
- (void)setValueArray:(NSArray *)valueArray { |
|
_valueArray = valueArray; |
|
} |
|
|
|
- (instancetype)initWithFrame:(CGRect)frame { |
|
self = [super initWithFrame:frame]; |
|
if (self) { |
|
lastSelectedIndex = - 1; |
|
pointArray = [NSMutableArray array]; |
|
_pointTapViewArray = [NSMutableArray array]; |
|
_tempRect = CGRectZero; |
|
self.yAxis_L = frame.size.height; |
|
self.xAxis_L = frame.size.width; |
|
|
|
} |
|
return self; |
|
} |
|
|
|
- (void)mapping { |
|
|
|
[super mapping]; |
|
|
|
[self drawChartLine]; |
|
[self drawGradient]; |
|
|
|
[self setupCircleViews]; |
|
[self setupCoverViews]; |
|
} |
|
|
|
- (void)reloadDatas { |
|
|
|
[super reloadDatas]; |
|
|
|
[self clearView]; |
|
[self mapping]; |
|
} |
|
|
|
#pragma mark 画折线图 |
|
- (void)drawChartLine |
|
{ |
|
UIBezierPath *pAxisPath = [[UIBezierPath alloc] init]; |
|
|
|
CGFloat unint_X = self.xAxis_L / (_xMarkmaxValue - _xMarkminValue); |
|
|
|
for (int i = 0; i < self.valueArray.count; i ++) { |
|
|
|
|
|
|
|
CGFloat value = [self.valueArray[i] floatValue]; |
|
//x轴的比例 |
|
// NSString *yTitle = [NSString stringWithFormat:@"%@",self.xMarkValues[i]]; |
|
// NSArray *arr = [yTitle componentsSeparatedByString:@"."]; |
|
CGFloat xMarkValue = [self.xMarkValues[i] floatValue]; |
|
CGFloat point_X = (xMarkValue-_xMarkminValue) * unint_X + self.startPoint.x; |
|
//Y轴比例 |
|
CGFloat percent = (value - self.minValue) / (self.maxValue - self.minValue); |
|
CGFloat point_Y = self.yAxis_L * (1 - percent) + self.startPoint.y; |
|
// CGFloat point_Y = self.yAxis_L - (value-_minValue) * unint_Y; |
|
|
|
CGPoint point = CGPointMake(point_X, point_Y); |
|
|
|
// 记录各点的坐标方便后边添加渐变阴影 和 点击层视图 等 |
|
[pointArray addObject:[NSValue valueWithCGPoint:point]]; |
|
|
|
if (i == 0) { |
|
[pAxisPath moveToPoint:point]; |
|
} |
|
else { |
|
[pAxisPath addLineToPoint:point]; |
|
} |
|
} |
|
|
|
CAShapeLayer *pAxisLayer = [CAShapeLayer layer]; |
|
pAxisLayer.lineWidth = 1; |
|
pAxisLayer.strokeColor = self.MainColor.CGColor; |
|
pAxisLayer.fillColor = [UIColor clearColor].CGColor; |
|
pAxisLayer.path = pAxisPath.CGPath; |
|
[self.layer addSublayer:pAxisLayer]; |
|
} |
|
|
|
#pragma mark 渐变阴影 |
|
- (void)drawGradient { |
|
|
|
CAGradientLayer *gradientLayer = [CAGradientLayer layer]; |
|
gradientLayer.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); |
|
// gradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:250/255.0 green:170/255.0 blue:10/255.0 alpha:0.8].CGColor,(__bridge id)[UIColor colorWithWhite:1 alpha:0.1].CGColor]; |
|
|
|
gradientLayer.colors = @[(__bridge id)self.MainColor.CGColor,(__bridge id)[UIColor colorWithWhite:1 alpha:0.1].CGColor]; |
|
|
|
gradientLayer.locations=@[@0.0,@1.0]; |
|
gradientLayer.startPoint = CGPointMake(0.0,0.0); |
|
gradientLayer.endPoint = CGPointMake(0.0,1); |
|
|
|
UIBezierPath *gradientPath = [[UIBezierPath alloc] init]; |
|
// [gradientPath moveToPoint:CGPointMake(self.startPoint.x, self.yAxis_L + self.startPoint.y)]; |
|
CGPoint startPoint = [[pointArray firstObject] CGPointValue]; |
|
[gradientPath moveToPoint:CGPointMake(startPoint.x, self.yAxis_L + self.startPoint.y)]; |
|
for (int i = 0; i < pointArray.count; i ++) { |
|
[gradientPath addLineToPoint:[pointArray[i] CGPointValue]]; |
|
} |
|
|
|
CGPoint endPoint = [[pointArray lastObject] CGPointValue]; |
|
// endPoint = CGPointMake(endPoint.x + self.startPoint.x, self.yAxis_L + self.startPoint.y); |
|
endPoint = CGPointMake(endPoint.x, self.yAxis_L + self.startPoint.y); |
|
[gradientPath addLineToPoint:endPoint]; |
|
CAShapeLayer *arc = [CAShapeLayer layer]; |
|
arc.path = gradientPath.CGPath; |
|
gradientLayer.mask = arc; |
|
[self.layer addSublayer:gradientLayer]; |
|
|
|
} |
|
|
|
#pragma mark 折线上的圆环 |
|
- (void)setupCircleViews { |
|
|
|
for (int i = 0; i < pointArray.count; i ++) { |
|
|
|
FBYLineGraphColorView *lineGraphColorView = [[FBYLineGraphColorView alloc] initWithCenter:[pointArray[i] CGPointValue] radius:4]; |
|
lineGraphColorView.tag = i + BASE_TAG_CIRCLEVIEW; |
|
lineGraphColorView.borderColor = self.MainColor; |
|
lineGraphColorView.borderWidth = 1.0; |
|
[self addSubview:lineGraphColorView]; |
|
} |
|
} |
|
|
|
#pragma mark 覆盖一层点击图层 |
|
- (void)setupCoverViews { |
|
|
|
for (int i = 0; i < pointArray.count; i ++) { |
|
|
|
UIView *coverView = [[UIView alloc] init]; |
|
coverView.tag = BASE_TAG_COVERVIEW + i; |
|
|
|
// if (i == 0) { |
|
// |
|
// coverView.frame = CGRectMake(self.startPoint.x, self.startPoint.y, self.xScaleMarkLEN / 2, self.yAxis_L); |
|
// [self addSubview:coverView]; |
|
// } |
|
// else if (i == pointArray.count - 1 && pointArray.count == self.xMarkScaleArr.count) { |
|
// CGPoint point = [pointArray[i] CGPointValue]; |
|
// coverView.frame = CGRectMake(point.x - self.xScaleMarkLEN / 2, self.startPoint.y, self.xScaleMarkLEN / 2, self.yAxis_L); |
|
// [self addSubview:coverView]; |
|
// } |
|
// else { |
|
// CGPoint point = [pointArray[i] CGPointValue]; |
|
// coverView.frame = CGRectMake(point.x - self.xScaleMarkLEN / 2, self.startPoint.y, self.xScaleMarkLEN, self.yAxis_L); |
|
// [self addSubview:coverView]; |
|
// } |
|
|
|
|
|
CGPoint point = [pointArray[i] CGPointValue]; |
|
if(self.chartType == 0){ |
|
coverView.frame = CGRectMake(point.x - 20 / 2, self.startPoint.y, 20, self.yAxis_L); |
|
}else{ |
|
coverView.frame = CGRectMake(point.x - 20 / 2, self.startPoint.y, self.xScaleMarkLEN, self.yAxis_L); |
|
} |
|
|
|
[self addSubview:coverView]; |
|
|
|
|
|
|
|
|
|
|
|
UITapGestureRecognizer *gesutre = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gesutreAction:)]; |
|
[coverView addGestureRecognizer:gesutre]; |
|
[_pointTapViewArray addObject:coverView]; |
|
} |
|
} |
|
|
|
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ |
|
|
|
//判断point是否在rect内 |
|
// bool CGRectContainsPoint(CGRect rect, CGPoint point) |
|
|
|
UITouch* touch = [touches anyObject]; |
|
CGPoint currentPoint = [touch locationInView:self]; // 当前视图内的坐标 |
|
if(!CGRectIsEmpty(_tempRect)){ |
|
if(CGRectContainsPoint(_tempRect, currentPoint)){ |
|
return; |
|
} |
|
} |
|
for (UIView *item in _pointTapViewArray) { |
|
if (CGRectContainsPoint(item.frame, currentPoint)){ |
|
_tempRect = item.frame; |
|
[self gesutreAction:item.gestureRecognizers.firstObject]; |
|
} |
|
} |
|
} |
|
|
|
#pragma mark- 点击层视图的点击事件 |
|
- (void)gesutreAction:(UITapGestureRecognizer *)sender { |
|
|
|
NSInteger index = sender.view.tag - BASE_TAG_COVERVIEW; |
|
|
|
if (lastSelectedIndex != -1) { |
|
|
|
FBYLineGraphColorView *lineGraphColorView = (FBYLineGraphColorView *)[self viewWithTag:lastSelectedIndex + BASE_TAG_CIRCLEVIEW]; |
|
lineGraphColorView.borderWidth = 1; |
|
|
|
UIButton *lastPopBtn = (UIButton *)[self viewWithTag:lastSelectedIndex + BASE_TAG_POPBTN]; |
|
[lastPopBtn removeFromSuperview]; |
|
} |
|
|
|
FBYLineGraphColorView *lineGraphColorView = (FBYLineGraphColorView *)[self viewWithTag:index + BASE_TAG_CIRCLEVIEW]; |
|
lineGraphColorView.borderWidth = 2; |
|
|
|
CGPoint point = [pointArray[index] CGPointValue]; |
|
|
|
UIButton *popBtn = [UIButton buttonWithType:(UIButtonTypeCustom)]; |
|
popBtn.tag = index + BASE_TAG_POPBTN; |
|
CGFloat popBtnWidth = 80; |
|
CGFloat popBtnHeight = 35; |
|
|
|
|
|
// [popBtn setBackgroundImage:[UIImage imageNamed:@"bgcolors"] forState:UIControlStateNormal]; |
|
[popBtn setBackgroundColor:[self.MainColor colorWithAlphaComponent:0.5]]; |
|
|
|
popBtn.layer.cornerRadius = 5; |
|
popBtn.layer.masksToBounds = YES; |
|
|
|
popBtn.titleLabel.textAlignment = NSTextAlignmentCenter; |
|
if(self.chartType == 0){ |
|
popBtnWidth = 80; |
|
popBtnHeight = 35; |
|
// [popBtn setTitleEdgeInsets:UIEdgeInsetsMake(- 3, 0, 0, 0)]; |
|
popBtn.titleLabel.numberOfLines = 2; |
|
popBtn.titleLabel.font = [UIFont systemFontOfSize:10]; |
|
//上传时间 |
|
NSTimeInterval updateTime = [self.xMarkValues[index] integerValue]; |
|
NSDateFormatter*dateFormatter = [[NSDateFormatter alloc]init]; |
|
[dateFormatter setDateFormat:@"HH:mm"]; |
|
NSString *upDateTime = [dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:updateTime]]; |
|
[popBtn setTitle:[NSString stringWithFormat:@"上传时间:%@\n值:%@",upDateTime,self.valueArray[index]] forState:(UIControlStateNormal)]; |
|
}else{ |
|
popBtnWidth = 50; |
|
popBtnHeight = 25; |
|
popBtn.titleLabel.font = [UIFont systemFontOfSize:12]; |
|
[popBtn setTitle:[NSString stringWithFormat:@"%@",self.valueArray[index]] forState:(UIControlStateNormal)]; |
|
} |
|
CGFloat temp_X = point.x - popBtnWidth/2.0; |
|
if (point.x+popBtnWidth/2.0 > self.frame.size.width){ |
|
temp_X = point.x - popBtnWidth; |
|
} |
|
if (temp_X < 0) { |
|
temp_X = 0; |
|
} |
|
popBtn.frame = CGRectMake(temp_X, point.y - popBtnHeight-5, popBtnWidth, popBtnHeight); |
|
|
|
|
|
|
|
[self addSubview:popBtn]; |
|
|
|
lastSelectedIndex = index; |
|
} |
|
|
|
-(void)drawXGridline{ |
|
[super drawXGridline]; |
|
//如果有上下限 |
|
if (_upperValue > self.minValue) { |
|
UIBezierPath *xAxisPath = [[UIBezierPath alloc] init]; |
|
//Y轴比例 |
|
CGFloat percent = (_upperValue - self.minValue)/ (self.maxValue - self.minValue); |
|
CGFloat point_Y = self.yAxis_L * (1 - percent) + self.startPoint.y; |
|
[xAxisPath moveToPoint:CGPointMake(self.startPoint.x, point_Y)]; |
|
[xAxisPath addLineToPoint:CGPointMake(self.startPoint.x + self.xAxis_L, point_Y)]; |
|
|
|
CAShapeLayer *xAxisLayer = [CAShapeLayer layer]; |
|
[xAxisLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithInt:1.5], nil]]; |
|
xAxisLayer.lineWidth = 0.5; |
|
xAxisLayer.strokeColor = [UIColor redColor].CGColor; |
|
xAxisLayer.path = xAxisPath.CGPath; |
|
[self.layer addSublayer:xAxisLayer]; |
|
|
|
UILabel *markLab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 25, 16)]; |
|
markLab.center = CGPointMake(self.startPoint.x + self.xAxis_L - 25, point_Y - 16/2.0); |
|
markLab.textAlignment = NSTextAlignmentRight; |
|
markLab.textColor = [UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1.0f]; |
|
markLab.font = [UIFont systemFontOfSize:11.0]; |
|
markLab.text = @"上限"; |
|
[self addSubview:markLab]; |
|
} |
|
|
|
if (_lowerValue > self.minValue){ |
|
UIBezierPath *xAxisPath = [[UIBezierPath alloc] init]; |
|
//Y轴比例 |
|
CGFloat percent = (_lowerValue - self.minValue)/ (self.maxValue - self.minValue); |
|
CGFloat point_Y = self.yAxis_L * (1 - percent) + self.startPoint.y; |
|
[xAxisPath moveToPoint:CGPointMake(self.startPoint.x, point_Y)]; |
|
[xAxisPath addLineToPoint:CGPointMake(self.startPoint.x + self.xAxis_L, point_Y)]; |
|
|
|
CAShapeLayer *xAxisLayer = [CAShapeLayer layer]; |
|
[xAxisLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithInt:1.5], nil]]; |
|
xAxisLayer.lineWidth = 0.5; |
|
xAxisLayer.strokeColor = [UIColor redColor].CGColor; |
|
xAxisLayer.path = xAxisPath.CGPath; |
|
[self.layer addSublayer:xAxisLayer]; |
|
UILabel *markLab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 25, 16)]; |
|
markLab.center = CGPointMake(self.startPoint.x + self.xAxis_L - 25, point_Y - 16/2.0); |
|
markLab.textAlignment = NSTextAlignmentRight; |
|
markLab.textColor = [UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1.0f]; |
|
markLab.font = [UIFont systemFontOfSize:11.0]; |
|
markLab.text = @"下限"; |
|
[self addSubview:markLab]; |
|
} |
|
} |
|
|
|
#pragma mark- 清空视图 |
|
- (void)clearView { |
|
[self removeSubviews]; |
|
[self removeSublayers]; |
|
} |
|
|
|
#pragma mark 移除 点击图层 、圆环 、数值标签 |
|
- (void)removeSubviews { |
|
for (UIView *view in self.subviews) { |
|
[view removeFromSuperview]; |
|
} |
|
} |
|
|
|
#pragma mark 移除折线 |
|
- (void)removeSublayers { |
|
for (CALayer *layer in self.layer.sublayers) { |
|
[layer removeFromSuperlayer]; |
|
} |
|
} |
|
|
|
/* |
|
// Only override drawRect: if you perform custom drawing. |
|
// An empty implementation adversely affects performance during animation. |
|
- (void)drawRect:(CGRect)rect { |
|
// Drawing code |
|
} |
|
*/ |
|
|
|
@end
|
|
|