LHYChartView.m 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379
  1. //
  2. // LHYChartView.m
  3. // LHYChartView
  4. //
  5. // Created by lreson on 16/7/21.
  6. // Copyright © 2016年 lreson. All rights reserved.
  7. //
  8. #import "LHYChartView.h"
  9. #import "YJYTouchCollectionView.h"
  10. #import "YJYTouchScroll.h"
  11. #import "YJYLinesCell.h"
  12. #import "LHYLinesPaoPaoView.h"
  13. #define btnW 12
  14. #define kPaoPaoWidth 75.f
  15. #define chartViewHeight self.bounds.size.height - 30
  16. #define KCircleRadius 3 //线条上圆圈半径
  17. #define KCircleRadius1 5 //线条上圆圈半径
  18. @interface LHYChartView ()<UIScrollViewDelegate,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,CAAnimationDelegate>
  19. {
  20. CGFloat currentPage;//当前页数
  21. //CGFloat Xmargin;//X轴方向的偏移
  22. CGFloat Ymargin;//Y轴方向的偏移
  23. CGPoint lastPoint;//最后一个坐标点
  24. UIButton *firstBtn;
  25. UIButton *lastBtn;
  26. CGFloat titleWOfY;
  27. }
  28. @property (nonatomic,strong)YJYTouchScroll *chartScrollView;
  29. @property (nonatomic,strong)YJYTouchCollectionView * xAxiCollectionView;
  30. @property (nonatomic,strong)UIPageControl *pageControl;//分页
  31. @property (nonatomic,strong)NSMutableArray *leftPointArr;//左边的数据源
  32. @property (nonatomic,strong)NSMutableArray *rightPointArr;//左边的数据源
  33. @property (nonatomic,strong)NSMutableArray *leftBtnArr;//左边按钮
  34. @property (nonatomic, strong)NSMutableArray *detailLabelArr;
  35. @property (nonatomic,strong)NSArray *leftScaleArr;
  36. @property (nonatomic,strong)NSArray *rightScaleArr;
  37. @property (nonatomic,strong)NSMutableArray *leftScaleViewArr;//左边的点击显示图
  38. @property (nonatomic,strong)UIView *scaleBgView;
  39. @property (nonatomic,strong)UILabel *lineLabel;
  40. @property (nonatomic,strong)UILabel *scaleLabel;
  41. @property (nonatomic,strong)UILabel *dateTimeLabel;
  42. @property (nonatomic,assign)CGFloat leftJiange;
  43. @property (nonatomic,assign)CGFloat jiange;
  44. @property (nonatomic,assign)CGFloat rightJiange;
  45. @property (nonatomic,assign)BOOL showSelect;
  46. @property (nonatomic,assign) NSInteger selectIndex;
  47. @property (nonatomic,strong)UIView *selectView;
  48. @property (nonatomic,strong)LHYLinesPaoPaoView * paopaoView;
  49. @property (nonatomic,strong)NSMutableArray *charCircleViewArr;
  50. @property (strong,nonatomic) UIBezierPath *circlePath;
  51. @property (strong,nonatomic) CAGradientLayer *gradientlayer;
  52. @property (strong,nonatomic) CAShapeLayer *percentLayer;
  53. @property (nonatomic,strong) UIView * circleView;
  54. @property (nonatomic,assign) NSInteger indexPathIndex;
  55. @property (nonatomic,strong) NSMutableArray * markArray;
  56. @property (nonatomic,strong) CAShapeLayer * dashLayer;
  57. //最后点击
  58. @property (nonatomic,assign) NSInteger lastIndex;
  59. //是否是刷新
  60. @property (nonatomic,assign) BOOL reLoading;
  61. //记录滚动位置
  62. @property (nonatomic,assign) CGPoint contentOffset;
  63. //最后一次点击的坐标
  64. @property (nonatomic,strong) NSValue * lastValue;
  65. //选中的泡泡Tag
  66. @property (nonatomic,assign) NSInteger selectTag;
  67. @end
  68. @implementation LHYChartView
  69. #pragma mark --------初始化-----------
  70. -(instancetype)initWithFrame:(CGRect)frame{
  71. if (self = [super initWithFrame:frame]) {
  72. [self initNew];
  73. }
  74. return self;
  75. }
  76. -(void)awakeFromNib{
  77. [super awakeFromNib];
  78. [self initNew];
  79. }
  80. -(instancetype)init{
  81. if (self = [super init]) {
  82. [self initNew];
  83. }
  84. return self;
  85. }
  86. -(void)initNew {
  87. currentPage = 0;
  88. _precisionScale = 1;
  89. _indexPathIndex = -1;
  90. self.leftPointArr = [NSMutableArray array];
  91. self.rightPointArr = [NSMutableArray array];
  92. self.leftBtnArr = [NSMutableArray array];
  93. self.detailLabelArr = [NSMutableArray array];
  94. self.leftScaleArr = [NSArray array];
  95. self.leftScaleViewArr = [NSMutableArray array];
  96. self.markArray = [NSMutableArray array];
  97. self.borderLineColor = [UIColor colorWithRed:224/255.0f green:224/255.0f blue:224/255.0f alpha:1];
  98. self.borderTriangleColor = [UIColor colorWithRed:224/255.0f green:224/255.0f blue:224/255.0f alpha:1];
  99. self.showSelect = NO;
  100. self.isFloating = NO;
  101. self.chartViewStyle = 0;
  102. self.chartLayerStyle = 0;
  103. self.lineLayerStyle = 0;
  104. self.proportion = 0.5;
  105. self.colors = [NSArray array];
  106. self.lineWidth = 1;
  107. self.isShow = NO;
  108. self.markColor = [UIColor whiteColor];
  109. self.paopaoDataArray = [NSArray new];
  110. self.unitStyle = LHYUnitDefault;
  111. self.paopaoTitleArray = [NSArray array];
  112. self.isSelect = YES;
  113. self.leftJiange = 1;
  114. self.rightJiange = 1;
  115. self.jiange = 1;
  116. self.isShowYtext = YES;
  117. self.isShowFirstPaoPao = NO;
  118. self.unitName = @"";
  119. self.selectTag = -1;
  120. self.middleLineColor = [UIColor colorWithHexString:@"e0e0e0"];
  121. UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewClick:)];
  122. [self addGestureRecognizer:tap];
  123. titleWOfY = 0;
  124. _Xmargin = 50;
  125. }
  126. -(UILabel *)scaleLabel{
  127. if (!_scaleLabel) {
  128. _scaleLabel = [[UILabel alloc]init];
  129. _scaleLabel.textAlignment = 1;
  130. _scaleLabel.text = @"3.3681%";
  131. _scaleLabel.font = [UIFont systemFontOfSize:11];
  132. _scaleLabel.backgroundColor = [UIColor colorWithRed:255/255.0 green:159/255.0 blue:106/255.0 alpha:1];
  133. _scaleLabel.textColor = [UIColor whiteColor];
  134. }
  135. return _scaleLabel;
  136. }
  137. -(UILabel *)dateTimeLabel{
  138. if (!_dateTimeLabel) {
  139. _dateTimeLabel = [[UILabel alloc]init];
  140. _dateTimeLabel.textAlignment = 1;
  141. _dateTimeLabel.text = @"2016.04.16";
  142. _dateTimeLabel.font = [UIFont systemFontOfSize:11];
  143. _dateTimeLabel.backgroundColor = [UIColor whiteColor];
  144. _dateTimeLabel.textColor = [UIColor colorWithRed:181/255.0 green:181/255.0 blue:181/255.0 alpha:1];
  145. }
  146. return _dateTimeLabel;
  147. }
  148. -(NSMutableArray *)charCircleViewArr{
  149. if (!_charCircleViewArr) {
  150. _charCircleViewArr = [NSMutableArray new];
  151. }
  152. return _charCircleViewArr;
  153. }
  154. -(YJYTouchCollectionView *)xAxiCollectionView{
  155. if (!_xAxiCollectionView) {
  156. UICollectionViewFlowLayout *collectionViewLayout = [[UICollectionViewFlowLayout alloc]init];
  157. collectionViewLayout.minimumInteritemSpacing = 0;
  158. collectionViewLayout.minimumLineSpacing = 0;
  159. collectionViewLayout.sectionInset = UIEdgeInsetsMake(0, 4, 0, 0);
  160. collectionViewLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
  161. _xAxiCollectionView = [[YJYTouchCollectionView alloc]initWithFrame:CGRectMake(CGRectGetMinX(_chartScrollView.frame), CGRectGetMaxY(_chartScrollView.frame) + 10, CGRectGetWidth(_chartScrollView.frame) + CGRectGetWidth(_chartScrollView.frame) / (_xRow - 1), 20) collectionViewLayout:collectionViewLayout];
  162. _xAxiCollectionView.backgroundColor = [UIColor clearColor];
  163. [_xAxiCollectionView registerNib:[UINib nibWithNibName:@"YJYLinesCell" bundle:nil] forCellWithReuseIdentifier:@"YJYLinesCell"];
  164. _xAxiCollectionView.delegate = self;
  165. _xAxiCollectionView.dataSource = self;
  166. _xAxiCollectionView.bounces = NO;
  167. _xAxiCollectionView.showsHorizontalScrollIndicator = NO;
  168. _xAxiCollectionView.userInteractionEnabled = YES;
  169. [self addSubview:_xAxiCollectionView];
  170. }
  171. return _xAxiCollectionView;
  172. }
  173. - (UIView *)selectView {
  174. if (!_selectView) {
  175. _selectView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0.5, self.chartScrollView.frame.size.height)];
  176. _selectView.backgroundColor = _markColor;
  177. [self.chartScrollView addSubview:_selectView];
  178. }
  179. return _selectView;
  180. }
  181. -(void)setMarkColor:(UIColor *)markColor{
  182. _markColor = markColor;
  183. }
  184. -(LHYLinesPaoPaoView *)paopaoView{
  185. if (!_paopaoView) {
  186. _paopaoView = [[LHYLinesPaoPaoView alloc] initWithFrame:CGRectZero];
  187. _paopaoView.backgroundColor = _paopaoBackGroundColor;
  188. _paopaoView.layer.shadowColor = [UIColor blackColor].CGColor;
  189. _paopaoView.layer.shadowOffset = CGSizeMake(0, 3);
  190. _paopaoView.layer.shadowOpacity = 0.5;
  191. [self.chartScrollView addSubview:_paopaoView];
  192. }
  193. return _paopaoView;
  194. }
  195. -(UILabel *)lineLabel{
  196. if (!_lineLabel) {
  197. _lineLabel = [[UILabel alloc]init];
  198. _lineLabel.backgroundColor = [UIColor colorWithRed:255/255.0 green:159/255.0 blue:106/255.0 alpha:1];
  199. }
  200. return _lineLabel;
  201. }
  202. #pragma -mark -------------scrollViewDelegate----------------
  203. -(void)scrollViewDidScroll:(UIScrollView *)scrollView{
  204. self.contentOffset = scrollView.contentOffset;
  205. if (scrollView == _chartScrollView) {
  206. _xAxiCollectionView.contentOffset = scrollView.contentOffset;
  207. }else{
  208. _chartScrollView.contentOffset = scrollView.contentOffset;
  209. }
  210. for (UIView * markCrossView in self.markArray) {
  211. CGRect frame = markCrossView.frame;
  212. frame.origin.x = scrollView.contentOffset.x;
  213. [markCrossView setFrame:frame];
  214. }
  215. }
  216. #pragma -mark --------------collViewDelegate----------------
  217. -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
  218. if (self.dataArrOfX.count > 0) {
  219. return self.dataArrOfX.count + 2;
  220. }
  221. return self.dataArrOfX.count;
  222. }
  223. -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
  224. YJYLinesCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"YJYLinesCell" forIndexPath:indexPath];
  225. if (indexPath.row == _indexPathIndex + 1) {
  226. if (self.x_Select_Font) {
  227. cell.titleLB.font = self.x_Select_Font;
  228. }else{
  229. cell.titleLB.font = self.x_Font;
  230. }
  231. if (self.x_Select_Color) {
  232. cell.titleLB.textColor = self.x_Select_Color;
  233. }else{
  234. cell.titleLB.textColor = self.x_Color;
  235. }
  236. }else{
  237. cell.titleLB.font = self.x_Font;
  238. cell.titleLB.textColor = self.x_Color;
  239. }
  240. if (indexPath.row == 0 || indexPath.row == self.dataArrOfX.count + 1) {
  241. cell.titleLB.text = @"";
  242. }else{
  243. cell.titleLB.text = self.dataArrOfX[indexPath.row - 1];
  244. }
  245. cell.titleLB.textAlignment=NSTextAlignmentCenter;
  246. return cell;
  247. }
  248. -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
  249. if (indexPath.row == 0 || indexPath.row == self.dataArrOfX.count + 1) {
  250. return CGSizeMake(CGRectGetWidth(_chartScrollView.frame) / (_xRow - 1) / 2, 20);
  251. }else{
  252. return CGSizeMake(CGRectGetWidth(self.chartScrollView.frame) / (self.xRow - 1), 20);
  253. }
  254. }
  255. -(void)setLeftDataArr:(NSArray *)leftDataArr{
  256. _leftDataArr = leftDataArr;
  257. }
  258. -(void)setRightDataArr:(NSArray *)rightDataArr{
  259. _rightDataArr = rightDataArr;
  260. self.pageControl.numberOfPages = 1;
  261. }
  262. // 获取数据最大值,并计算每一行间隔值
  263. - (CGFloat)spaceValue:(NSArray *)array{
  264. CGFloat minValue = MAXFLOAT;
  265. CGFloat maxValue = -MAXFLOAT;
  266. for (int i = 0; i < [array count]; i++) {
  267. if ([array[i] floatValue] * _precisionScale> maxValue) {
  268. maxValue = [array[i] floatValue] * _precisionScale;
  269. }
  270. if ([array[i] floatValue] * _precisionScale < minValue) {
  271. minValue = [array[i] floatValue] * _precisionScale;
  272. }
  273. }
  274. NSInteger max = [self getNumber:maxValue];
  275. if (_unitStyle == LHYUnitMillion) {
  276. NSInteger maxValueInterger = max / 100000000.f + 0.99;
  277. NSInteger xMaxValue = maxValueInterger % (_row - 1);
  278. if (xMaxValue != 0) {
  279. xMaxValue = (_row - 1) - xMaxValue + maxValueInterger;
  280. }else{
  281. xMaxValue = maxValueInterger;
  282. }
  283. return xMaxValue / (_row - 1) * 100000000.f;
  284. }else if (_unitStyle == LHYUnitWan) {
  285. NSInteger maxValueInterger = max / 10000.f + 0.99;
  286. NSInteger xMaxValue = maxValueInterger % (_row - 1);
  287. if (xMaxValue != 0) {
  288. xMaxValue = (_row - 1) - xMaxValue + maxValueInterger;
  289. }else{
  290. xMaxValue = maxValueInterger;
  291. }
  292. return xMaxValue / (_row - 1) * 10000.f;
  293. }else if (_unitStyle == LHYUnitThousand) {
  294. NSInteger maxValueInterger = max / 1000.f + 0.99;
  295. NSInteger xMaxValue = maxValueInterger % (_row - 1);
  296. if (xMaxValue != 0) {
  297. xMaxValue = (_row - 1) - xMaxValue + maxValueInterger;
  298. }else{
  299. xMaxValue = maxValueInterger;
  300. }
  301. return xMaxValue / (_row - 1) * 1000.f;
  302. }else if (_unitStyle == LHYUnitMoneyDefault) {
  303. if (max == 0) {
  304. return 10000.f;
  305. }
  306. NSInteger maxValueInterger = 0;
  307. if (max < 100000000) {
  308. maxValueInterger = max / 1000.f + 0.999;
  309. }else{
  310. maxValueInterger = max / 10000000.f + 0.9999999;
  311. }
  312. NSInteger xMaxValue = maxValueInterger % (_row - 1);
  313. if (xMaxValue != 0) {
  314. xMaxValue = (_row - 1) - xMaxValue + maxValueInterger;
  315. }else{
  316. if (maxValueInterger == 0) {
  317. xMaxValue = _row - 1;
  318. }else{
  319. xMaxValue = maxValueInterger;
  320. }
  321. }
  322. if (max >= 100000000) {
  323. return xMaxValue / (_row - 1) * 10000000.f;
  324. }
  325. return xMaxValue / (_row - 1) * 1000.f;
  326. }else{
  327. NSInteger maxValueInterger = 0;
  328. if (max >= 1000) {
  329. maxValueInterger = max / 100.f + 0.99;
  330. }else{
  331. maxValueInterger = max;
  332. }
  333. NSInteger xMaxValue = maxValueInterger % (_row - 1);
  334. if (xMaxValue != 0) {
  335. xMaxValue = (_row - 1) - xMaxValue + maxValueInterger;
  336. }else{
  337. xMaxValue = maxValueInterger;
  338. }
  339. if (max >= 1000) {
  340. return xMaxValue / (_row - 1) * 100;
  341. }
  342. return xMaxValue / (_row - 1);
  343. }
  344. }
  345. // 只取小数点之前的数字
  346. - (CGFloat)getNumber:(CGFloat)value{
  347. CGFloat upValue = ceil(value);
  348. NSString *string = [NSString stringWithFormat:@"%.0f",upValue];
  349. return [string integerValue];
  350. }
  351. #pragma mark ----------显示---------------
  352. -(void)show{
  353. self.reLoading = NO;
  354. self.contentOffset = CGPointMake(0, 0);
  355. self.lastIndex = 0;
  356. [self onLoading];
  357. }
  358. -(void)reShow{
  359. self.reLoading = YES;
  360. self.selectIndex = -1;
  361. [self onLoading];
  362. }
  363. -(void)onLoading{
  364. if (_dashLayer) {
  365. [_dashLayer removeFromSuperlayer];
  366. _dashLayer = nil;
  367. }
  368. [self.chartScrollView removeFromSuperview];
  369. [self.xAxiCollectionView removeFromSuperview];
  370. [self.paopaoView removeFromSuperview];
  371. self.chartScrollView = nil;
  372. self.xAxiCollectionView = nil;
  373. self.paopaoView = nil;
  374. [self colorConversion];
  375. self.selectView = nil;
  376. /// 添加连线
  377. [self addDetailViews];
  378. [self.xAxiCollectionView reloadData];
  379. switch (_chartViewStyle) {
  380. case 0:
  381. [self showLeftRightView];
  382. break;
  383. case 1:
  384. [self showLeftRightView];
  385. break;
  386. case 2:
  387. [self showLeftRightView];
  388. break;
  389. default:
  390. break;
  391. }
  392. [_chartScrollView setContentOffset:self.contentOffset];
  393. if (!self.reLoading) {
  394. if (self.leftPointArr.count > 0) {
  395. NSArray * pointArray = self.leftPointArr[0];
  396. if (self.isShowFirstPaoPao && pointArray.count > 0) {
  397. NSValue * pointValue = pointArray[0];
  398. CGPoint point = [pointValue CGPointValue];
  399. point.x += titleWOfY;
  400. [self viewClick:[NSValue valueWithCGPoint:point]];
  401. if (self.paopaoView.hidden) {
  402. [self viewClick:[NSValue valueWithCGPoint:point]];
  403. }
  404. }
  405. if (self.isShowLastPaoPao && pointArray.count > 0) {
  406. CGFloat contentSizeWidth = self.chartScrollView.contentSize.width;
  407. CGFloat offsetX = contentSizeWidth - CGRectGetWidth(self.chartScrollView.frame);
  408. CGPoint contentPoint = CGPointMake(offsetX < 0 ? 0 : offsetX, 0);
  409. [self.chartScrollView setContentOffset:contentPoint];
  410. }
  411. }
  412. }else{
  413. if (self.leftPointArr.count > 0) {
  414. if (self.lastIndex) {
  415. CGPoint point = self.lastValue.CGPointValue;
  416. self.lastValue = [NSValue valueWithCGPoint:point];
  417. point.x -= titleWOfY;
  418. if (self.selectTag >= 0) {
  419. [self drawOtherLin:self.selectTag AndPoint:point];
  420. }
  421. }
  422. }
  423. }
  424. }
  425. //转换颜色
  426. -(void)colorConversion{
  427. NSMutableArray * colorArray = [NSMutableArray array];
  428. for (id obj in _leftColorStrArr) {
  429. UIColor * color;
  430. if ([obj isKindOfClass:[UIColor class]]) {
  431. color = obj;
  432. }else{
  433. NSString * colorStr = obj;
  434. color = [UIColor colorWithHexString:colorStr];
  435. }
  436. [colorArray addObject:color];
  437. }
  438. _leftColorStrArr = [NSArray arrayWithArray:colorArray];
  439. [colorArray removeAllObjects];
  440. for (id obj in _rightColorStrArr) {
  441. UIColor * color;
  442. if ([obj isKindOfClass:[UIColor class]]) {
  443. color = obj;
  444. }else{
  445. NSString * colorStr = obj;
  446. color = [UIColor colorWithHexString:colorStr];
  447. }
  448. [colorArray addObject:color];
  449. }
  450. _rightColorStrArr = [NSArray arrayWithArray:colorArray];
  451. }
  452. /// 显示左右两种标线
  453. -(void)showLeftRightView{
  454. [self.leftPointArr removeAllObjects];
  455. if (_leftDataArr.count > 0) {
  456. if (!self.reLoading) {
  457. if (_unitStyle == LHYUnitThousand) {
  458. _jiange = 1000;
  459. _leftJiange = 1000;
  460. }else if (_unitStyle == LHYUnitWan){
  461. _jiange = 10000;
  462. _leftJiange = 10000;
  463. }else if (_unitStyle == LHYUnitMillion){
  464. _jiange = 100000000;
  465. _leftJiange = 100000000;
  466. }else{
  467. _jiange = 1;
  468. _leftJiange = 1;
  469. }
  470. }
  471. if (self.max) {
  472. CGFloat jiange = [self spaceValue:@[[NSString stringWithFormat:@"%f",self.max]]];
  473. if (jiange > _leftJiange) {
  474. _leftJiange = jiange;
  475. }
  476. if (jiange > _jiange) {
  477. _jiange = jiange;
  478. }
  479. } else{
  480. for (int i = 0; i < _leftDataArr.count; i++) {
  481. CGFloat jiange = [self spaceValue:_leftDataArr[i]];
  482. if (jiange > _leftJiange) {
  483. _leftJiange = jiange;
  484. }
  485. if (jiange > _jiange) {
  486. _jiange = jiange;
  487. }
  488. }
  489. }
  490. [self addLeftViews];
  491. [self setChartViewContentSize];
  492. if (!_rightDataArr || _rightDataArr.count == 0) {
  493. [self calculateLeftLabelMaxWidth];
  494. [self addLines1With:self.chartScrollView];
  495. }
  496. NSMutableArray * pointMarray = [NSMutableArray array];
  497. for (int i = 0; i < _leftDataArr.count; i++) {
  498. NSArray * dataArray = _leftDataArr[i];
  499. ///添加点
  500. [pointMarray addObject:[self addDataPointWith:self.chartScrollView andArr:dataArray andInterval:_leftJiange]];
  501. }
  502. /// 添加点
  503. [self.leftPointArr addObjectsFromArray:pointMarray];
  504. for (int i = 0; i<pointMarray.count; i++) {
  505. NSArray * colorArray = [NSArray array];
  506. if (i < _colors.count) {
  507. colorArray = _colors[i];
  508. }
  509. [self addBezierPoint:pointMarray[i] andColor:_leftColorStrArr[i<_leftColorStrArr.count?i:_leftColorStrArr.count-1] andColors:colorArray];
  510. }
  511. }
  512. if (_rightDataArr.count > 0) {
  513. if (self.max) {
  514. CGFloat jiange = [self spaceValue:@[[NSString stringWithFormat:@"%f",self.max]]];
  515. if (jiange > _leftJiange) {
  516. _leftJiange = jiange;
  517. }
  518. if (jiange > _jiange) {
  519. _jiange = jiange;
  520. }
  521. }else{
  522. for (int i = 0; i < _rightDataArr.count; i++) {
  523. if (_unitStyle == LHYUnitThousand) {
  524. _rightJiange = 1000;
  525. }else if (_unitStyle == LHYUnitWan){
  526. _rightJiange = 10000;
  527. }else if (_unitStyle == LHYUnitMillion){
  528. _rightJiange = 100000000;
  529. }else{
  530. _rightJiange = 1;
  531. }
  532. CGFloat jiange = [self spaceValue:_rightDataArr[i]];
  533. if (jiange > _rightJiange) {
  534. _rightJiange = jiange;
  535. }
  536. }
  537. }
  538. [self addLeftViews];
  539. [self setChartViewContentSize];
  540. [self calculateLeftLabelMaxWidth];
  541. [self addLines1With:self.chartScrollView];
  542. NSMutableArray * pointMarray = [NSMutableArray array];
  543. for (int i = 0; i < _rightDataArr.count; i++) {
  544. NSArray * dataArray = _rightDataArr[i];
  545. [pointMarray addObject:[self addDataPointWith:self.chartScrollView andArr:dataArray andInterval:_rightJiange]];//添加点
  546. }
  547. [self.leftPointArr addObjectsFromArray:pointMarray];
  548. for (int i = 0; i<pointMarray.count; i++) {
  549. NSArray * colorArray = [NSArray array];
  550. if (i < _colors.count) {
  551. colorArray = _colors[i];
  552. }
  553. [self addBezierPoint:pointMarray[i] andColor:_rightColorStrArr[i<_rightColorStrArr.count?i:_rightColorStrArr.count-1] andColors:colorArray];
  554. }
  555. /// 添加连线
  556. [self addRightViews];
  557. }
  558. if (_leftDataArr.count <= 0 && _rightDataArr.count <= 0) {
  559. [self addLeftViews];
  560. [self setChartViewContentSize];
  561. [self addLines1With:self.chartScrollView];
  562. }
  563. if (self.leftPointArr.count > 0) {
  564. for (int i = 0; i < self.leftPointArr.count; i++) {
  565. NSMutableArray * pointMarray = [NSMutableArray arrayWithArray:self.leftPointArr[i]];
  566. if (pointMarray.count > 2 && pointMarray.count == self.dataArrOfX.count) {
  567. [pointMarray removeObjectAtIndex:pointMarray.count - 1];
  568. [pointMarray removeObjectAtIndex:0];
  569. }else if (pointMarray.count > 0){
  570. [pointMarray removeObjectAtIndex:0];
  571. }
  572. self.leftPointArr[i] = pointMarray;
  573. }
  574. }
  575. [self addBottomViewsWith:self.chartScrollView];
  576. }
  577. -(void)setChartViewContentSize{
  578. CGFloat chartScrollViewwidth = _chartViewStyle == LHYChartViewLeftRightLine ? self.bounds.size.width-titleWOfY * 2 :self.bounds.size.width-titleWOfY;
  579. CGFloat xMargin = chartScrollViewwidth / (_xRow - 1);
  580. if (self.dataArrOfX.count > 0) {
  581. self.chartScrollView.contentSize = CGSizeMake(xMargin*(self.dataArrOfX.count + 1), 0);
  582. }
  583. }
  584. -(void)setIsShowYtext:(BOOL)isShowYtext{
  585. _isShowYtext = isShowYtext;
  586. titleWOfY = isShowYtext ? titleWOfY : 0;
  587. }
  588. #pragma mark *******************数据源************************
  589. -(void)setDataArrOfX:(NSArray *)dataArrOfX{
  590. _dataArrOfX = dataArrOfX;
  591. }
  592. #pragma mark *******************分割线************************
  593. -(void)addDetailViews{
  594. CGFloat width = 0;
  595. width = _chartViewStyle == LHYChartViewLeftRightLine ? self.bounds.size.width-titleWOfY * 2 :self.bounds.size.width-titleWOfY;
  596. self.chartScrollView = [[YJYTouchScroll alloc]initWithFrame:CGRectMake(titleWOfY, 0, width, chartViewHeight)];
  597. self.chartScrollView.backgroundColor = [UIColor clearColor];
  598. self.chartScrollView.bounces = NO;
  599. self.chartScrollView.delegate = self;
  600. self.chartScrollView.showsHorizontalScrollIndicator = NO;
  601. self.chartScrollView.userInteractionEnabled = YES;
  602. [self addSubview:self.chartScrollView];
  603. [self addSubview:self.xAxiCollectionView];
  604. }
  605. #pragma mark 渐变线条
  606. -(void)buildBGCircleLayer:(NSArray *)colors
  607. {
  608. CAShapeLayer *bgCircleLayer = [CAShapeLayer layer];
  609. bgCircleLayer.path = _circlePath.CGPath;
  610. bgCircleLayer.strokeColor = [UIColor lightGrayColor].CGColor;
  611. bgCircleLayer.fillColor = [UIColor clearColor].CGColor;
  612. bgCircleLayer.lineWidth = _lineWidth;
  613. bgCircleLayer.lineCap = kCALineCapRound; // 截面形状
  614. [self addShowPercentLayer:colors];
  615. [self percentAnimation];
  616. }
  617. -(void)addShowPercentLayer:(NSArray *)colors
  618. {
  619. _gradientlayer = (id)[CAGradientLayer layer];
  620. if (colors && colors.count > 0) {
  621. NSMutableArray * colorMarray = [NSMutableArray array];
  622. for (int i = 0; i < colors.count; i++) {
  623. UIColor * color = colors[i];
  624. [colorMarray addObject:(id)color.CGColor];
  625. }
  626. _gradientlayer.colors = colorMarray;
  627. }else{
  628. _gradientlayer.colors = [NSArray arrayWithObjects:(id)[[UIColor redColor]CGColor],(id)[[UIColor blueColor]CGColor], nil];
  629. }
  630. _gradientlayer.startPoint= CGPointMake(0.10, 1);
  631. _gradientlayer.endPoint = CGPointMake(0.90, 1);
  632. if (_locations && _locations.count > 0) {
  633. _gradientlayer.locations = _locations;
  634. }else{
  635. _gradientlayer.locations = @[[NSNumber numberWithFloat:_proportion]];
  636. }
  637. _gradientlayer.frame = CGRectMake(0, 0, self.chartScrollView.contentSize.width, CGRectGetHeight(self.chartScrollView.frame));
  638. _percentLayer = [CAShapeLayer layer];
  639. _percentLayer.path = _circlePath.CGPath;
  640. _percentLayer.strokeColor = [UIColor redColor].CGColor;
  641. _percentLayer.fillColor = [UIColor clearColor].CGColor;
  642. _percentLayer.lineWidth = _lineWidth;
  643. _percentLayer.strokeStart = 0;
  644. _percentLayer.strokeEnd = 1;
  645. _percentLayer.lineCap = kCALineCapRound;
  646. if (_chartLayerStyle == 2) {
  647. _percentLayer.shadowColor = [UIColor redColor].CGColor;
  648. _percentLayer.shadowOffset = CGSizeMake(0,5);
  649. _percentLayer.shadowOpacity = 0.5;
  650. }
  651. [_gradientlayer setMask:_percentLayer];
  652. [self.chartScrollView.layer addSublayer:_gradientlayer];
  653. }
  654. -(void)percentAnimation
  655. {
  656. CABasicAnimation *strokeAnmi = [CABasicAnimation animation];
  657. strokeAnmi.keyPath = @"strokeEnd";
  658. strokeAnmi.fromValue = [NSNumber numberWithFloat:0];
  659. strokeAnmi.toValue = [NSNumber numberWithFloat:1.0f];
  660. strokeAnmi.duration =2.0f;
  661. strokeAnmi.delegate = self;
  662. strokeAnmi.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  663. strokeAnmi.autoreverses = NO;
  664. if (!self.reLoading) [_percentLayer addAnimation:strokeAnmi forKey:@"stroke"];
  665. }
  666. //等动画结束之后的操作
  667. -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
  668. {
  669. if (_isShow) {
  670. [self drawCircleArr:self.leftPointArr color:self.leftColorStrArr];
  671. }
  672. //是否动画结束后显示最后一条数据
  673. if (!self.leftPointArr || !self.leftPointArr.count) return;
  674. NSArray * pointArray = self.leftPointArr[0];
  675. if (self.isShowLastPaoPao && pointArray.count > 0) {
  676. CGPoint point = [pointArray[pointArray.count - 1] CGPointValue];
  677. if (point.x >= CGRectGetWidth(self.chartScrollView.frame)) {
  678. point.x = [pointArray[self.xRow - 3] CGPointValue].x;
  679. }
  680. point.x += titleWOfY;
  681. NSValue * value = [NSValue valueWithCGPoint:point];
  682. if (!self.paopaoView || !CGRectGetWidth(self.paopaoView.frame) || self.paopaoView.hidden) {
  683. [self viewClick:value];
  684. }
  685. }
  686. }
  687. #pragma mark ----------绘画折现----------------
  688. -(void)addBezierPoint:(NSArray *)pointArray andColor:(UIColor *)color andColors:(NSArray *)colors{
  689. if (pointArray.count <= 0) {
  690. return;
  691. }
  692. //取得起始点
  693. CGPoint startP = CGPointMake(0, 0);
  694. if (!self.hiddenZreo) {
  695. startP = [[pointArray objectAtIndex:0] CGPointValue];
  696. }else{
  697. startP = [[pointArray objectAtIndex:1] CGPointValue];
  698. }
  699. //直线的连线
  700. UIBezierPath *lineBeizer = [UIBezierPath bezierPath];
  701. [lineBeizer moveToPoint:startP];
  702. _circlePath = lineBeizer;
  703. //遮罩层的形状
  704. UIBezierPath *shelterBezier = [UIBezierPath bezierPath];
  705. shelterBezier.lineCapStyle = kCGLineCapRound;
  706. shelterBezier.lineJoinStyle = kCGLineJoinMiter;
  707. [shelterBezier moveToPoint:startP];
  708. for (int i = 0;i<pointArray.count;i++ ) {
  709. if (!self.hiddenZreo) {
  710. if (i > 0) {
  711. CGPoint prePoint = [[pointArray objectAtIndex:i-1] CGPointValue];
  712. CGPoint nowPoint = [[pointArray objectAtIndex:i] CGPointValue];
  713. [lineBeizer addCurveToPoint:nowPoint controlPoint1:CGPointMake((nowPoint.x+prePoint.x)/2, prePoint.y) controlPoint2:CGPointMake((nowPoint.x+prePoint.x)/2, nowPoint.y)];
  714. if (_chartLayerStyle == LHYChartGradient) [shelterBezier addCurveToPoint:nowPoint controlPoint1:CGPointMake((nowPoint.x+prePoint.x)/2, prePoint.y) controlPoint2:CGPointMake((nowPoint.x+prePoint.x)/2, nowPoint.y)];
  715. if (i == pointArray.count-1) {
  716. /// 添加连线
  717. [lineBeizer moveToPoint:nowPoint];
  718. lastPoint = nowPoint;
  719. }
  720. }
  721. }else{
  722. if (pointArray.count > 2) {
  723. if (i > 1) {
  724. CGPoint prePoint = [[pointArray objectAtIndex:i-1] CGPointValue];
  725. CGPoint nowPoint = [[pointArray objectAtIndex:i] CGPointValue];
  726. [lineBeizer addCurveToPoint:nowPoint controlPoint1:CGPointMake((nowPoint.x+prePoint.x)/2, prePoint.y) controlPoint2:CGPointMake((nowPoint.x+prePoint.x)/2, nowPoint.y)];
  727. if (_chartLayerStyle == LHYChartGradient) [shelterBezier addCurveToPoint:nowPoint controlPoint1:CGPointMake((nowPoint.x+prePoint.x)/2, prePoint.y) controlPoint2:CGPointMake((nowPoint.x+prePoint.x)/2, nowPoint.y)];
  728. if (i == pointArray.count-1) {
  729. ///添加连线
  730. [lineBeizer moveToPoint:nowPoint];
  731. lastPoint = nowPoint;
  732. }
  733. }
  734. }else{
  735. if (i > 0) {
  736. CGPoint prePoint = [[pointArray objectAtIndex:i] CGPointValue];
  737. CGPoint nowPoint = [[pointArray objectAtIndex:i] CGPointValue];
  738. nowPoint.x +=1;
  739. [lineBeizer addCurveToPoint:nowPoint controlPoint1:CGPointMake((nowPoint.x+prePoint.x)/2, prePoint.y) controlPoint2:CGPointMake((nowPoint.x+prePoint.x)/2, nowPoint.y)];
  740. if (_chartLayerStyle == LHYChartGradient) [shelterBezier addCurveToPoint:nowPoint controlPoint1:CGPointMake((nowPoint.x+prePoint.x)/2, prePoint.y) controlPoint2:CGPointMake((nowPoint.x+prePoint.x)/2, nowPoint.y)];
  741. if (i == pointArray.count-1) {
  742. /// 添加连线
  743. [lineBeizer moveToPoint:nowPoint];
  744. lastPoint = nowPoint;
  745. }
  746. }
  747. }
  748. }
  749. }
  750. CGFloat bgViewHeight = self.chartScrollView.bounds.size.height;
  751. //获取最后一个点的X值
  752. CGFloat lastPointX = lastPoint.x;
  753. //最后一个点对应的X轴的值
  754. CGPoint lastPointX1 = CGPointMake(lastPointX, bgViewHeight);
  755. [shelterBezier addLineToPoint:lastPointX1];
  756. /// 回到原点
  757. [shelterBezier addLineToPoint:CGPointMake(startP.x, bgViewHeight)];
  758. [shelterBezier addLineToPoint:startP];
  759. if (_lineLayerStyle == 1) {
  760. if (_chartLayerStyle == 1) {
  761. [self addGradientWithBezierPath:shelterBezier andColor:color];
  762. }
  763. [self buildBGCircleLayer:colors];
  764. return;
  765. }
  766. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  767. shapeLayer.path = lineBeizer.CGPath;
  768. shapeLayer.fillColor = [UIColor clearColor].CGColor;
  769. shapeLayer.strokeColor = color.CGColor;
  770. shapeLayer.lineWidth = 3;
  771. switch (_chartLayerStyle) {
  772. case 0:
  773. break;
  774. case 1:
  775. [self addGradientWithBezierPath:shelterBezier andColor:color];
  776. break;
  777. case 2:
  778. #pragma mark ------------阴影投影---------------
  779. shapeLayer.shadowOffset = CGSizeMake(0, 10);
  780. shapeLayer.shadowColor = color.CGColor;
  781. shapeLayer.shadowOpacity = 0.5;
  782. break;
  783. default:
  784. break;
  785. }
  786. [self.chartScrollView.layer addSublayer:shapeLayer];
  787. CABasicAnimation *strokeAnmi = [CABasicAnimation animation];
  788. strokeAnmi.keyPath = @"strokeEnd";
  789. strokeAnmi.fromValue = [NSNumber numberWithFloat:0];
  790. strokeAnmi.toValue = [NSNumber numberWithFloat:1.0f];
  791. strokeAnmi.duration =2.0f;
  792. strokeAnmi.delegate = self;
  793. strokeAnmi.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  794. strokeAnmi.autoreverses = NO;
  795. if (!self.reLoading) [shapeLayer addAnimation:strokeAnmi forKey:@"stroke"];
  796. }
  797. #pragma mark ------------渐变图层---------------
  798. -(void)addGradientWithBezierPath:(UIBezierPath *)beizer andColor:(UIColor *)color{
  799. /// 遮罩层
  800. CAShapeLayer *shadeLayer = [CAShapeLayer layer];
  801. shadeLayer.path = beizer.CGPath;
  802. shadeLayer.fillColor = [UIColor greenColor].CGColor;
  803. CAGradientLayer *gradientLayer = [CAGradientLayer layer];
  804. gradientLayer.frame = CGRectMake(0, 0, 0, self.chartScrollView.bounds.size.height);
  805. gradientLayer.startPoint = CGPointMake(0, 0);
  806. gradientLayer.endPoint = CGPointMake(0, 1);
  807. gradientLayer.cornerRadius = 5;
  808. gradientLayer.masksToBounds = YES;
  809. gradientLayer.colors = @[(__bridge id)[color colorWithAlphaComponent:0.3].CGColor,(__bridge id)[color colorWithAlphaComponent:0].CGColor];
  810. gradientLayer.locations = @[@(0.5f)];
  811. CALayer *baseLayer = [CALayer layer];
  812. [baseLayer addSublayer:gradientLayer];
  813. [baseLayer setMask:shadeLayer];
  814. [self.chartScrollView.layer addSublayer:baseLayer];
  815. CABasicAnimation *boundsAnmi = [CABasicAnimation animation];
  816. boundsAnmi.keyPath = @"bounds";
  817. boundsAnmi.duration = self.reLoading ? 0.0001f : 2.f;
  818. boundsAnmi.toValue = [NSValue valueWithCGRect:CGRectMake(5, 0, 2*lastPoint.x, self.chartScrollView.bounds.size.height)];
  819. boundsAnmi.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  820. boundsAnmi.fillMode = kCAFillModeForwards;
  821. boundsAnmi.delegate = self;
  822. boundsAnmi.autoreverses = NO;
  823. boundsAnmi.removedOnCompletion = NO;
  824. [gradientLayer addAnimation:boundsAnmi forKey:@"bounds"];
  825. }
  826. #pragma mark ----------获取所有坐标点-------------
  827. -(NSMutableArray *)addDataPointWith:(UIView *)view andArr:(NSArray *)DataArr andInterval:(CGFloat)interval{
  828. CGFloat height = self.chartScrollView.bounds.size.height - 13 - KCircleRadius1 / 2 - 4;
  829. /// 初始点
  830. NSMutableArray *arr = [NSMutableArray arrayWithArray:DataArr];
  831. NSMutableArray * marr = [NSMutableArray array];
  832. CGFloat xMargin = CGRectGetWidth(self.chartScrollView.frame) / (_xRow - 1);
  833. for (int i = 0; i<arr.count; i++) {
  834. float tempHeight = [arr[i] floatValue] / (interval * (_row - 1)) ;
  835. NSValue *point = [NSValue valueWithCGPoint:CGPointMake(xMargin * i + xMargin, (height *(1 - tempHeight) + 13))];
  836. if (i == 0) {
  837. NSValue *point1 = [NSValue valueWithCGPoint:CGPointMake(0 , (height *(1 - tempHeight) + 13))];
  838. [marr addObject:point1];
  839. }
  840. [marr addObject:point];
  841. }
  842. return marr;
  843. }
  844. #pragma mark ---------添加左侧Y轴标注--------------
  845. -(void)addLeftViews{
  846. CGFloat textWidth = 0;
  847. CGFloat labelWidth = 0;
  848. switch (_chartViewStyle) {
  849. case 0:
  850. textWidth = [NSString measureSinglelineStringWidth:[self unitValue:_jiange * (_row - 1)] andFont:_y_Font];
  851. break;
  852. case 1:
  853. textWidth = [NSString measureSinglelineStringWidth:[self unitValue:_jiange * (_row - 1)] andFont:_y_Font];
  854. break;
  855. case 2:
  856. textWidth = [NSString measureSinglelineStringWidth:[self unitValue:_leftJiange * (_row - 1)] andFont:_y_Font];
  857. break;
  858. default:
  859. break;
  860. }
  861. if (_unitStyle == LHYUnitMoneyPercentage) {
  862. textWidth = [NSString measureSinglelineStringWidth:@"100%" andFont:_y_Font];
  863. }
  864. if (_isShowYtext) labelWidth = textWidth + 2 > labelWidth ? textWidth + 2 : labelWidth;
  865. titleWOfY = labelWidth;
  866. [self.markArray removeAllObjects];
  867. CGFloat topHeight = 13;
  868. CGFloat chartScrollViewwidth = _chartViewStyle == LHYChartViewLeftRightLine ? self.bounds.size.width-labelWidth * 2 :self.bounds.size.width-labelWidth;
  869. for (NSInteger i = 0; i< _row ;i++ ) {
  870. UILabel * leftLabel = [self viewWithTag:1000 + i + 1];
  871. CGFloat height = CGRectGetHeight(self.chartScrollView.frame) - topHeight;
  872. if (!leftLabel) {
  873. leftLabel = [[UILabel alloc]init];
  874. leftLabel.tag = 1000 + i + 1;
  875. }
  876. CGRect frame = CGRectMake(0, topHeight + height- height / (_row - 1) * i - [_y_Font pointSize] / 2, labelWidth*2.0, [_y_Font pointSize]);
  877. [leftLabel setFrame:frame];
  878. leftLabel.font = _y_Font;
  879. leftLabel.textColor = _y_Color;
  880. if (_unitStyle == LHYUnitMoneyPercentage) {
  881. leftLabel.text = [NSString stringWithFormat:@"%.0f%%", 100.0 / (_row - 1) * i];
  882. } else{
  883. switch (_chartViewStyle) {
  884. case 0:
  885. leftLabel.text = [self unitValue:_jiange * i];
  886. break;
  887. case 1:
  888. leftLabel.text = [self unitValue:_jiange * i];
  889. break;
  890. case 2:
  891. leftLabel.text = [self unitValue:_leftJiange * i];
  892. break;
  893. default:
  894. break;
  895. }
  896. }
  897. if (i > 0 && self.isShowYtext) [self addSubview:leftLabel];
  898. if (self.isGrid){
  899. CGFloat xMargin = chartScrollViewwidth / (_xRow - 1);
  900. CGFloat width = 0;
  901. if (xMargin*(self.dataArrOfX.count + 1) < chartScrollViewwidth){
  902. width = chartScrollViewwidth;
  903. }else{
  904. width = xMargin*(self.dataArrOfX.count + 1);
  905. }
  906. UIView * crossView = [[UIView alloc] initWithFrame:CGRectMake(0,topHeight + height - height / (_row - 1) * i + 0.5,width, 0.5)];
  907. crossView.backgroundColor = _middleLineColor;
  908. [self.chartScrollView addSubview:crossView];
  909. if (i != 0) {
  910. UIView * markCrossView = [[UIView alloc] initWithFrame:CGRectMake(0,topHeight + height - height / (_row - 1) * i + 0.5,8, 0.5)];
  911. markCrossView.backgroundColor = _borderLineColor;
  912. [self.chartScrollView addSubview:markCrossView];
  913. [self.markArray addObject:markCrossView];
  914. }
  915. }
  916. }
  917. if (self.isGrid) {
  918. if (!self.dataArrOfX || self.dataArrOfX.count == 0 || (self.dataArrOfX.count > 0 && chartScrollViewwidth / (self.xRow - 3)*(self.dataArrOfX.count - 1) <= chartScrollViewwidth + 1)) {
  919. CGFloat verticalX = 0;
  920. while (verticalX <= chartScrollViewwidth + 0.5) {
  921. UIView * vertical = [[UIView alloc] initWithFrame:CGRectMake(verticalX - 0.5,topHeight,0.5, CGRectGetHeight(self.chartScrollView.frame) - topHeight)];
  922. vertical.backgroundColor = _middleLineColor;
  923. [self.chartScrollView addSubview:vertical];
  924. verticalX += chartScrollViewwidth / (self.xRow - 1);
  925. }
  926. }else{
  927. for (int i = 0; i < self.dataArrOfX.count + 2; i++) {
  928. UIView * vertical = [[UIView alloc] initWithFrame:CGRectMake(chartScrollViewwidth / (self.xRow - 1) * i - 0.5,topHeight,0.5, CGRectGetHeight(self.chartScrollView.frame)- topHeight)];
  929. vertical.backgroundColor = _middleLineColor;
  930. [self.chartScrollView addSubview:vertical];
  931. }
  932. }
  933. }
  934. }
  935. -(void)calculateLeftLabelMaxWidth{
  936. for (NSInteger i = 0;i< _row ;i++ ) {
  937. NSString * str = @"";
  938. switch (_chartViewStyle) {
  939. case 0:
  940. str = [self unitValue:_jiange * i];
  941. break;
  942. case 1:
  943. str = [self unitValue:_jiange * i];
  944. break;
  945. case 2:
  946. str = [self unitValue:_leftJiange * i];
  947. break;
  948. default:
  949. break;
  950. }
  951. }
  952. CGFloat width = _chartViewStyle == LHYChartViewLeftRightLine ? self.bounds.size.width-titleWOfY * 2 :self.bounds.size.width-titleWOfY;
  953. [_chartScrollView setFrame:CGRectMake(titleWOfY, 0, width, chartViewHeight)];
  954. [_xAxiCollectionView setFrame:CGRectMake(CGRectGetMinX(_chartScrollView.frame), CGRectGetMaxY(_chartScrollView.frame) + 10, CGRectGetWidth(self.frame) - CGRectGetMinX(_chartScrollView.frame), 20)];
  955. }
  956. -(NSString *)unitValue:(CGFloat)value{
  957. CGFloat returnValue = 0;
  958. if (_unitStyle == LHYUnitGe || _unitStyle == LHYUnitDefault) {
  959. returnValue = value;
  960. }else if (_unitStyle == LHYUnitMoneyPercentageDefault){
  961. return [NSString stringWithFormat:@"%.0f%%",value];
  962. }else if (_unitStyle == 1) {
  963. returnValue = value / 1000;
  964. }else if (_unitStyle == 2){
  965. returnValue = value / 10000;
  966. }else if (_unitStyle == 3){
  967. returnValue = value / 100000000;
  968. }else if (_unitStyle == 4){
  969. if (value >= 100000000) {
  970. return [NSString stringWithFormat:@"%.1f亿%@",value / 100000000,self.unitName];
  971. }else{
  972. return [NSString stringWithFormat:@"%.1f万%@",value / 10000,self.unitName];
  973. }
  974. }
  975. if (returnValue >= 1000) {
  976. return [NSString stringWithFormat:@"%.1fk%@",returnValue / 1000,self.unitName];
  977. }
  978. return [NSString stringWithFormat:@"%.0f%@",returnValue,self.unitName];
  979. }
  980. #pragma mark ---------添加右侧Y轴标注--------------
  981. -(void)addRightViews{
  982. for (NSInteger i = 0;i< _row ;i++ ) {
  983. CGFloat height = CGRectGetHeight(_chartScrollView.frame);
  984. CGFloat jiange = (height - _row * 15) / (_row - 1);
  985. CGRect frame = CGRectMake(CGRectGetWidth(self.frame) - titleWOfY + 5, height - 15*(i + 1) - jiange * i , titleWOfY - 5, 15);
  986. UILabel *leftLabel = [[UILabel alloc]initWithFrame:frame];
  987. leftLabel.font = [UIFont systemFontOfSize:10.0f];
  988. leftLabel.textColor = [UIColor colorWithHexString:@"0x999999"];
  989. leftLabel.textAlignment = NSTextAlignmentLeft;
  990. leftLabel.text = [NSString stringWithFormat:@"%.0f",_rightJiange * i];
  991. [self addSubview:leftLabel];
  992. }
  993. }
  994. -(void)addBottomViewsWith:(UIView *)View{
  995. NSArray *bottomArr;
  996. if (View == self.chartScrollView) {
  997. bottomArr = _dataArrOfX;
  998. }else{
  999. }
  1000. }
  1001. -(void)TopBtnAction:(UIButton *)sender{
  1002. for (UIButton*btn in _leftBtnArr) {
  1003. if (sender.tag == btn.tag) {
  1004. btn.selected = YES;
  1005. }else{
  1006. btn.selected = NO;
  1007. }
  1008. }
  1009. [self showDetailLabel:sender];
  1010. }
  1011. -(void)showDetailLabel:(UIButton *)sender{
  1012. for (UILabel * label in _detailLabelArr) {
  1013. if (sender.tag+200 == label.tag) {
  1014. label.hidden = NO;
  1015. }else{
  1016. label.hidden = YES;
  1017. }
  1018. }
  1019. }
  1020. #define mark - 点击屏幕事件
  1021. -(void)viewClick:(id)sender{
  1022. if (!_isSelect) return;
  1023. [self colorConversion];
  1024. CGPoint point;
  1025. if ([sender isKindOfClass:[UITapGestureRecognizer class]]) {
  1026. point = [sender locationInView:self];
  1027. self.lastValue = [NSValue valueWithCGPoint:point];
  1028. point.x -= titleWOfY;
  1029. } else {
  1030. NSValue * value = sender;
  1031. point = value.CGPointValue;
  1032. self.lastValue = [NSValue valueWithCGPoint:point];
  1033. point.x -= titleWOfY;
  1034. }
  1035. CGFloat xMargin = CGRectGetWidth(self.chartScrollView.frame) / (_xRow - 1);
  1036. if (point.x > xMargin / 2 && point.x < CGRectGetMaxX(self.chartScrollView.frame) && point.y > CGRectGetMinY(self.chartScrollView.frame) && point.y < CGRectGetMaxY(self.chartScrollView.frame)) {
  1037. point.x = point.x + self.chartScrollView.contentOffset.x;
  1038. point.y = point.y + self.chartScrollView.contentOffset.y;
  1039. NSInteger index = point.x / xMargin - 1;
  1040. float indexF = point.x - xMargin * (index + 1);
  1041. if (indexF>xMargin / 2) {
  1042. index = index + 1;
  1043. }
  1044. self.selectTag = index;
  1045. [self drawOtherLin:index AndPoint:point];
  1046. return;
  1047. }
  1048. if (point.x > xMargin / 2 && point.x < CGRectGetMaxX(self.xAxiCollectionView.frame) && point.y > CGRectGetMinY(self.xAxiCollectionView.frame) && point.y < CGRectGetMaxY(self.xAxiCollectionView.frame)) {
  1049. point.x = point.x + self.xAxiCollectionView.contentOffset.x;
  1050. point.y = point.y + self.xAxiCollectionView.contentOffset.y;
  1051. NSInteger index = point.x / xMargin - 1;
  1052. float indexF = point.x - xMargin * (index + 1);
  1053. if (indexF>xMargin / 2) {
  1054. index = index + 1;
  1055. }
  1056. [self drawOtherLin:index AndPoint:point];
  1057. return;
  1058. }
  1059. }
  1060. /// 点击之后画出重点线以及数值
  1061. -(void)drawOtherLin:(NSInteger)index AndPoint:(CGPoint)touchpoint{
  1062. if(index >= self.dataArrOfX.count || index<0 || self.dataArrOfX.count == 0){
  1063. return ;
  1064. }
  1065. [self.paopaoView removeFromSuperview];
  1066. self.paopaoView = nil;
  1067. if (self.showSelect && self.selectIndex== index) {
  1068. self.lastIndex = 0;
  1069. self.selectTag = -1;
  1070. self.selectView.hidden = YES;
  1071. self.paopaoView.hidden = YES;
  1072. self.indexPathIndex = -1;
  1073. for (UIView *view in self.charCircleViewArr) {
  1074. [view removeFromSuperview];
  1075. }
  1076. self.showSelect = NO;
  1077. [_xAxiCollectionView reloadData];
  1078. return;
  1079. }
  1080. self.lastIndex = index + 1;
  1081. self.showSelect = YES;
  1082. self.selectIndex = index;
  1083. self.indexPathIndex = index;
  1084. [_xAxiCollectionView reloadData];
  1085. [self setPaopaoUI:index];
  1086. }
  1087. -(void)setPaopaoUI:(NSInteger)index{
  1088. CGFloat xMargin = CGRectGetWidth(self.chartScrollView.frame) / (_xRow - 1);
  1089. [self.chartScrollView bringSubviewToFront:self.selectView];
  1090. self.selectView.hidden = NO;
  1091. self.selectView.backgroundColor = _markColor;
  1092. if (xMargin*index + self.selectView.frame.size.width > self.chartScrollView.contentSize.width) {
  1093. self.selectView.frame = CGRectMake(xMargin*index+xMargin, 0, self.selectView.frame.size.width, self.selectView.frame.size.height);
  1094. } else {
  1095. self.selectView.frame = CGRectMake(xMargin*index+xMargin, 0, self.selectView.frame.size.width, self.selectView.frame.size.height);
  1096. }
  1097. [self.chartScrollView bringSubviewToFront:self.paopaoView];
  1098. self.paopaoView.hidden = NO;
  1099. [self.chartScrollView bringSubviewToFront:self.selectView];
  1100. NSMutableArray *dataArr = [NSMutableArray new];
  1101. if (_chartViewStyle == LHYChartViewLeftRightLine) {
  1102. if (self.paopaoDataArray.count > 0){
  1103. [self.paopaoDataArray enumerateObjectsUsingBlock:^(NSArray<NSArray *> * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  1104. if (index < obj.count) {
  1105. [dataArr addObject:obj[index]];
  1106. }
  1107. }];
  1108. } else {
  1109. [self.leftDataArr enumerateObjectsUsingBlock:^(NSArray<NSArray *> * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  1110. if (index < obj.count) {
  1111. [dataArr addObject:obj[index]];
  1112. }
  1113. }];
  1114. [self.rightDataArr enumerateObjectsUsingBlock:^(NSArray<NSArray *> * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  1115. if (index < obj.count) {
  1116. [dataArr addObject:obj[index]];
  1117. }
  1118. }];
  1119. }
  1120. } else {
  1121. if (self.paopaoDataArray.count > 0){
  1122. [self.paopaoDataArray enumerateObjectsUsingBlock:^(NSArray<NSArray *> * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  1123. if (index < obj.count) {
  1124. [dataArr addObject:obj[index]];
  1125. }
  1126. }];
  1127. } else {
  1128. [self.leftDataArr enumerateObjectsUsingBlock:^(NSArray<NSArray *> * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  1129. if (index < obj.count) {
  1130. [dataArr addObject:obj[index]];
  1131. }
  1132. }];
  1133. }
  1134. }
  1135. NSMutableArray *colorArr = [NSMutableArray array];
  1136. for (int i = 0; i < self.leftColorStrArr.count; i++) {
  1137. [colorArr addObject:self.leftColorStrArr[i]];
  1138. }
  1139. for (int i = 0; i < self.rightColorStrArr.count ; i++) {
  1140. [colorArr addObject:self.rightColorStrArr[i]];
  1141. }
  1142. CGSize size = [LHYLinesPaoPaoView getWidthAndHeight:dataArr];
  1143. float paopao_x = index * xMargin + xMargin - size.width * 0.5;
  1144. if (self.paopaoTitleArray.count == 0) {
  1145. size.height -= 17;
  1146. }
  1147. size.height += 13;
  1148. if (paopao_x < 0) {
  1149. paopao_x = 0;
  1150. } else if (paopao_x > self.chartScrollView.contentSize.width - size.width && paopao_x > self.chartScrollView.frame.size.width - size.width) {
  1151. paopao_x = self.chartScrollView.contentSize.width - size.width;
  1152. }
  1153. self.paopaoView.frame = CGRectMake(paopao_x, self.paopaoView.frame.origin.y, size.width-20.0, size.height + 5);
  1154. self.paopaoView.margin = xMargin;
  1155. if (paopao_x == 0 && size.width > xMargin) {
  1156. self.paopaoView.beyondLeft = YES;
  1157. }else if ((index + 1) * xMargin + size.width * 0.5 > self.chartScrollView.contentSize.width && size.width > _Xmargin && (index + 1) * xMargin + size.width * 0.5 > self.chartScrollView.frame.size.width){
  1158. self.paopaoView.beyondRight = YES;
  1159. }
  1160. NSArray * colorArray = _paopaoDataColors ? _paopaoDataColors : colorArr;
  1161. UIColor* titleColor = _paopaoTitleColor ? _paopaoTitleColor : [UIColor colorWithHexString:@"0x999999"];
  1162. self.paopaoView.chartContentWidth = self.chartScrollView.contentSize.width;
  1163. NSMutableArray * colorMarray = [NSMutableArray array];
  1164. if (colorArray.count != dataArr.count) {
  1165. for (int s = 0; s < self.leftDataArr.count; s++) {
  1166. NSArray * arr = self.leftDataArr[s];
  1167. if (arr.count > index) {
  1168. [colorMarray addObject:colorArr[s]];
  1169. }
  1170. }
  1171. }else{
  1172. [colorMarray addObjectsFromArray:colorArray];
  1173. }
  1174. if (self.paopaoTitleArray.count > 0) {
  1175. if (self.leftPointArr.copy != 0) {
  1176. NSArray * pointArray = self.leftPointArr[0];
  1177. for (NSArray * arr in self.leftPointArr) {
  1178. if (index < arr.count) {
  1179. pointArray = arr;
  1180. break;
  1181. }
  1182. }
  1183. CGPoint showPoint = [pointArray[index] CGPointValue];
  1184. self.paopaoView.pointX = showPoint.x;
  1185. [self.paopaoView show:dataArr and:self.paopaoTitleArray[index] andTitleColor:titleColor colorArr:colorMarray];
  1186. }
  1187. } else {
  1188. if (self.leftPointArr.count != 0) {
  1189. NSArray * pointArray = self.leftPointArr[0];
  1190. for (NSArray * arr in self.leftPointArr) {
  1191. if (index < arr.count) {
  1192. pointArray = arr;
  1193. break;
  1194. }
  1195. }
  1196. CGPoint showPoint = [pointArray[index] CGPointValue];
  1197. self.paopaoView.pointX = showPoint.x;
  1198. [self.paopaoView show:dataArr and:@"" andTitleColor:titleColor colorArr:colorMarray];
  1199. }
  1200. }
  1201. [self addCircle:index];
  1202. }
  1203. /// 圆圈
  1204. - (void)addCircle:(NSInteger)index{
  1205. for (UIView *circleView in self.charCircleViewArr) {
  1206. [circleView removeFromSuperview];
  1207. }
  1208. NSMutableArray * leftColorArr = [NSMutableArray array];
  1209. switch (_chartViewStyle) {
  1210. case 0:
  1211. for (int i = 0; i < _leftColorStrArr.count; i++) {
  1212. [leftColorArr addObject:_leftColorStrArr[i]];
  1213. }
  1214. [self.charCircleViewArr removeAllObjects];
  1215. [self drawCircle:index arr:self.leftPointArr color:leftColorArr];
  1216. break;
  1217. case 1:
  1218. for (int i = 0; i < _leftColorStrArr.count; i++) {
  1219. [leftColorArr addObject:_leftColorStrArr[i]];
  1220. }
  1221. [self.charCircleViewArr removeAllObjects];
  1222. [self drawCircle:index arr:self.leftPointArr color:leftColorArr];
  1223. break;
  1224. case 2:
  1225. for (int i = 0; i < _leftColorStrArr.count; i++) {
  1226. [leftColorArr addObject:_leftColorStrArr[i]];
  1227. }
  1228. for (int i = 0; i < _rightColorStrArr.count; i++) {
  1229. [leftColorArr addObject:_rightColorStrArr[i]];
  1230. }
  1231. [self.charCircleViewArr removeAllObjects];
  1232. [self drawCircle:index arr:self.leftPointArr color:leftColorArr];
  1233. break;
  1234. default:
  1235. break;
  1236. }
  1237. }
  1238. - (void)drawCircle:(NSInteger)index arr:(NSArray *)pointArr color:(NSArray<UIColor *> *)colors{
  1239. CGFloat pointY = 0;
  1240. for (int i = 0; i<pointArr.count; i++) {
  1241. NSArray *arr = pointArr[i];
  1242. if (arr.count > index){
  1243. CGPoint point = [arr[index] CGPointValue];
  1244. UIView * circleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KCircleRadius1*2, KCircleRadius1*2)];
  1245. circleView.center = point;
  1246. if (i == 0) {
  1247. pointY = point.y;
  1248. }
  1249. if (self.isFloating) {
  1250. if (point.y < pointY) {
  1251. pointY = point.y;
  1252. }
  1253. }else if(i == 0){
  1254. [self.paopaoView drawBoxWithDirection:directionTop];
  1255. }
  1256. circleView.backgroundColor = self.isShowCircleOutWhite ? colors[i] : [UIColor whiteColor];
  1257. circleView.layer.cornerRadius = KCircleRadius1;
  1258. circleView.layer.borderColor = self.isShowCircleOutWhite ? [UIColor whiteColor].CGColor : colors[i].CGColor;
  1259. circleView.layer.borderWidth = 2;
  1260. circleView.layer.masksToBounds = YES;
  1261. self.circleView = circleView;
  1262. [self.chartScrollView addSubview:circleView];
  1263. [self.charCircleViewArr addObject:circleView];
  1264. }else{
  1265. [self.paopaoView drawBoxWithDirection:directionTop];
  1266. }
  1267. }
  1268. if (self.isFloating) {
  1269. if (pointY - CGRectGetHeight(self.paopaoView.frame) - KCircleRadius >= 0) {
  1270. CGRect frame = self.paopaoView.frame;
  1271. frame.origin.y = pointY - CGRectGetHeight(self.paopaoView.frame) - KCircleRadius;
  1272. [self.paopaoView setFrame:frame];
  1273. [self.paopaoView drawBoxWithDirection:directionTop];
  1274. }else{
  1275. CGRect frame = self.paopaoView.frame;
  1276. frame.origin.y = pointY + KCircleRadius;
  1277. [self.paopaoView setFrame:frame];
  1278. [self.paopaoView drawBoxWithDirection:directionBottom];
  1279. }
  1280. }
  1281. [self.chartScrollView bringSubviewToFront:self.paopaoView];
  1282. }
  1283. - (void)drawCircleArr:(NSArray *)pointArr color:(NSArray *)colors{
  1284. for (int i = 0; i<pointArr.count; i++) {
  1285. NSArray *arr = pointArr[i];
  1286. for (int o = 0; o <arr.count; o++) {
  1287. CGPoint point = [arr[o] CGPointValue];
  1288. UIView * circleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KCircleRadius*2, KCircleRadius*2)];
  1289. circleView.center = point;
  1290. UIColor * color = colors[i];
  1291. circleView.backgroundColor = color;
  1292. circleView.layer.cornerRadius = KCircleRadius;
  1293. circleView.layer.borderColor = [UIColor whiteColor].CGColor;
  1294. circleView.layer.borderWidth = 1;
  1295. circleView.layer.masksToBounds = YES;
  1296. [self.chartScrollView addSubview:circleView];
  1297. }
  1298. }
  1299. [self.chartScrollView bringSubviewToFront:self.circleView];
  1300. [self.chartScrollView bringSubviewToFront:self.paopaoView];
  1301. }
  1302. -(void)addLines1With:(UIView *)view{
  1303. CGFloat magrginHeight = (view.bounds.size.height)/ _row;
  1304. Ymargin = magrginHeight;
  1305. CAShapeLayer * dashLayer = [CAShapeLayer layer];
  1306. _dashLayer = dashLayer;
  1307. dashLayer.strokeColor = self.borderLineColor.CGColor;
  1308. dashLayer.fillColor = self.borderTriangleColor.CGColor;
  1309. // 默认设置路径宽度为0,使其在起始状态下不显示
  1310. dashLayer.lineWidth = 0.5;
  1311. UIBezierPath * path = [[UIBezierPath alloc]init];
  1312. path.lineWidth = 1.0;
  1313. [path moveToPoint:CGPointMake(titleWOfY, CGRectGetHeight(_chartScrollView.frame))];
  1314. [path addLineToPoint:CGPointMake(titleWOfY,3)];
  1315. [path addLineToPoint:CGPointMake(titleWOfY + 3,3)];
  1316. [path addLineToPoint:CGPointMake(titleWOfY,0)];
  1317. [path addLineToPoint:CGPointMake(titleWOfY - 3,3)];
  1318. [path addLineToPoint:CGPointMake(titleWOfY,3)];
  1319. [path moveToPoint:CGPointMake(titleWOfY, CGRectGetHeight(_chartScrollView.frame))];
  1320. [path addLineToPoint:CGPointMake(CGRectGetMaxX(_chartScrollView.frame),CGRectGetHeight(_chartScrollView.frame))];
  1321. if (_chartViewStyle == LHYChartViewLeftRightLine) {
  1322. [path moveToPoint:CGPointMake(CGRectGetMaxX(_chartScrollView.frame) + 1, CGRectGetHeight(_chartScrollView.frame))];
  1323. [path addLineToPoint:CGPointMake(CGRectGetMaxX(_chartScrollView.frame) + 1,0)];
  1324. }else{
  1325. [path addLineToPoint:CGPointMake(CGRectGetMaxX(_chartScrollView.frame),CGRectGetHeight(_chartScrollView.frame) - 3)];
  1326. [path addLineToPoint:CGPointMake(CGRectGetMaxX(_chartScrollView.frame) + 3,CGRectGetHeight(_chartScrollView.frame))];
  1327. [path addLineToPoint:CGPointMake(CGRectGetMaxX(_chartScrollView.frame),CGRectGetHeight(_chartScrollView.frame) + 3)];
  1328. [path addLineToPoint:CGPointMake(CGRectGetMaxX(_chartScrollView.frame),CGRectGetHeight(_chartScrollView.frame))];
  1329. }
  1330. dashLayer.path = path.CGPath;
  1331. [self.layer addSublayer:dashLayer];
  1332. }
  1333. @end