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.
377 lines
13 KiB
377 lines
13 KiB
1 year ago
|
//
|
||
|
// 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
|