| // | 
| //  JHLineChart.m | 
| //  JHChartDemo | 
| // | 
| //  Created by cjatech-简豪 on 16/4/10. | 
| //  Copyright © 2016年 JH. All rights reserved. | 
| // | 
|   | 
| #import "JHLineChart.h" | 
| #define kXandYSpaceForSuperView 20.0 | 
| #define XlineItemMAXCount 8 | 
| #define YlineItemMAXCount 8 | 
|   | 
| @interface JHLineChart () | 
|   | 
| @property (assign, nonatomic)   CGFloat  xLength; | 
| @property (assign , nonatomic)  CGFloat  yLength; | 
| @property (assign , nonatomic)  CGFloat  perXLen ; | 
| @property (assign , nonatomic)  CGFloat  perYlen ; | 
| @property (assign , nonatomic)  CGFloat  perValue ; | 
| @property (nonatomic,strong)    NSMutableArray * drawDataArr; | 
| @property (nonatomic,strong) CAShapeLayer *shapeLayer; | 
| @property (assign , nonatomic) BOOL  isEndAnimation ; | 
| @property (nonatomic,strong) NSMutableArray * layerArr; | 
| @end | 
|   | 
| @implementation JHLineChart | 
|   | 
|   | 
|   | 
| /** | 
|  *  重写初始化方法 | 
|  * | 
|  *  @param frame         frame | 
|  *  @param lineChartType 折线图类型 | 
|  * | 
|  *  @return 自定义折线图 | 
|  */ | 
| -(instancetype)initWithFrame:(CGRect)frame andLineChartType:(JHLineChartType)lineChartType | 
| { | 
|      | 
|     if (self = [super initWithFrame:frame]) { | 
|         self.backgroundColor = [UIColor clearColor]; | 
|         _lineType = lineChartType; | 
|         _lineWidth = 0.5; | 
|         _xyFontSize = 7.0; | 
|         self.contentInsets = UIEdgeInsetsMake(10, 20, 10, 10); | 
|         _yLineDataArr  = @[@"100",@"200",@"300",@"400",@"500",@"600",@"700",@"800"];//[NSMutableArray array]; | 
|         _xLineDataArr  = [NSMutableArray array]; | 
|         _xAndYLineColor = [UIColor darkGrayColor]; | 
|         _pointNumberColorArr = @[[UIColor redColor]]; | 
|         _positionLineColorArr = @[[UIColor darkGrayColor]]; | 
|         _pointColorArr = @[[UIColor orangeColor]]; | 
|         _xAndYNumberColor = [UIColor darkGrayColor]; | 
|         _valueLineColorArr = @[[UIColor redColor]]; | 
|         _layerArr = [NSMutableArray array]; | 
|         _showYLine = YES; | 
|         _showYLevelLine = NO; | 
|         _showValueLeadingLine = YES; | 
|         _contentFillColorArr = @[[UIColor lightGrayColor]]; | 
|         [self configChartXAndYLength]; | 
|         [self configChartOrigin]; | 
|         [self configPerXAndPerY]; | 
| } | 
|     return self; | 
|      | 
| } | 
|   | 
| /** | 
|  *  清除图标内容 | 
|  */ | 
| -(void)clear | 
| { | 
|      | 
|     _valueArr = nil; | 
|     _drawDataArr = nil; | 
|      | 
|     for (CALayer *layer in _layerArr) { | 
|          | 
|         [layer removeFromSuperlayer]; | 
|     } | 
|     [self showAnimation]; | 
|      | 
| } | 
|   | 
| /** | 
|  *  获取每个X或y轴刻度间距 | 
|  */ | 
| - (void)configPerXAndPerY | 
| { | 
|     switch (_lineChartQuadrantType) | 
|     { | 
| //        case JHLineChartQuadrantTypeFirstQuardrant: | 
| //        { | 
| //            _perXLen = (_xLength-kXandYSpaceForSuperView)/(XlineItemMAXCount-1); | 
| //            _perYlen = (_yLength-kXandYSpaceForSuperView)/YlineItemMAXCount; | 
| //        } | 
| //            break; | 
| //        case JHLineChartQuadrantTypeFirstAndSecondQuardrant: | 
| //        { | 
| //            _perXLen = (_xLength/2-kXandYSpaceForSuperView)/XlineItemMAXCount; | 
| //            _perYlen = (_yLength-kXandYSpaceForSuperView)/YlineItemMAXCount; | 
| //        } | 
| //            break; | 
| //        case JHLineChartQuadrantTypeFirstAndFouthQuardrant: | 
| //        { | 
| //            _perXLen = (_xLength-kXandYSpaceForSuperView)/(XlineItemMAXCount-1); | 
| //            _perYlen = (_yLength/2-kXandYSpaceForSuperView)/YlineItemMAXCount; | 
| //        } | 
| //            break; | 
| //        case JHLineChartQuadrantTypeAllQuardrant: | 
| //        { | 
| //            _perXLen = (_xLength/2-kXandYSpaceForSuperView)/(XlineItemMAXCount); | 
| //            _perYlen = (_yLength/2-kXandYSpaceForSuperView)/YlineItemMAXCount; | 
| //        } | 
| //            break; | 
| //             | 
| //        default: | 
| //            break; | 
|   | 
|         case JHLineChartQuadrantTypeFirstQuardrant: | 
|         { | 
|             _perXLen = (_xLength-kXandYSpaceForSuperView)/(_xLineDataArr.count-1); | 
|             _perYlen = (_yLength-kXandYSpaceForSuperView)/_yLineDataArr.count; | 
|         } | 
|             break; | 
|         case JHLineChartQuadrantTypeFirstAndSecondQuardrant: | 
|         { | 
|             _perXLen = (_xLength/2-kXandYSpaceForSuperView)/[_xLineDataArr[0] count]; | 
|             _perYlen = (_yLength-kXandYSpaceForSuperView)/_yLineDataArr.count; | 
|         } | 
|             break; | 
|         case JHLineChartQuadrantTypeFirstAndFouthQuardrant: | 
|         { | 
|             _perXLen = (_xLength-kXandYSpaceForSuperView)/(_xLineDataArr.count-1); | 
|             _perYlen = (_yLength/2-kXandYSpaceForSuperView)/[_yLineDataArr[0] count]; | 
|         } | 
|             break; | 
|         case JHLineChartQuadrantTypeAllQuardrant: | 
|         { | 
|              _perXLen = (_xLength/2-kXandYSpaceForSuperView)/([_xLineDataArr[0] count]); | 
|              _perYlen = (_yLength/2-kXandYSpaceForSuperView)/[_yLineDataArr[0] count]; | 
|         } | 
|             break; | 
|              | 
|         default: | 
|             break; | 
|     } | 
|      | 
| } | 
|   | 
|   | 
| /** | 
|  *  重写LineChartQuardrantType的setter方法 动态改变折线图原点 | 
|  * | 
|  */ | 
| -(void)setLineChartQuadrantType:(JHLineChartQuadrantType)lineChartQuadrantType{ | 
|      | 
|     _lineChartQuadrantType = lineChartQuadrantType; | 
|     [self configChartOrigin]; | 
|      | 
| } | 
|   | 
|   | 
|   | 
| /** | 
|  *  获取X与Y轴的长度 | 
|  */ | 
| - (void)configChartXAndYLength | 
| { | 
|     _xLength = CGRectGetWidth(self.frame)-self.contentInsets.left-self.contentInsets.right; | 
|     _yLength = CGRectGetHeight(self.frame)-self.contentInsets.top-self.contentInsets.bottom; | 
| } | 
|   | 
|   | 
| /** | 
|  *  重写ValueArr的setter方法 赋值时改变Y轴刻度大小 | 
|  * | 
|  */ | 
| -(void)setValueArr:(NSMutableArray *)valueArr | 
| { | 
|      | 
|     _valueArr = valueArr; | 
|      | 
|     [self updateYScale]; | 
|      | 
|      | 
| } | 
|   | 
| -(void)clearLine | 
| { | 
|     for (CALayer *layer in _layerArr) { | 
|          | 
|         [layer removeFromSuperlayer]; | 
|     } | 
|     [self showAnimation]; | 
| } | 
|   | 
| /** | 
|  *  更新Y轴的刻度大小 | 
|  */ | 
| - (void)updateYScale | 
| { | 
|         switch (_lineChartQuadrantType) | 
|     { | 
|         case JHLineChartQuadrantTypeFirstAndFouthQuardrant: | 
|         { | 
|              | 
|             NSInteger max = 0; | 
|             NSInteger min = 0; | 
|              | 
|             for (NSArray *arr in _valueArr) { | 
|                 for (NSString * numer  in arr) { | 
|                     NSInteger i = [numer integerValue]; | 
|                     if (i>=max) { | 
|                         max = i; | 
|                     } | 
|                     if (i<=min) { | 
|                         min = i; | 
|                     } | 
|                 } | 
|                  | 
|             } | 
|              | 
|          min = labs(min); | 
|          max = (min<max?(max):(min)); | 
|         if (max%5==0) { | 
|                 max = max; | 
|             }else | 
|                 max = (max/5+1)*5; | 
|         NSMutableArray *arr = [NSMutableArray array]; | 
|         NSMutableArray *minArr = [NSMutableArray array]; | 
|         if (max<=5) { | 
|             for (NSInteger i = 0; i<5; i++) { | 
|                      | 
|                 [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*1]]; | 
|                 [minArr addObject:[NSString stringWithFormat:@"-%ld",(i+1)*1]]; | 
|                 } | 
|             } | 
|              | 
|         if (max<=10&&max>5) { | 
|                  | 
|                  | 
|             for (NSInteger i = 0; i<5; i++) { | 
|                      | 
|                     [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*2]]; | 
|                 [minArr addObject:[NSString stringWithFormat:@"-%ld",(i+1)*2]]; | 
|   | 
|                 } | 
|                  | 
|         }else if(max>10&&max<=100){ | 
|              | 
|              | 
|             for (NSInteger i = 0; i<max/5; i++) { | 
|                 [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*5]]; | 
|                 [minArr addObject:[NSString stringWithFormat:@"-%ld",(i+1)*5]]; | 
|             } | 
|              | 
|         }else{ | 
|              | 
|             NSInteger count = max / 10; | 
|              | 
|             for (NSInteger i = 0; i<11; i++) { | 
|                 [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*count]]; | 
|                 [minArr addObject:[NSString stringWithFormat:@"-%ld",(i+1)*count]]; | 
|             } | 
|              | 
|         } | 
|   | 
|          | 
|              | 
|             _yLineDataArr = @[[arr copy],[minArr copy]]; | 
|              | 
|              | 
|             [self setNeedsDisplay]; | 
|              | 
|              | 
|         }break; | 
|         case JHLineChartQuadrantTypeAllQuardrant:{ | 
|              | 
|             NSInteger max = 0; | 
|             NSInteger min = 0; | 
|              | 
|              | 
|             for (NSArray *arr in _valueArr) | 
|             { | 
|                 for (NSString * numer  in arr) | 
|                 { | 
|                     NSInteger i = [numer integerValue]; | 
|                     if (i>=max) { | 
|                         max = i; | 
|                     } | 
|                     if (i<=min) { | 
|                         min = i; | 
|                     } | 
|                 } | 
|                  | 
|             } | 
|   | 
|              | 
|             min = labs(min); | 
|             max = (min<max?(max):(min)); | 
|             if (max%5==0) { | 
|                 max = max; | 
|             }else | 
|                 max = (max/5+1)*5; | 
|             NSMutableArray *arr = [NSMutableArray array]; | 
|             NSMutableArray *minArr = [NSMutableArray array]; | 
|             if (max<=5) { | 
|                 for (NSInteger i = 0; i<5; i++) { | 
|                      | 
|                     [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*1]]; | 
|                     [minArr addObject:[NSString stringWithFormat:@"-%ld",(i+1)*1]]; | 
|                 } | 
|             } | 
|              | 
|             if (max<=10&&max>5) { | 
|                  | 
|                  | 
|                 for (NSInteger i = 0; i<5; i++) { | 
|                      | 
|                     [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*2]]; | 
|                     [minArr addObject:[NSString stringWithFormat:@"-%ld",(i+1)*2]]; | 
|                      | 
|                 } | 
|                  | 
|             }else if(max>10&&max<=100){ | 
|                  | 
|                  | 
|                 for (NSInteger i = 0; i<max/5; i++) { | 
|                     [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*5]]; | 
|                     [minArr addObject:[NSString stringWithFormat:@"-%ld",(i+1)*5]]; | 
|                 } | 
|                  | 
|             }else{ | 
|                  | 
|                 NSInteger count = max / 10; | 
|                  | 
|                 for (NSInteger i = 0; i<11; i++) { | 
|                     [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*count]]; | 
|                     [minArr addObject:[NSString stringWithFormat:@"-%ld",(i+1)*count]]; | 
|                 } | 
|                  | 
|             } | 
|   | 
|             _yLineDataArr = @[[arr copy],[minArr copy]]; | 
|              | 
|             [self setNeedsDisplay]; | 
|         }break; | 
|         default:{ | 
|             if (_valueArr.count) { | 
|                  | 
|                 NSInteger max=0; | 
|                  | 
|                 for (NSArray *arr in _valueArr) { | 
|                     for (NSString * numer  in arr) { | 
|                         NSInteger i = [numer integerValue]; | 
|                         if (i>=max) { | 
|                             max = i; | 
|                         } | 
|                          | 
|                     } | 
|                      | 
|                 } | 
|   | 
|                  | 
|                 if (max%5==0) { | 
|                     max = max; | 
|                 }else | 
|                     max = (max/5+1)*5; | 
|                 _yLineDataArr = nil; | 
|                 NSMutableArray *arr = [NSMutableArray array]; | 
|                 if (max<=5) { | 
|                     for (NSInteger i = 0; i<5; i++) { | 
|                          | 
|                         [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*1]]; | 
|                          | 
|                     } | 
|                 } | 
|                  | 
|                 if (max<=10&&max>5) { | 
|                      | 
|                      | 
|                     for (NSInteger i = 0; i<5; i++) { | 
|                          | 
|                         [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*2]]; | 
|                          | 
|                     } | 
|                      | 
|                 }else if(max>10&&max<=50){ | 
|                      | 
|                     for (NSInteger i = 0; i<max/5+1; i++) { | 
|                         [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*5]]; | 
|                          | 
|                          | 
|                     } | 
|                      | 
|                 }else if(max<=100){ | 
|                      | 
|                     for (NSInteger i = 0; i<max/10; i++) { | 
|                         [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*10]]; | 
|                          | 
|                          | 
|                     } | 
|                      | 
|                 }else if(max > 100){ | 
|                      | 
|                     NSInteger count = max / 10; | 
|                      | 
|                     for (NSInteger i = 0; i<10+1; i++) { | 
|                         [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*count]]; | 
|                          | 
|                     } | 
|                 } | 
|   | 
|                  | 
|                 _yLineDataArr = [arr copy]; | 
|                  | 
|                 [self setNeedsDisplay]; | 
|                  | 
|                  | 
|             } | 
|   | 
|         } | 
|             break; | 
|     } | 
|      | 
|      | 
|      | 
| } | 
|   | 
|   | 
| /** | 
|  *  构建折线图原点 | 
|  */ | 
| - (void)configChartOrigin | 
| { | 
|      | 
|     switch (_lineChartQuadrantType) { | 
|         case JHLineChartQuadrantTypeFirstQuardrant: | 
|         { | 
|             self.chartOrigin = CGPointMake(self.contentInsets.left, self.frame.size.height-self.contentInsets.bottom); | 
|         } | 
|             break; | 
|         case JHLineChartQuadrantTypeFirstAndSecondQuardrant: | 
|         { | 
|             self.chartOrigin = CGPointMake(self.contentInsets.left+_xLength/2, CGRectGetHeight(self.frame)-self.contentInsets.bottom); | 
|         } | 
|             break; | 
|         case JHLineChartQuadrantTypeFirstAndFouthQuardrant: | 
|         { | 
|             self.chartOrigin = CGPointMake(self.contentInsets.left, self.contentInsets.top+_yLength/2); | 
|         } | 
|             break; | 
|         case JHLineChartQuadrantTypeAllQuardrant: | 
|         { | 
|              self.chartOrigin = CGPointMake(self.contentInsets.left+_xLength/2, self.contentInsets.top+_yLength/2); | 
|         } | 
|             break; | 
|              | 
|         default: | 
|             break; | 
|     } | 
|      | 
| } | 
|   | 
|   | 
|   | 
|   | 
| /* 绘制x与y轴 */ | 
| - (void)drawXAndYLineWithContext:(CGContextRef)context | 
| { | 
|   | 
|     switch (_lineChartQuadrantType) { | 
|         case JHLineChartQuadrantTypeFirstQuardrant:{ | 
|              | 
|             [self drawLineWithContext:context andStarPoint:self.chartOrigin andEndPoint:P_M(self.contentInsets.left+_xLength, self.chartOrigin.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|             if (_showYLine) | 
|             { | 
|                   [self drawLineWithContext:context andStarPoint:self.chartOrigin andEndPoint:P_M(self.chartOrigin.x,self.chartOrigin.y-_yLength) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|             } | 
|            | 
|             if (_xLineDataArr.count>0) | 
|             { | 
|                 CGFloat xPace = (_xLength-kXandYSpaceForSuperView)/(_xLineDataArr.count-1); | 
|                  | 
|                 for (NSInteger i = 0; i<_xLineDataArr.count;i++ ) | 
|                 { | 
|                     CGPoint p = P_M(i*xPace+self.chartOrigin.x, self.chartOrigin.y); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:_xLineDataArr[i]]; | 
|                     if (_showYLevelLine) | 
|                     { | 
|                         _xLength = CGRectGetWidth(self.frame)-self.contentInsets.left-self.contentInsets.right; | 
|                          | 
|                         [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(self.chartOrigin.x+self.perXLen*i,self.chartOrigin.y-_yLength) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                          | 
|                     } | 
|                     else | 
|                         [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x, p.y-3) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                      | 
|                     [self drawText:[NSString stringWithFormat:@"%@",_xLineDataArr[i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                 } | 
|                | 
|                  | 
|                  | 
|             } | 
|              | 
|             if (_yLineDataArr.count>0) | 
|             { | 
|                 CGFloat yPace = (_yLength - kXandYSpaceForSuperView)/(_yLineDataArr.count); | 
|                 for (NSInteger i = 0; i<_yLineDataArr.count; i++) | 
|                 { | 
|                     CGPoint p = P_M(self.chartOrigin.x, self.chartOrigin.y - (i+1)*yPace); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:_yLineDataArr[i]]; | 
|                     if (_showYLevelLine) | 
|                    { | 
|                          [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(self.contentInsets.left+_xLength, p.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                         | 
|                     } | 
|                     else | 
|                     { | 
|                         [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                     } | 
|                      | 
|                     [self drawText:[NSString stringWithFormat:@"%@",_yLineDataArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-3) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                 } | 
|             } | 
|              | 
|         }break; | 
|         case JHLineChartQuadrantTypeFirstAndSecondQuardrant:{ | 
|             [self drawLineWithContext:context andStarPoint:P_M(self.contentInsets.left, self.chartOrigin.y) andEndPoint:P_M(self.contentInsets.left+_xLength, self.chartOrigin.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|              | 
|             if (_showYLine) { | 
|                  [self drawLineWithContext:context andStarPoint:self.chartOrigin andEndPoint:P_M(self.chartOrigin.x,self.chartOrigin.y-_yLength) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|             } | 
|             | 
|              | 
|              | 
|             if (_xLineDataArr.count == 2) { | 
|                 NSArray * rightArr = _xLineDataArr[1]; | 
|                 NSArray * leftArr = _xLineDataArr[0]; | 
|                  | 
|                 CGFloat xPace = (_xLength/2-kXandYSpaceForSuperView)/(rightArr.count-1); | 
|                  | 
|                 for (NSInteger i = 0; i<rightArr.count;i++ ) { | 
|                     CGPoint p = P_M(i*xPace+self.chartOrigin.x, self.chartOrigin.y); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:rightArr[i]]; | 
|                     [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x, p.y-3) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                      | 
|                     [self drawText:[NSString stringWithFormat:@"%@",rightArr[i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                 } | 
|                  | 
|                 for (NSInteger i = 0; i<leftArr.count;i++ ) { | 
|                     CGPoint p = P_M(self.chartOrigin.x-(i+1)*xPace, self.chartOrigin.y); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:leftArr[i]]; | 
|                      | 
|   | 
|                          | 
|                     [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x, p.y-3) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                          | 
|   | 
|                     [self drawText:[NSString stringWithFormat:@"%@",leftArr[leftArr.count-1-i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                 } | 
|                  | 
|             } | 
|             if (_yLineDataArr.count>0) | 
|             { | 
|                 CGFloat yPace = (_yLength - kXandYSpaceForSuperView)/(_yLineDataArr.count); | 
|                 for (NSInteger i = 0; i<_yLineDataArr.count; i++) { | 
|                     CGPoint p = P_M(self.chartOrigin.x, self.chartOrigin.y - (i+1)*yPace); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:_yLineDataArr[i]]; | 
|                     if (_showYLevelLine) { | 
|                          [self drawLineWithContext:context andStarPoint:P_M(self.contentInsets.left, p.y) andEndPoint:P_M(self.contentInsets.left+_xLength, p.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                     }else | 
|                         [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                     [self drawText:[NSString stringWithFormat:@"%@",_yLineDataArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-3) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                 } | 
|             } | 
|   | 
|         }break; | 
|         case JHLineChartQuadrantTypeFirstAndFouthQuardrant:{ | 
|             [self drawLineWithContext:context andStarPoint:self.chartOrigin andEndPoint:P_M(self.contentInsets.left+_xLength, self.chartOrigin.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|              | 
|             if (_showYLine) { | 
|                 [self drawLineWithContext:context andStarPoint:P_M(self.contentInsets.left,CGRectGetHeight(self.frame)-self.contentInsets.bottom) andEndPoint:P_M(self.chartOrigin.x,self.contentInsets.top) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|             } | 
|              | 
|             if (_xLineDataArr.count>0) { | 
|                 CGFloat xPace = (_xLength-kXandYSpaceForSuperView)/(_xLineDataArr.count-1); | 
|                  | 
|                 for (NSInteger i = 0; i<_xLineDataArr.count;i++ ) { | 
|                     CGPoint p = P_M(i*xPace+self.chartOrigin.x, self.chartOrigin.y); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:_xLineDataArr[i]]; | 
|                     [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x, p.y-3) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                      | 
|                     if (i==0) { | 
|                         len = -2; | 
|                     } | 
|                      | 
|                     [self drawText:[NSString stringWithFormat:@"%@",_xLineDataArr[i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                 } | 
|             } | 
|              | 
|             if (_yLineDataArr.count == 2) { | 
|                  | 
|                 NSArray * topArr = _yLineDataArr[0]; | 
|                 NSArray * bottomArr = _yLineDataArr[1]; | 
|                 CGFloat yPace = (_yLength/2 - kXandYSpaceForSuperView)/([_yLineDataArr[0] count]); | 
|                 _perYlen = yPace; | 
|                 for (NSInteger i = 0; i<topArr.count; i++) { | 
|                     CGPoint p = P_M(self.chartOrigin.x, self.chartOrigin.y - (i+1)*yPace); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:topArr[i]]; | 
|                     if (_showYLevelLine) { | 
|                          [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(self.contentInsets.left+_xLength, p.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                     }else | 
|                         [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                     [self drawText:[NSString stringWithFormat:@"%@",topArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-3) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                      | 
|                 } | 
|                  | 
|                  | 
|                 for (NSInteger i = 0; i<bottomArr.count; i++) { | 
|                     CGPoint p = P_M(self.chartOrigin.x, self.chartOrigin.y + (i+1)*yPace); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:bottomArr[i]]; | 
|                      | 
|                     if (_showYLevelLine) { | 
|                          [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(self.contentInsets.left+_xLength, p.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                     }else{ | 
|                      | 
|                         [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                     } | 
|                     [self drawText:[NSString stringWithFormat:@"%@",bottomArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-3) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                 } | 
|                  | 
|                  | 
|             } | 
|   | 
|         }break; | 
|         case JHLineChartQuadrantTypeAllQuardrant:{ | 
|             [self drawLineWithContext:context andStarPoint:P_M(self.chartOrigin.x-_xLength/2, self.chartOrigin.y) andEndPoint:P_M(self.chartOrigin.x+_xLength/2, self.chartOrigin.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|              | 
|             if (_showYLine) { | 
|                 [self drawLineWithContext:context andStarPoint:P_M(self.chartOrigin.x,self.chartOrigin.y+_yLength/2) andEndPoint:P_M(self.chartOrigin.x,self.chartOrigin.y-_yLength/2) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|             } | 
|              | 
|              | 
|              | 
|             if (_xLineDataArr.count == 2) { | 
|                 NSArray * rightArr = _xLineDataArr[1]; | 
|                 NSArray * leftArr = _xLineDataArr[0]; | 
|                  | 
|                 CGFloat xPace = (_xLength/2-kXandYSpaceForSuperView)/(rightArr.count-1); | 
|                  | 
|                 for (NSInteger i = 0; i<rightArr.count;i++ ) { | 
|                     CGPoint p = P_M(i*xPace+self.chartOrigin.x, self.chartOrigin.y); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:rightArr[i]]; | 
|                     [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x, p.y-3) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                      | 
|                     [self drawText:[NSString stringWithFormat:@"%@",rightArr[i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                 } | 
|                 for (NSInteger i = 0; i<leftArr.count;i++ ) { | 
|                     CGPoint p = P_M(self.chartOrigin.x-(i+1)*xPace, self.chartOrigin.y); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:leftArr[i]]; | 
|                     [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x, p.y-3) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                      | 
|                     [self drawText:[NSString stringWithFormat:@"%@",leftArr[leftArr.count-1-i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                 } | 
|                  | 
|             } | 
|   | 
|              | 
|             if (_yLineDataArr.count == 2) { | 
|                  | 
|                 NSArray * topArr = _yLineDataArr[0]; | 
|                 NSArray * bottomArr = _yLineDataArr[1]; | 
|                 CGFloat yPace = (_yLength/2 - kXandYSpaceForSuperView)/([_yLineDataArr[0] count]); | 
|                 _perYlen = yPace; | 
|                 for (NSInteger i = 0; i<topArr.count; i++) { | 
|                     CGPoint p = P_M(self.chartOrigin.x, self.chartOrigin.y - (i+1)*yPace); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:topArr[i]]; | 
|                     [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                     [self drawText:[NSString stringWithFormat:@"%@",topArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-3) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                      | 
|                 } | 
|                  | 
|                  | 
|                 for (NSInteger i = 0; i<bottomArr.count; i++) { | 
|                     CGPoint p = P_M(self.chartOrigin.x, self.chartOrigin.y + (i+1)*yPace); | 
|                     CGFloat len = [self getTextWithWhenDrawWithText:bottomArr[i]]; | 
|                     [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:_xAndYLineColor]; | 
|                     [self drawText:[NSString stringWithFormat:@"%@",bottomArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-3) WithColor:_xAndYNumberColor andFontSize:_xyFontSize]; | 
|                 } | 
|                  | 
|                  | 
|             } | 
|              | 
|         }break; | 
|              | 
|         default: | 
|             break; | 
|     } | 
|      | 
|   | 
| } | 
|   | 
| /** | 
|  *  动画展示路径 | 
|  */ | 
| -(void)showAnimation | 
| { | 
|     [self configPerXAndPerY]; | 
|     [self configValueDataArray]; | 
|     [self drawAnimation]; | 
| } | 
|   | 
|   | 
| - (void)drawRect:(CGRect)rect | 
| { | 
|      | 
|      | 
|     CGContextRef context = UIGraphicsGetCurrentContext(); | 
|      | 
|     [self drawXAndYLineWithContext:context]; | 
|      | 
|      | 
|     if (!_isEndAnimation) { | 
|         return; | 
|     } | 
|      | 
|     if (_drawDataArr.count) { | 
|         [self drawPositionLineWithContext:context]; | 
|     } | 
|      | 
| } | 
|   | 
|   | 
|   | 
| /** | 
|  *  装换值数组为点数组 | 
|  */ | 
| - (void)configValueDataArray | 
| { | 
|     _drawDataArr = [NSMutableArray array]; | 
|      | 
|     if (_valueArr.count==0) { | 
|         return; | 
|     } | 
|      | 
|     switch (_lineChartQuadrantType) | 
|     { | 
|         case JHLineChartQuadrantTypeFirstQuardrant: | 
|         { | 
|             _perValue = _perYlen/[[_yLineDataArr firstObject] floatValue]; | 
|              | 
|             // 多条曲线绘制 | 
|             for (NSArray *valueArr in _valueArr) | 
|             { | 
|                 NSMutableArray *dataMArr = [NSMutableArray array]; | 
|                 for (NSInteger i = 0; i < valueArr.count; i++) | 
|                 { | 
|                      | 
|                     CGPoint p = P_M(i*_perXLen+self.chartOrigin.x,self.contentInsets.top + _yLength - [valueArr[i] floatValue]*_perValue); | 
|                     NSValue *value = [NSValue valueWithCGPoint:p]; | 
|                     [dataMArr addObject:value]; | 
|                 } | 
|                 [_drawDataArr addObject:[dataMArr copy]]; | 
|                  | 
|             } | 
|              | 
| //            // 单条曲线绘制 | 
| //            NSMutableArray *dataMArr = [NSMutableArray array]; | 
| //            for (NSInteger i = 0; i < _valueArr.count; i++) | 
| //            { | 
| //                NSString * valueStr = [_valueArr objectAtIndex:i]; | 
| //                CGPoint p = P_M(i*_perXLen+self.chartOrigin.x,self.contentInsets.top + _yLength - [valueStr floatValue]*_perValue); | 
| //                NSValue *value = [NSValue valueWithCGPoint:p]; | 
| //                [dataMArr addObject:value]; | 
| //            } | 
| //             | 
| //            [_drawDataArr addObject:[dataMArr copy]]; | 
|              | 
|         }break; | 
|         case JHLineChartQuadrantTypeFirstAndSecondQuardrant:{ | 
|              | 
|             _perValue = _perYlen/[[_yLineDataArr firstObject] floatValue]; | 
|              | 
|              | 
|              | 
|             for (NSArray *valueArr in _valueArr) { | 
|                 NSMutableArray *dataMArr = [NSMutableArray array]; | 
|                | 
|                      | 
|                     CGPoint p ; | 
|                     for (NSInteger i = 0; i<[_xLineDataArr[0] count]; i++) { | 
|                         p = P_M(self.contentInsets.left + kXandYSpaceForSuperView+i*_perXLen, self.contentInsets.top + _yLength - [valueArr[i] floatValue]*_perValue); | 
|                         [dataMArr addObject:[NSValue valueWithCGPoint:p]]; | 
|                     } | 
|                      | 
|                     for (NSInteger i = 0; i<[_xLineDataArr[1] count]; i++) { | 
|                         p = P_M(self.chartOrigin.x+i*_perXLen, self.contentInsets.top + _yLength - [valueArr[i+[_xLineDataArr[0] count]] floatValue]*_perValue); | 
|                         [dataMArr addObject:[NSValue valueWithCGPoint:p]]; | 
|                          | 
|                     } | 
|                      | 
|                      | 
|                 | 
|                 [_drawDataArr addObject:[dataMArr copy]]; | 
|                  | 
|             } | 
|   | 
|   | 
|              | 
|              | 
|         }break; | 
|         case JHLineChartQuadrantTypeFirstAndFouthQuardrant:{ | 
|             _perValue = _perYlen/[[_yLineDataArr[0] firstObject] floatValue]; | 
|             for (NSArray *valueArr in _valueArr) { | 
|                 NSMutableArray *dataMArr = [NSMutableArray array]; | 
|                 for (NSInteger i = 0; i<valueArr.count; i++) { | 
|                      | 
|                     CGPoint p = P_M(i*_perXLen+self.chartOrigin.x,self.chartOrigin.y - [valueArr[i] floatValue]*_perValue); | 
|                     NSValue *value = [NSValue valueWithCGPoint:p]; | 
|                     [dataMArr addObject:value]; | 
|                 } | 
|                 [_drawDataArr addObject:[dataMArr copy]]; | 
|                  | 
|             } | 
|              | 
|         }break; | 
|         case JHLineChartQuadrantTypeAllQuardrant:{ | 
|              | 
|              | 
|              | 
|             _perValue = _perYlen/[[_yLineDataArr[0] firstObject] floatValue]; | 
|             for (NSArray *valueArr in _valueArr) { | 
|                 NSMutableArray *dataMArr = [NSMutableArray array]; | 
|               | 
|                      | 
|                     CGPoint p ; | 
|                     for (NSInteger i = 0; i<[_xLineDataArr[0] count]; i++) { | 
|                         p = P_M(self.contentInsets.left + kXandYSpaceForSuperView+i*_perXLen, self.chartOrigin.y-[valueArr[i] floatValue]*_perValue); | 
|                         [dataMArr addObject:[NSValue valueWithCGPoint:p]]; | 
|                     } | 
|                      | 
|                     for (NSInteger i = 0; i<[_xLineDataArr[1] count]; i++) { | 
|                         p = P_M(self.chartOrigin.x+i*_perXLen, self.chartOrigin.y-[valueArr[i+[_xLineDataArr[0] count]] floatValue]*_perValue); | 
|                         [dataMArr addObject:[NSValue valueWithCGPoint:p]]; | 
|                          | 
|                     } | 
|                      | 
|                      | 
|             | 
|                 [_drawDataArr addObject:[dataMArr copy]]; | 
|                  | 
|             } | 
|   | 
|         }break; | 
|         default: | 
|             break; | 
|     } | 
|   | 
|   | 
|   | 
| } | 
|   | 
|   | 
| //执行动画 | 
| - (void)drawAnimation | 
| { | 
|      | 
|     [_shapeLayer removeFromSuperlayer]; | 
|     _shapeLayer = [CAShapeLayer layer]; | 
|      | 
|     if (_drawDataArr.count==0) | 
|     { | 
|         return; | 
|     } | 
|      | 
|     //第一、UIBezierPath绘制线段 | 
|     [self configPerXAndPerY]; | 
|   | 
|      | 
|     for (NSInteger i = 0;i<_drawDataArr.count;i++) | 
|     { | 
|          | 
|         NSArray *dataArr = _drawDataArr[i]; | 
|          | 
|         [self drawPathWithDataArr:dataArr andIndex:i]; | 
|          | 
|     } | 
|      | 
|   | 
|      | 
| } | 
|   | 
|   | 
| - (CGPoint)centerOfFirstPoint:(CGPoint)p1 andSecondPoint:(CGPoint)p2{ | 
|      | 
|      | 
|     return P_M((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0); | 
|      | 
| } | 
|   | 
|   | 
|   | 
| - (void)drawPathWithDataArr:(NSArray *)dataArr andIndex:(NSInteger )colorIndex | 
| { | 
|      | 
|     UIBezierPath *firstPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 0, 0)]; | 
|      | 
|     UIBezierPath *secondPath = [UIBezierPath bezierPath]; | 
|      | 
|     for (NSInteger i = 0; i<dataArr.count; i++) | 
|     { | 
|          | 
|         NSValue *value = dataArr[i]; | 
|          | 
|         CGPoint p = value.CGPointValue; | 
|          | 
|         if (_pathCurve) | 
|         { | 
|             if (i==0) { | 
|                  | 
|                 if (_contentFill) | 
|                 { | 
|   | 
|                     [secondPath moveToPoint:P_M(p.x, self.chartOrigin.y)]; | 
|                     [secondPath addLineToPoint:p]; | 
|                 } | 
|   | 
|                 [firstPath moveToPoint:p]; | 
|             } | 
|             else | 
|             { | 
|                 CGPoint nextP = [dataArr[i-1] CGPointValue]; | 
|                 CGPoint control1 = P_M(p.x + (nextP.x - p.x) / 2.0, nextP.y ); | 
|                 CGPoint control2 = P_M(p.x + (nextP.x - p.x) / 2.0, p.y); | 
|                  [secondPath addCurveToPoint:p controlPoint1:control1 controlPoint2:control2]; | 
|                 [firstPath addCurveToPoint:p controlPoint1:control1 controlPoint2:control2]; | 
|             } | 
|         } | 
|         else | 
|         { | 
|              | 
|               if (i==0) | 
|               { | 
|                   if (_contentFill) { | 
|                       [secondPath moveToPoint:P_M(p.x, self.chartOrigin.y)]; | 
|                       [secondPath addLineToPoint:p]; | 
|                   } | 
|                   [firstPath moveToPoint:p]; | 
| //                   [secondPath moveToPoint:p]; | 
|               } | 
|               else | 
|               { | 
|                    [firstPath addLineToPoint:p]; | 
|                    [secondPath addLineToPoint:p]; | 
|             } | 
|   | 
|         } | 
|   | 
|         if (i==dataArr.count-1) { | 
|              | 
|             [secondPath addLineToPoint:P_M(p.x, self.chartOrigin.y)]; | 
|              | 
|         } | 
|     } | 
|      | 
|      | 
|      | 
|     if (_contentFill) | 
|     { | 
|         [secondPath closePath]; | 
|     } | 
|      | 
|     //第二、UIBezierPath和CAShapeLayer关联 | 
|      | 
|      | 
|     CAShapeLayer *shapeLayer = [CAShapeLayer layer]; | 
|     shapeLayer.frame = self.bounds; | 
|     shapeLayer.path = firstPath.CGPath; | 
|     UIColor *color = (_valueLineColorArr.count==_drawDataArr.count?(_valueLineColorArr[colorIndex]):([UIColor orangeColor])); | 
|     shapeLayer.strokeColor = color.CGColor; | 
|     shapeLayer.fillColor = [UIColor clearColor].CGColor; | 
|     shapeLayer.lineWidth = _lineWidth;//(_animationPathWidth<=0?2:_animationPathWidth); | 
|      | 
|     //第三,动画 | 
|      | 
|     CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))]; | 
|      | 
|     ani.fromValue = @0; | 
|      | 
|     ani.toValue = @1; | 
|      | 
|     ani.duration = 0.0; | 
|      | 
|     ani.delegate = self; | 
|      | 
|     ani.speed = 6.0; | 
|      | 
|     [shapeLayer addAnimation:ani forKey:NSStringFromSelector(@selector(strokeEnd))]; | 
|      | 
|     [self.layer addSublayer:shapeLayer]; | 
|     [_layerArr addObject:shapeLayer]; | 
|      | 
|      | 
|     CAShapeLayer *shaperLay = [CAShapeLayer layer]; | 
|     shaperLay.frame = self.bounds; | 
|     shaperLay.path = secondPath.CGPath; | 
|     if (self.contentFillColorArr.count == self.drawDataArr.count) { | 
|          | 
|         shaperLay.fillColor = [self.contentFillColorArr[colorIndex] CGColor]; | 
|     }else{ | 
|         shaperLay.fillColor = [UIColor clearColor].CGColor; | 
|     } | 
|      | 
|     [self.layer addSublayer:shaperLay]; | 
|     [_layerArr addObject:shaperLay]; | 
|     | 
| // delete | 
| //    weakSelf(weakSelf) | 
| //    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(ani.duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | 
| //         | 
| //        CAShapeLayer *shaperLay = [CAShapeLayer layer]; | 
| //        shaperLay.frame = weakself.bounds; | 
| //        shaperLay.path = secondPath.CGPath; | 
| //        if (weakself.contentFillColorArr.count == weakself.drawDataArr.count) { | 
| //             | 
| //            shaperLay.fillColor = [weakself.contentFillColorArr[colorIndex] CGColor]; | 
| //        }else{ | 
| //            shaperLay.fillColor = [UIColor clearColor].CGColor; | 
| //        } | 
| //         | 
| //        [weakself.layer addSublayer:shaperLay]; | 
| //        [_layerArr addObject:shaperLay]; | 
| //    }); | 
|      | 
|      | 
| } | 
|   | 
|   | 
|   | 
| /** | 
|  *  设置点的引导虚线 | 
|  * | 
|  *  @param context 图形面板上下文 | 
|  */ | 
| - (void)drawPositionLineWithContext:(CGContextRef)context{ | 
|      | 
|     if (_drawDataArr.count==0) { | 
|         return; | 
|     } | 
|      | 
|      | 
|     for (NSInteger m = 0;m<_valueArr.count;m++) { | 
|         NSArray *arr = _drawDataArr[m]; | 
|          | 
|         for (NSInteger i = 0 ;i<arr.count;i++ ) { | 
|              | 
|             CGPoint p = [arr[i] CGPointValue]; | 
|             UIColor *positionLineColor; | 
|             if (_positionLineColorArr.count == _valueArr.count) { | 
|                 positionLineColor = _positionLineColorArr[m]; | 
|             }else | 
|                 positionLineColor = [UIColor orangeColor]; | 
|   | 
|              | 
|             if (_showValueLeadingLine) { | 
|                 [self drawLineWithContext:context andStarPoint:P_M(self.chartOrigin.x, p.y) andEndPoint:p andIsDottedLine:YES andColor:positionLineColor]; | 
|                 [self drawLineWithContext:context andStarPoint:P_M(p.x, self.chartOrigin.y) andEndPoint:p andIsDottedLine:YES andColor:positionLineColor]; | 
|             } | 
|            | 
|              | 
|             if (p.y!=0) | 
|             { | 
|                 UIColor *pointNumberColor = (_pointNumberColorArr.count == _valueArr.count?(_pointNumberColorArr[m]):([UIColor orangeColor])); | 
|                  | 
|                 switch (_lineChartQuadrantType) { | 
|                         | 
|                          | 
|                     case JHLineChartQuadrantTypeFirstQuardrant: | 
|                     { | 
|                         //NSString *aimStr = [NSString stringWithFormat:@"(%@,%@)",_xLineDataArr[i],_valueArr[m][i]]; | 
|                         NSString *aimStr = [NSString stringWithFormat:@"%@",_valueArr[m][i]]; | 
|   | 
|                         CGFloat length = [self sizeOfStringWithMaxSize:CGSizeMake(100, 25) textFont:7.0 aimString:aimStr].width; | 
|                         [self drawText:aimStr andContext:context atPoint:P_M(p.x - length / 2, p.y - 10) WithColor:pointNumberColor andFontSize:7.0]; | 
|                     } | 
|                         break; | 
|                     case JHLineChartQuadrantTypeFirstAndSecondQuardrant: | 
|                     { | 
|                         NSString *str = (i<[_xLineDataArr[0] count]?(_xLineDataArr[0][i]):(_xLineDataArr[1][i-[_xLineDataArr[0] count]])); | 
|                          | 
|                         //NSString *aimStr = [NSString stringWithFormat:@"(%@,%@)",str,_valueArr[m][i]]; | 
|                         NSString *aimStr = [NSString stringWithFormat:@"%@",_valueArr[m][i]]; | 
|   | 
|                         CGFloat length = [self sizeOfStringWithMaxSize:CGSizeMake(100, 25) textFont:7.0 aimString:aimStr].width; | 
|                          | 
|                         [self drawText:aimStr andContext:context atPoint:P_M(p.x - length / 2, p.y - 10) WithColor:pointNumberColor andFontSize:7.0]; | 
|                     } | 
|                         break; | 
|                     case JHLineChartQuadrantTypeFirstAndFouthQuardrant: | 
|                     { | 
|                         //NSString *aimStr = [NSString stringWithFormat:@"(%@,%@)",_xLineDataArr[i],_valueArr[m][i]]; | 
|                         NSString *aimStr = [NSString stringWithFormat:@"%@",_valueArr[m][i]]; | 
|   | 
|                         CGFloat length = [self sizeOfStringWithMaxSize:CGSizeMake(100, 25) textFont:7.0 aimString:aimStr].width; | 
|                         [self drawText:aimStr andContext:context atPoint:P_M(p.x - length / 2, p.y - 10) WithColor:pointNumberColor andFontSize:7.0]; | 
|                     } | 
|                         break; | 
|                     case JHLineChartQuadrantTypeAllQuardrant: | 
|                     { | 
|                         NSString *str = (i<[_xLineDataArr[0] count]?(_xLineDataArr[0][i]):(_xLineDataArr[1][i-[_xLineDataArr[0] count]])); | 
|                          | 
|                         //NSString *aimStr =[NSString stringWithFormat:@"(%@,%@)",str,_valueArr[m][i]]; | 
|                         NSString *aimStr =[NSString stringWithFormat:@"%@",_valueArr[m][i]]; | 
|   | 
|                         CGFloat length = [self sizeOfStringWithMaxSize:CGSizeMake(100, 25) textFont:7.0 aimString:aimStr].width; | 
|                          | 
|                         [self drawText:aimStr andContext:context atPoint:P_M(p.x - length / 2, p.y - 10) WithColor:pointNumberColor andFontSize:7.0]; | 
|                     } | 
|                         break; | 
|                          | 
|                     default: | 
|                         break; | 
|                 } | 
|                  | 
|             } | 
|              | 
|              | 
|         } | 
|     } | 
|      | 
|      _isEndAnimation = NO; | 
|      | 
|      | 
| } | 
|   | 
|   | 
|   | 
|   | 
|   | 
| -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ | 
|      | 
|     if (flag) | 
|     { | 
|         [self drawPoint]; | 
|     } | 
|      | 
| } | 
|   | 
| /** | 
|  *  绘制值的点 | 
|  */ | 
| - (void)drawPoint | 
| { | 
|      | 
|     for (NSInteger m = 0;m<_drawDataArr.count;m++) | 
|     { | 
|          | 
|         NSArray *arr = _drawDataArr[m]; | 
|         for (NSInteger i = 0; i<arr.count; i++) | 
|         { | 
|              | 
|             NSValue *value = arr[i]; | 
|              | 
|             CGPoint p = value.CGPointValue; | 
|              | 
|              | 
|             UIBezierPath *pBezier = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 5, 5)]; | 
|             [pBezier moveToPoint:p]; | 
|             //            [pBezier addArcWithCenter:p radius:13 startAngle:0 endAngle:M_PI*2 clockwise:YES]; | 
|              | 
|             CAShapeLayer *pLayer = [CAShapeLayer layer]; | 
|             pLayer.frame = CGRectMake(0, 0, 5, 5); | 
|             pLayer.position = p; | 
|             pLayer.path = pBezier.CGPath; | 
|              | 
|             UIColor *color = _pointColorArr.count==_drawDataArr.count?(_pointColorArr[m]):([UIColor orangeColor]); | 
|              | 
|             pLayer.fillColor = color.CGColor; | 
|              | 
|             CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))]; | 
|              | 
|             ani.fromValue = @0; | 
|              | 
|             ani.toValue = @1; | 
|              | 
|             ani.duration = 0.0; | 
|              | 
|             ani.speed = 6.0; | 
|              | 
|             [pLayer addAnimation:ani forKey:NSStringFromSelector(@selector(strokeEnd))]; | 
|              | 
|             [self.layer addSublayer:pLayer]; | 
|             [_layerArr addObject:pLayer]; | 
|              | 
|              | 
|         } | 
|          | 
|         _isEndAnimation = YES; | 
|          | 
|         [self setNeedsDisplay]; | 
|     } | 
| } | 
|   | 
|   | 
|   | 
|   | 
|   | 
|   | 
| @end |