SalesAchievementChartViewController.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. //
  2. // ChartViewController.m
  3. // IBOSS
  4. //
  5. // Created by guan hong hou on 2017/8/21.
  6. // Copyright © 2017年 elongtian. All rights reserved.
  7. //
  8. // 功能描述:销售业绩图表控制器
  9. #import "SalesAchievementChartViewController.h"
  10. #import "NSString+Tools.h"
  11. #import "SalesAchievementRankModel.h"
  12. #import "SalesAchievementListFrame.h"
  13. #define kTextFont [UIFont systemFontOfSize:LabelAndTextFontOfSize]
  14. @interface SalesAchievementChartViewController (){
  15. UIScrollView * _scroll;
  16. }
  17. @end
  18. @implementation SalesAchievementChartViewController
  19. #pragma mark - 公共函数
  20. /**
  21. 视图加载完成函数
  22. */
  23. - (void)viewDidLoad {
  24. [super viewDidLoad];
  25. [self initUI];
  26. }
  27. /**
  28. 安全区视图发生变化
  29. */
  30. -(void)viewSafeAreaInsetsDidChange{
  31. _scroll.frame = CGRectMake(0, 0, SCREENWIDTH, self.view.superview.frame.size.height);
  32. self.view.frame = CGRectMake(0, 0, SCREENWIDTH, self.view.superview.frame.size.height);
  33. [super viewSafeAreaInsetsDidChange];
  34. }
  35. #pragma mark - 私有函数
  36. /**
  37. 初始化UI
  38. */
  39. -(void)initUI{
  40. UIView *separatorView = [UIView new];
  41. separatorView.frame = CGRectMake(0, 0, Screen_Width, 10);
  42. separatorView.backgroundColor = LineBackgroundColor;
  43. [self.view addSubview:separatorView];
  44. UILabel *lblTitle = [[UILabel alloc]init];
  45. lblTitle.frame = CGRectMake((Screen_Width-160)/2, CGRectGetMaxY(separatorView.frame)+5, 160, 25);
  46. lblTitle.text = @"销售业绩排行 (单位:元)";
  47. lblTitle.textColor = LabelGrayTextColor;
  48. lblTitle.font = [UIFont systemFontOfSize:14];
  49. [self.view addSubview:lblTitle];
  50. _bottomSeparatorView = [UIView new];
  51. _bottomSeparatorView.frame = CGRectMake(0,CGRectGetMaxY(lblTitle.frame)+5, Screen_Width,2);
  52. _bottomSeparatorView.backgroundColor = LineBackgroundColor;
  53. [self.view addSubview:_bottomSeparatorView];
  54. //柱状图左间距
  55. _scroll = [UIScrollView new];
  56. _scroll.frame = self.view.bounds;
  57. [self.view addSubview:_scroll];
  58. self.view.backgroundColor = [UIColor whiteColor];
  59. }
  60. /**
  61. 刷新数据
  62. */
  63. -(void)refreshData{
  64. if(_rankList.count > 10){
  65. NSRange range = NSMakeRange(0, 10);
  66. _rankList = [_rankList subarrayWithRange:range];
  67. }
  68. Boolean flag = [self isHaveNegativeValue];
  69. if(flag){
  70. [self loadNegativeHistogram];
  71. }
  72. else{
  73. [self loadPositiveHistogram];
  74. }
  75. }
  76. /**
  77. 刷新正数柱状图
  78. */
  79. - (void) loadPositiveHistogram{
  80. if(_histogramView != nil){
  81. [_histogramView removeFromSuperview];
  82. }
  83. self.view.backgroundColor = [UIColor whiteColor];
  84. CGFloat xSpacing = 30;
  85. //柱状图高度
  86. CGFloat height = 40;
  87. //第一个柱状图上间距
  88. CGFloat fySpacing = 15;
  89. //柱状图间距
  90. // CGFloat ySpacing = 10;
  91. //柱状图内文字左间距
  92. CGFloat xTextSpacing = 5;
  93. //柱状图最大长度
  94. CGFloat maxWidth = SCREENWIDTH - xSpacing - 10;
  95. _histogramView = [[UIView alloc]initWithFrame:CGRectMake(0,CGRectGetMaxY(_bottomSeparatorView.frame),Screen_Width,[self getHistogramHeight:_rankList])];
  96. [_scroll addSubview:_histogramView];
  97. _histogramView.backgroundColor = [UIColor whiteColor];
  98. SalesAchievementListFrame *maxAchievementFrame = [_rankList objectAtIndex:0];
  99. double maxGoodsAmount = maxAchievementFrame.achievementRankModel.goodsAmount;
  100. for(int i = 0;i < _rankList.count;i++){
  101. SalesAchievementListFrame *maxAchievementFrame = [_rankList objectAtIndex:i];
  102. double goodsAmount = maxAchievementFrame.achievementRankModel.goodsAmount;
  103. // NSString *objectName = maxAchievementFrame.achievementRankModel.objectName;
  104. CGFloat width;
  105. if(goodsAmount < maxGoodsAmount){
  106. width = maxWidth * (fabs(goodsAmount)/maxGoodsAmount);
  107. if(width < 1){
  108. width = 1;
  109. }
  110. }
  111. else{
  112. width = maxWidth;
  113. }
  114. [self layerToRight:_histogramView withFrame:CGRectMake(xSpacing, 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]];
  115. [self.view addSubview:_histogramView];
  116. UILabel *lblOrderSort = [[UILabel alloc] init];
  117. NSString *orderSortStr = [NSString stringWithFormat:@"%ld", (long)maxAchievementFrame.achievementRankModel.orderSort];
  118. CGRect orderSortFrame = [orderSortStr textRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) attributes:@{NSFontAttributeName:kTextFont}];
  119. orderSortFrame.origin.x = 10;
  120. orderSortFrame.origin.y = (height - orderSortFrame.size.height)/2 + fySpacing * (i+1) + height * i;
  121. lblOrderSort.frame = orderSortFrame;
  122. lblOrderSort.font = kTextFont;
  123. lblOrderSort.text = orderSortStr;
  124. [_histogramView addSubview:lblOrderSort];
  125. UILabel *lblDepartmentName = [[UILabel alloc] init];
  126. NSString *departmentNameStr = maxAchievementFrame.achievementRankModel.objectName;
  127. CGRect departmentNameFrame = [departmentNameStr textRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) attributes:@{NSFontAttributeName:kTextFont}];
  128. departmentNameFrame.origin.x = xTextSpacing + xSpacing;
  129. departmentNameFrame.origin.y = 5 + fySpacing*(i+1)+height*i;
  130. lblDepartmentName.textAlignment = NSTextAlignmentRight;
  131. lblDepartmentName.frame = departmentNameFrame;
  132. lblDepartmentName.font = kTextFont;
  133. lblDepartmentName.text = departmentNameStr;
  134. [_histogramView addSubview:lblDepartmentName];
  135. UILabel *lblGoodsAmount = [[UILabel alloc] init];
  136. NSString *goodsAmountStr = [NSString stringWithFormat:@"¥%.2f", maxAchievementFrame.achievementRankModel.goodsAmount];
  137. CGRect goodsAmountFrame = [goodsAmountStr textRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) attributes:@{NSFontAttributeName:kTextFont}];
  138. goodsAmountFrame.origin.x= xTextSpacing + xSpacing;
  139. goodsAmountFrame.origin.y=CGRectGetMaxY( lblDepartmentName.frame);
  140. lblGoodsAmount.textAlignment = NSTextAlignmentRight;
  141. lblGoodsAmount.frame = goodsAmountFrame;
  142. lblGoodsAmount.font = kTextFont;
  143. lblGoodsAmount.text = goodsAmountStr;
  144. [_histogramView addSubview:lblGoodsAmount];
  145. }
  146. _scroll.contentSize = CGSizeMake(self.view.frame.size.width, CGRectGetMaxY(_histogramView.frame)+10 + rectStatusHeight +rectNavHeight + 150);
  147. [_scroll addSubview:_histogramView];
  148. }
  149. /**
  150. 刷新负数柱状图
  151. */
  152. - (void) loadNegativeHistogram{
  153. if(_histogramView != nil){
  154. [_histogramView removeFromSuperview];
  155. }
  156. //柱状图左间距
  157. CGFloat xSpacing = 15;
  158. //柱状图高度
  159. CGFloat height = 40;
  160. //第一个柱状图上间距
  161. CGFloat fySpacing = 15;
  162. //柱状图间距
  163. // CGFloat ySpacing = 10;
  164. //柱状图内文字左间距
  165. CGFloat xTextSpacing = 5;
  166. //柱状图最大长度
  167. CGFloat maxWidth = SCREENWIDTH/2 - 10;
  168. _histogramView = [[UIView alloc]initWithFrame:CGRectMake(0,CGRectGetMaxY(_bottomSeparatorView.frame),Screen_Width,[self getHistogramHeight:_rankList])];
  169. [_scroll addSubview:_histogramView];
  170. _histogramView.backgroundColor = [UIColor whiteColor];
  171. SalesAchievementListFrame *maxAchievementFrame = [_rankList objectAtIndex:0];
  172. double maxGoodsAmount = maxAchievementFrame.achievementRankModel.goodsAmount;
  173. for(int i = 0;i < _rankList.count;i++){
  174. SalesAchievementListFrame *maxAchievementFrame = [_rankList objectAtIndex:i];
  175. double goodsAmount = maxAchievementFrame.achievementRankModel.goodsAmount;
  176. // NSString *objectName = maxAchievementFrame.achievementRankModel.objectName;
  177. CGFloat width;
  178. if(goodsAmount < maxGoodsAmount){
  179. width = maxWidth * (fabs(goodsAmount)/maxGoodsAmount);
  180. if(width < 1){
  181. width = 1;
  182. }
  183. }
  184. else{
  185. width = maxWidth;
  186. }
  187. UILabel *lblGoodsAmount = [[UILabel alloc] init];
  188. NSString *goodsAmountStr = [NSString stringWithFormat:@"¥%.2f", maxAchievementFrame.achievementRankModel.goodsAmount];
  189. CGRect goodsAmountFrame = [goodsAmountStr textRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) attributes:@{NSFontAttributeName:kTextFont}];
  190. UILabel *lblOrderSort = [[UILabel alloc] init];
  191. NSString *orderSortStr = [NSString stringWithFormat:@"%ld",(long) maxAchievementFrame.achievementRankModel.orderSort];
  192. CGRect orderSortFrame = [orderSortStr textRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) attributes:@{NSFontAttributeName:kTextFont}];
  193. UILabel *lblDepartmentName = [[UILabel alloc] init];
  194. NSString *objectNameStr = [maxAchievementFrame.achievementRankModel objectName];
  195. CGRect objectNameFrame = [objectNameStr textRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) attributes:@{NSFontAttributeName:kTextFont}];
  196. if(goodsAmount >=0){
  197. [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]];
  198. objectNameFrame.origin.x = xTextSpacing+Screen_Width/2;
  199. objectNameFrame.origin.y = 5 + fySpacing*(i+1)+height*i;
  200. goodsAmountFrame.origin.x=xTextSpacing+Screen_Width/2;
  201. goodsAmountFrame.origin.y=CGRectGetMaxY(objectNameFrame);
  202. orderSortFrame.origin.x = Screen_Width/2-xSpacing;
  203. orderSortFrame.origin.y = (height - orderSortFrame.size.height)/2 + fySpacing*(i+1)+height*i;
  204. }
  205. else if(goodsAmount < 0){
  206. [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]];
  207. objectNameFrame.origin.x=Screen_Width/2- xTextSpacing-CGRectGetWidth(objectNameFrame);
  208. objectNameFrame.origin.y = 5 + fySpacing*(i+1)+height*i;
  209. goodsAmountFrame.origin.x=Screen_Width/2-xTextSpacing-CGRectGetWidth(goodsAmountFrame);
  210. goodsAmountFrame.origin.y=CGRectGetMaxY(objectNameFrame);
  211. orderSortFrame.origin.x =Screen_Width/2+xTextSpacing;
  212. orderSortFrame.origin.y = (height - orderSortFrame.size.height)/2 + fySpacing*(i+1)+height*i;
  213. }
  214. [self.view addSubview:_histogramView];
  215. UIView *yAxis=[[UIView alloc]init];
  216. yAxis.frame=CGRectMake(Screen_Width/2, 0, 2.5, [self getHistogramHeight:_rankList]);
  217. yAxis.backgroundColor=LineBackgroundColor;
  218. [_histogramView addSubview:yAxis];
  219. lblDepartmentName.frame = objectNameFrame;
  220. lblDepartmentName.font = kTextFont;
  221. lblDepartmentName.text = objectNameStr;
  222. [_histogramView addSubview:lblDepartmentName];
  223. lblOrderSort.frame = orderSortFrame;
  224. lblOrderSort.font = kTextFont;
  225. lblOrderSort.text = orderSortStr;
  226. [_histogramView addSubview:lblOrderSort];
  227. lblGoodsAmount.textAlignment = NSTextAlignmentRight;
  228. lblGoodsAmount.frame = goodsAmountFrame;
  229. lblGoodsAmount.font = kTextFont;
  230. lblGoodsAmount.text = goodsAmountStr;
  231. [_histogramView addSubview:lblGoodsAmount];
  232. }
  233. _scroll.contentSize = CGSizeMake(self.view.frame.size.width, CGRectGetMaxY(_histogramView.frame)+10+rectStatusHeight+rectNavHeight + 150);
  234. [_scroll addSubview:_histogramView];
  235. }
  236. /**
  237. 判断是否有负数
  238. @return <#return value description#>
  239. */
  240. -(Boolean) isHaveNegativeValue{
  241. Boolean flag=NO;
  242. for(int i = 0;i < _rankList.count;i++){
  243. SalesAchievementListFrame *frame = [_rankList objectAtIndex:i];
  244. double goodsAmount = frame.achievementRankModel.goodsAmount;
  245. if(goodsAmount < 0){
  246. flag = true;
  247. break;
  248. }
  249. }
  250. return flag;
  251. }
  252. /**
  253. 计算柱状图高度
  254. @param dataList <#dataList description#>
  255. @return <#return value description#>
  256. */
  257. -(CGFloat)getHistogramHeight:(NSArray*)dataList{
  258. NSInteger row = dataList.count;
  259. return (row * 40 + (row * 20));
  260. }
  261. /**
  262. 绘制向右的柱状图
  263. @param subview
  264. @param frame
  265. */
  266. - (void)layerToRight:(UIView *) subview withFrame:(CGRect) frame withColor:(UIColor *) color
  267. {
  268. CGFloat x = frame.origin.x;
  269. CGFloat y = frame.origin.y;
  270. CGFloat height = frame.size.height;
  271. CGFloat width = frame.size.width;
  272. CALayer *itemLayer = [CALayer layer];
  273. itemLayer.frame = frame;
  274. itemLayer.backgroundColor = color.CGColor;
  275. [subview.layer addSublayer:itemLayer];
  276. CABasicAnimation *aniBounds = [CABasicAnimation animationWithKeyPath:@"bounds"];
  277. aniBounds.fromValue = [NSValue valueWithCGRect:CGRectMake(x, y, 0, height)];
  278. aniBounds.toValue = [NSValue valueWithCGRect:CGRectMake(x, y, CGRectGetWidth(frame), CGRectGetHeight(frame))];
  279. CABasicAnimation *aniPosition = [CABasicAnimation animationWithKeyPath:@"position"];
  280. aniPosition.fromValue = [NSValue valueWithCGPoint:CGPointMake(x, frame.size.height/2 + y)];
  281. aniPosition.toValue = [NSValue valueWithCGPoint:CGPointMake(x + (CGRectGetMaxX(frame)-x)/2,y + (CGRectGetMaxY(frame)-y)/2)];
  282. CAAnimationGroup *anis = [CAAnimationGroup animation];
  283. anis.animations = @[aniBounds,aniPosition];
  284. anis.duration = 1;
  285. anis.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  286. anis.removedOnCompletion = NO;
  287. anis.fillMode=kCAFillModeForwards;
  288. [itemLayer addAnimation:anis forKey:nil];
  289. }
  290. /**
  291. 绘制向左的柱状图
  292. @param subview
  293. @param frame
  294. */
  295. - (void)layerToLeft:(UIView *) subview withFrame:(CGRect) frame withColor:(UIColor *) color
  296. {
  297. CGFloat x = frame.origin.x;
  298. CGFloat y = frame.origin.y;
  299. CGFloat height = frame.size.height;
  300. CGFloat width = frame.size.width;
  301. CALayer *itemLayer = [CALayer layer];
  302. itemLayer.frame = frame;
  303. itemLayer.backgroundColor = color.CGColor;
  304. [subview.layer addSublayer:itemLayer];
  305. CABasicAnimation *aniBounds = [CABasicAnimation animationWithKeyPath:@"bounds"];
  306. aniBounds.fromValue = [NSValue valueWithCGRect:CGRectMake(x, y, 0, height)];
  307. aniBounds.toValue = [NSValue valueWithCGRect:CGRectMake(x, y, CGRectGetWidth(frame), CGRectGetHeight(frame))];
  308. CABasicAnimation *aniPosition = [CABasicAnimation animationWithKeyPath:@"position"];
  309. aniPosition.toValue = [NSValue valueWithCGPoint:CGPointMake(x+ (CGRectGetMaxX(frame)-x)/2, frame.size.height/2 + y)];
  310. aniPosition.fromValue = [NSValue valueWithCGPoint:CGPointMake(x+width,y + (CGRectGetMaxY(frame)-y)/2)];
  311. CAAnimationGroup *anis = [CAAnimationGroup animation];
  312. anis.animations = @[aniBounds,aniPosition];
  313. anis.duration = 1;
  314. anis.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  315. anis.removedOnCompletion = NO;
  316. anis.fillMode=kCAFillModeForwards;
  317. [itemLayer addAnimation:anis forKey:nil];
  318. }
  319. @end