// // InventoryAnalysisViewChartViewController.m // IBOSS // // Created by ssl on 2018/1/4. // Copyright © 2018年 elongtian. All rights reserved. // #import "InventoryAnalysisViewChartViewController.h" #import "SalesPaymentRankModel.h" #import "SalesPaymentRankFrame.h" #import "NSString+Tools.h" #define kTextFont [UIFont systemFontOfSize:LabelAndTextFontOfSize] @interface InventoryAnalysisViewChartViewController (){ /** scrollview */ UIScrollView * _scroll; /** 标题 */ UILabel *_lblTitle; } @end @implementation InventoryAnalysisViewChartViewController #pragma mark - 公共函数 /** 视图加载完成函数 */ - (void)viewDidLoad { [super viewDidLoad]; [self initUI]; } #pragma mark - 私有函数 /** 初始化UI */ - (void)initUI{ UIView *separatorView = [UIView new]; separatorView.tag = 11; separatorView.frame = CGRectMake(0, 0, Screen_Width, 10); separatorView.backgroundColor = LineBackgroundColor; [self.view addSubview:separatorView]; //柱状图左间距 _scroll = [UIScrollView new]; _scroll.frame = CGRectMake(0, CGRectGetMaxY(separatorView.frame), SCREENWIDTH, self.view.frame.size.height-CGRectGetMaxY(separatorView.frame)); [self.view addSubview:_scroll]; _lblTitle = [[UILabel alloc]init]; _lblTitle.text = @"库存按种类进行统计分析的条形图"; _lblTitle.textAlignment = NSTextAlignmentCenter; [_lblTitle sizeToFit]; _lblTitle.center = CGPointMake(SCREENWIDTH/2,CGRectGetMaxY(separatorView.frame)+5); _lblTitle.tag = 10; _lblTitle.textColor = LabelGrayTextColor; _lblTitle.font = [UIFont systemFontOfSize:14]; [_scroll addSubview:_lblTitle]; _bottomSeparatorView = [UIView new]; _bottomSeparatorView.tag = 10; _bottomSeparatorView.hidden = YES; _bottomSeparatorView.frame = CGRectMake(0,CGRectGetMaxY(_lblTitle.frame)+5, Screen_Width,2); _bottomSeparatorView.backgroundColor=LineBackgroundColor; [_scroll addSubview:_bottomSeparatorView]; self.view.backgroundColor = [UIColor whiteColor]; } /** 刷新数据 */ - (void)refreshData:(NSString *) str{ _lblTitle.text = [NSString stringWithFormat:@"库存按%@进行统计分析的条形图",str]; NSRange range=NSMakeRange(0, 10); if(_rankList.count > 10){ NSRange range = NSMakeRange(0, 10); _rankList = [_rankList subarrayWithRange:range]; } Boolean flag = [self isHaveNegativeValue]; if(flag){ [self loadNegativeHistogram]; } else{ [self loadPositiveHistogram]; } } /** 判断是否有负数 @return <#return value description#> */ - (Boolean) isHaveNegativeValue{ Boolean flag = NO; for(int i = 0;i < _rankList.count;i++){ SalesPaymentRankFrame *frame = [_rankList objectAtIndex:i]; double backAmount = [frame.paymentRankModel.inventoryQuantity doubleValue]; if(backAmount < 0){ flag = true; break; } } return flag; } /** 绘制向右的柱状图 @param subview @param frame */ - (void)layerToRight:(UIView *) subview withFrame:(CGRect) frame withColor:(UIColor *) color { CGFloat x = frame.origin.x; CGFloat y = frame.origin.y; CGFloat height = frame.size.height; CGFloat width = frame.size.width; CAGradientLayer *itemLayer = [CAGradientLayer layer]; itemLayer.frame = frame; itemLayer.colors = [self getColorArr]; itemLayer.locations = @[@0,@0.5]; itemLayer.startPoint = CGPointMake(0, 0); itemLayer.endPoint = CGPointMake(0, 1.0); [subview.layer addSublayer:itemLayer]; CABasicAnimation *aniBounds = [CABasicAnimation animationWithKeyPath:@"bounds"]; aniBounds.fromValue = [NSValue valueWithCGRect:CGRectMake(x, y, 0, height)]; aniBounds.toValue = [NSValue valueWithCGRect:CGRectMake(x, y, CGRectGetWidth(frame), CGRectGetHeight(frame))]; CABasicAnimation *aniPosition = [CABasicAnimation animationWithKeyPath:@"position"]; aniPosition.fromValue = [NSValue valueWithCGPoint:CGPointMake(x, frame.size.height/2 + y)]; aniPosition.toValue = [NSValue valueWithCGPoint:CGPointMake(x + (CGRectGetMaxX(frame)-x)/2,y + (CGRectGetMaxY(frame)-y)/2)]; CAAnimationGroup *anis = [CAAnimationGroup animation]; anis.animations = @[aniBounds,aniPosition]; anis.duration = 1; anis.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; anis.removedOnCompletion = NO; anis.fillMode=kCAFillModeForwards; [itemLayer addAnimation:anis forKey:nil]; } /** 绘制向左的柱状图 @param subview @param frame */ - (void)layerToLeft:(UIView *) subview withFrame:(CGRect) frame withColor:(UIColor *) color { CGFloat x = frame.origin.x; CGFloat y = frame.origin.y; CGFloat height = frame.size.height; CGFloat width = frame.size.width; CAGradientLayer *itemLayer = [CAGradientLayer layer]; itemLayer.frame = frame; itemLayer.colors = [self getColorArr]; itemLayer.locations = @[@0,@0.5]; itemLayer.startPoint = CGPointMake(0, 0); itemLayer.endPoint = CGPointMake(0, 1.0); [subview.layer addSublayer:itemLayer]; CABasicAnimation *aniBounds = [CABasicAnimation animationWithKeyPath:@"bounds"]; aniBounds.fromValue = [NSValue valueWithCGRect:CGRectMake(x, y, 0, height)]; aniBounds.toValue = [NSValue valueWithCGRect:CGRectMake(x, y, CGRectGetWidth(frame), CGRectGetHeight(frame))]; CABasicAnimation *aniPosition = [CABasicAnimation animationWithKeyPath:@"position"]; aniPosition.toValue = [NSValue valueWithCGPoint:CGPointMake(x+ (CGRectGetMaxX(frame)-x)/2, frame.size.height/2 + y)]; aniPosition.fromValue = [NSValue valueWithCGPoint:CGPointMake(x+width,y + (CGRectGetMaxY(frame)-y)/2)]; CAAnimationGroup *anis = [CAAnimationGroup animation]; anis.animations = @[aniBounds,aniPosition]; anis.duration = 1; anis.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; anis.removedOnCompletion = NO; anis.fillMode=kCAFillModeForwards; [itemLayer addAnimation:anis forKey:nil]; } /** 刷新正向柱状图 */ - (void) loadPositiveHistogram{ for (UIView *subview in _scroll.subviews) { if(subview.tag != 10) { [subview removeFromSuperview]; } } self.view.backgroundColor = [UIColor whiteColor]; CGFloat xSpacing =30; //柱状图高度 CGFloat height = 40; //第一个柱状图上间距 CGFloat fySpacing = 15; //柱状图间距 CGFloat ySpacing = 10; //柱状图内文字左间距 CGFloat xTextSpacing = 5; //柱状图最大长度 CGFloat maxWidth = SCREENWIDTH - xSpacing - 10; _histogramView = [[UIView alloc]initWithFrame:CGRectMake(0,CGRectGetMaxY(_bottomSeparatorView.frame),Screen_Width,[self getHistogramHeight:_rankList])]; [_scroll addSubview:_histogramView]; _histogramView.backgroundColor = [UIColor whiteColor]; SalesPaymentRankFrame *maxBackFrame= [_rankList objectAtIndex:0]; double maxBackAmount=[maxBackFrame.paymentRankModel.inventoryQuantity doubleValue] ; if(_rankList.count >=3){ [self createAxis:maxWidth maxAmount:maxBackAmount]; } //画水平柱状图 for(int i=0;i<_rankList.count;i++){ SalesPaymentRankFrame *frame= [_rankList objectAtIndex:i]; double backAmount= [frame.paymentRankModel.inventoryQuantity doubleValue]; NSString *objectName= frame.paymentRankModel.objectName; CGFloat width; //计算长度 if(backAmountfabs(lastAmount)){ maxBackAmount = firstAmount; }else{ maxBackAmount = fabs(lastAmount); } [self createNegativeAxis:maxWidth maxAmount:maxBackAmount]; //画柱状图 for(int i=0;i<_rankList.count;i++){ SalesPaymentRankFrame *frame = [_rankList objectAtIndex:i]; double backAmount = [frame.paymentRankModel.inventoryQuantity doubleValue]; NSString *objectName = frame.paymentRankModel.objectName; CGFloat width; //计算长度 if(backAmount=0){ [self layerToRight:_histogramView withFrame:CGRectMake(Screen_Width/2, fySpacing*(i+1)+height*i,width, height)withColor:[UIColor colorWithRed:96.0/255.0 green:159.0/255.0 blue:233.0/255.0 alpha:1]]; objectNameFrame.origin.x = xTextSpacing+Screen_Width/2; objectNameFrame.origin.y = 5 + fySpacing*(i+1)+height*i; backAmountFrame.origin.x = xTextSpacing+Screen_Width/2; backAmountFrame.origin.y = CGRectGetMaxY(objectNameFrame); orderSortFrame.origin.x = Screen_Width/2-xSpacing; orderSortFrame.origin.y = (height - orderSortFrame.size.height)/2 + fySpacing*(i+1)+height*i; } //负值 else if(backAmount < 0){ [self layerToLeft:_histogramView withFrame:CGRectMake(Screen_Width/2-width, fySpacing*(i+1)+height*i,width, height)withColor:[UIColor colorWithRed:96.0/255.0 green:159.0/255.0 blue:233.0/255.0 alpha:1]]; objectNameFrame.origin.x = Screen_Width/2-xTextSpacing-CGRectGetWidth(objectNameFrame); objectNameFrame.origin.y = 5 + fySpacing*(i+1)+height*i; backAmountFrame.origin.x = Screen_Width/2-xTextSpacing-CGRectGetWidth(backAmountFrame); backAmountFrame.origin.y = CGRectGetMaxY(objectNameFrame); orderSortFrame.origin.x =Screen_Width/2+xTextSpacing; orderSortFrame.origin.y = (height - orderSortFrame.size.height)/2 + fySpacing*(i+1)+height*i; } [self.view addSubview:_histogramView]; UIView *yAxis=[[UIView alloc]init]; yAxis.frame=CGRectMake(Screen_Width/2, 0, 2.5, [self getHistogramHeight:_rankList]); yAxis.backgroundColor=LineBackgroundColor; [_histogramView addSubview:yAxis]; lblDepartmentName.frame = objectNameFrame; lblDepartmentName.font = kTextFont; lblDepartmentName.text = objectNameStr; [_histogramView addSubview:lblDepartmentName]; lblOrderSort.frame = orderSortFrame; lblOrderSort.font = kTextFont; lblOrderSort.text = orderSortStr; [_histogramView addSubview:lblOrderSort]; lblBackAmount.textAlignment = NSTextAlignmentRight; lblBackAmount.frame = backAmountFrame; lblBackAmount.font = kTextFont; lblBackAmount.text = backAmountStr; [_histogramView addSubview:lblBackAmount]; } _scroll.contentSize = CGSizeMake(self.view.frame.size.width, CGRectGetMaxY(_histogramView.frame)+10+rectStatusHeight+rectNavHeight + 150); [_scroll addSubview:_histogramView]; } /** 计算柱状图的高度 @param dataList <#dataList description#> @return <#return value description#> */ -(CGFloat)getHistogramHeight:(NSArray*)dataList{ // 上下间隔已经在frame上做了 NSInteger row = dataList.count; return (row * 40 + (row * 15)); } /** 创建负数的轴线 @param width 最大长度 @param maxAmount 最大金额 */ - (void) createNegativeAxis:(CGFloat) width maxAmount:(CGFloat)maxAmount{ // 线的路径 UIBezierPath *leveLinePath = [UIBezierPath bezierPath]; // 起点 [leveLinePath moveToPoint:CGPointMake((_histogramView.frame.size.width - (2 * width))/2, 0)]; // 其他点 [leveLinePath addLineToPoint:CGPointMake(2 * width + 10, 0)]; CAShapeLayer *leveLineLayer = [CAShapeLayer layer]; leveLineLayer.lineWidth = 1; leveLineLayer.strokeColor = LineBackgroundColor.CGColor; leveLineLayer.path = leveLinePath.CGPath; leveLineLayer.fillColor = nil; // 默认为blackColor [_histogramView.layer addSublayer:leveLineLayer]; NSString *str = [NSString stringWithFormat:@"%d",(int)maxAmount]; int m = ceil([str integerValue]/pow(10, str.length-1)); m = m * pow(10, str.length-1); m = 5000100.00; //右侧垂直等份轴线 for (int i = 0; i <= 3; i++) { if(i != 0){ CGFloat c = (width/3)*i+width+10; // if(i != 0){ // UILabel *lb = [[UILabel alloc] initWithFrame:CGRectMake(c-20, _histogramView.frame.origin.y-17, 200, 17)]; // lb.textAlignment = NSTextAlignmentCenter; // lb.center = CGPointMake(c-10, _histogramView.frame.origin.y-10); // lb.text = [NSString stringWithFormat:@"%d",(m/5)*i]; // lb.textColor = [UIColor colorWithRed:153/255.0 green:153/255.0 blue:153/255.0 alpha:1]; // lb.font = [UIFont systemFontOfSize:9]; // [_scroll addSubview:lb]; // } UIBezierPath *linePath = [UIBezierPath bezierPath]; [linePath moveToPoint:CGPointMake(c, 0)]; [linePath addLineToPoint:CGPointMake(c, _histogramView.frame.size.height)]; CAShapeLayer *lineLayer = [CAShapeLayer layer]; lineLayer.lineWidth = 1; lineLayer.strokeColor = LineBackgroundColor.CGColor; lineLayer.path = linePath.CGPath; lineLayer.fillColor = nil; // 默认为blackColor [_histogramView.layer addSublayer:lineLayer]; } } //左侧垂直等份轴线 for (int i = 0; i <= 3; i++) { //计算等分间距 CGFloat c = width + 10 -(width/3)*i; if(i != 0){ UIBezierPath *linePath = [UIBezierPath bezierPath]; [linePath moveToPoint:CGPointMake(c, 0)]; [linePath addLineToPoint:CGPointMake(c, _histogramView.frame.size.height)]; CAShapeLayer *lineLayer = [CAShapeLayer layer]; lineLayer.lineWidth = 1; lineLayer.strokeColor = LineBackgroundColor.CGColor; lineLayer.path = linePath.CGPath; lineLayer.fillColor = nil; // 默认为blackColor [_histogramView.layer addSublayer:lineLayer]; } } } /** 创建正数的轴线 @param width <#width description#> @param maxAmount <#maxAmount description#> */ - (void) createAxis:(CGFloat) width maxAmount:(CGFloat)maxAmount{ // 线的路径 UIBezierPath *linePath = [UIBezierPath bezierPath]; // 起点 [linePath moveToPoint:CGPointMake(width+30, 0)]; // 其他点 [linePath addLineToPoint:CGPointMake(30, 0)]; [linePath addLineToPoint:CGPointMake(30,_histogramView.frame.size.height)]; CAShapeLayer *lineLayer = [CAShapeLayer layer]; lineLayer.lineWidth = 1; lineLayer.strokeColor = LineBackgroundColor.CGColor; lineLayer.path = linePath.CGPath; lineLayer.fillColor = nil; // 默认为blackColor [_histogramView.layer addSublayer:lineLayer]; NSString *str = [NSString stringWithFormat:@"%d",(int)maxAmount]; int m = ceil([str integerValue]/pow(10, str.length-1)); m = m * pow(10, str.length-1); //垂直五条轴线 for (int i = 0; i <= 5; i++) { CGFloat c = (width/5)*i+30; // if(i != 0){ // UILabel *lb = [[UILabel alloc] initWithFrame:CGRectMake(c-20, _histogramView.frame.origin.y-17, 200, 17)]; // lb.textAlignment = NSTextAlignmentCenter; // lb.center = CGPointMake(c-10, _histogramView.frame.origin.y-10); // lb.text = [NSString stringWithFormat:@"%d",(m/5)*i]; // lb.textColor = [UIColor colorWithRed:153/255.0 green:153/255.0 blue:153/255.0 alpha:1]; // lb.font = [UIFont systemFontOfSize:9]; // [_scroll addSubview:lb]; // } UIBezierPath *linePath = [UIBezierPath bezierPath]; [linePath moveToPoint:CGPointMake(c, 0)]; [linePath addLineToPoint:CGPointMake(c, _histogramView.frame.size.height)]; CAShapeLayer *lineLayer = [CAShapeLayer layer]; lineLayer.lineWidth = 1; lineLayer.strokeColor = LineBackgroundColor.CGColor; lineLayer.path = linePath.CGPath; lineLayer.fillColor = nil; // 默认为blackColor [_histogramView.layer addSublayer:lineLayer]; } } /** 渐变色 @return <#return value description#> */ -(NSMutableArray *) getColorArr{ NSMutableArray *arr = [NSMutableArray array]; [arr addObject:(__bridge id)[UIColor colorWithRed:236/255.0 green:134/255.0 blue:40/255.0 alpha:1].CGColor]; [arr addObject:(__bridge id)[UIColor colorWithRed:236/255.0 green:134/255.0 blue:40/255.0 alpha:0.4].CGColor]; [arr addObject:(__bridge id)[UIColor colorWithRed:236/255.0 green:134/255.0 blue:40/255.0 alpha:1].CGColor]; return arr; } @end