Merge pull request #194 from KerryJava/master
add grade displayed above the chart
Showing
3 changed files
with
144 additions
and
1 deletions
| @@ -20,4 +20,8 @@ | @@ -20,4 +20,8 @@ | ||
| 20 | @property (nonatomic) CGFloat barRadius; | 20 | @property (nonatomic) CGFloat barRadius; |
| 21 | @property (nonatomic) CAShapeLayer *gradientMask; | 21 | @property (nonatomic) CAShapeLayer *gradientMask; |
| 22 | 22 | ||
| 23 | +@property (nonatomic) CAShapeLayer *gradeLayer; | ||
| 24 | +@property (nonatomic) CATextLayer* textLayer; | ||
| 25 | + | ||
| 26 | + | ||
| 23 | @end | 27 | @end |
| @@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
| 8 | 8 | ||
| 9 | #import "PNBar.h" | 9 | #import "PNBar.h" |
| 10 | #import "PNColor.h" | 10 | #import "PNColor.h" |
| 11 | +#import <CoreText/CoreText.h> | ||
| 11 | 12 | ||
| 12 | @implementation PNBar | 13 | @implementation PNBar |
| 13 | 14 | ||
| @@ -39,11 +40,13 @@ | @@ -39,11 +40,13 @@ | ||
| 39 | - (void)setGrade:(float)grade | 40 | - (void)setGrade:(float)grade |
| 40 | { | 41 | { |
| 41 | NSLog(@"New garde %f",grade); | 42 | NSLog(@"New garde %f",grade); |
| 43 | + | ||
| 44 | + CGFloat startPosY = (1 - grade) * self.frame.size.height; | ||
| 42 | 45 | ||
| 43 | UIBezierPath *progressline = [UIBezierPath bezierPath]; | 46 | UIBezierPath *progressline = [UIBezierPath bezierPath]; |
| 44 | 47 | ||
| 45 | [progressline moveToPoint:CGPointMake(self.frame.size.width / 2.0, self.frame.size.height)]; | 48 | [progressline moveToPoint:CGPointMake(self.frame.size.width / 2.0, self.frame.size.height)]; |
| 46 | - [progressline addLineToPoint:CGPointMake(self.frame.size.width / 2.0, (1 - grade) * self.frame.size.height)]; | 49 | + [progressline addLineToPoint:CGPointMake(self.frame.size.width / 2.0, startPosY)]; |
| 47 | 50 | ||
| 48 | [progressline setLineWidth:1.0]; | 51 | [progressline setLineWidth:1.0]; |
| 49 | [progressline setLineCapStyle:kCGLineCapSquare]; | 52 | [progressline setLineCapStyle:kCGLineCapSquare]; |
| @@ -73,6 +76,12 @@ | @@ -73,6 +76,12 @@ | ||
| 73 | // Add gradient | 76 | // Add gradient |
| 74 | [self.gradientMask addAnimation:pathAnimation forKey:@"animationKey"]; | 77 | [self.gradientMask addAnimation:pathAnimation forKey:@"animationKey"]; |
| 75 | self.gradientMask.path = progressline.CGPath; | 78 | self.gradientMask.path = progressline.CGPath; |
| 79 | + | ||
| 80 | + // add text | ||
| 81 | + [self setGradeFrame:grade startPosY:startPosY]; | ||
| 82 | + CABasicAnimation* opacityAnimation = [self fadeAnimation]; | ||
| 83 | + [self.textLayer addAnimation:opacityAnimation forKey:nil]; | ||
| 84 | + | ||
| 76 | } | 85 | } |
| 77 | 86 | ||
| 78 | }else{ | 87 | }else{ |
| @@ -115,6 +124,11 @@ | @@ -115,6 +124,11 @@ | ||
| 115 | 124 | ||
| 116 | self.gradientMask.strokeEnd = 1.0; | 125 | self.gradientMask.strokeEnd = 1.0; |
| 117 | [self.gradientMask addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; | 126 | [self.gradientMask addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; |
| 127 | + | ||
| 128 | + //set grade | ||
| 129 | + [self setGradeFrame:grade startPosY:startPosY]; | ||
| 130 | + CABasicAnimation* opacityAnimation = [self fadeAnimation]; | ||
| 131 | + [self.textLayer addAnimation:opacityAnimation forKey:nil]; | ||
| 118 | } | 132 | } |
| 119 | } | 133 | } |
| 120 | 134 | ||
| @@ -153,4 +167,55 @@ | @@ -153,4 +167,55 @@ | ||
| 153 | } | 167 | } |
| 154 | 168 | ||
| 155 | 169 | ||
| 170 | +// add number display on the top of bar | ||
| 171 | +-(CGPathRef)gradePath:(CGRect)rect | ||
| 172 | +{ | ||
| 173 | + return nil; | ||
| 174 | +} | ||
| 175 | + | ||
| 176 | +-(CATextLayer*)textLayer | ||
| 177 | +{ | ||
| 178 | + if (!_textLayer) { | ||
| 179 | + _textLayer = [[CATextLayer alloc]init]; | ||
| 180 | + [_textLayer setString:@"0"]; | ||
| 181 | + [_textLayer setAlignmentMode:kCAAlignmentCenter]; | ||
| 182 | + [_textLayer setForegroundColor:[[UIColor blackColor] CGColor]]; | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + return _textLayer; | ||
| 186 | +} | ||
| 187 | + | ||
| 188 | +-(void)setGradeFrame:(CGFloat)grade startPosY:(CGFloat)startPosY | ||
| 189 | +{ | ||
| 190 | + CGFloat textheigt = self.bounds.size.width; | ||
| 191 | + CGFloat textWidth = self.bounds.size.width; | ||
| 192 | + CGFloat textStartPosY; | ||
| 193 | + | ||
| 194 | + | ||
| 195 | + if (startPosY < textheigt) { | ||
| 196 | + textStartPosY = startPosY; | ||
| 197 | + } | ||
| 198 | + else { | ||
| 199 | + textStartPosY = startPosY - textheigt; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + [_chartLine addSublayer:self.textLayer]; | ||
| 203 | + [self.textLayer setFontSize:textheigt/2]; | ||
| 204 | + | ||
| 205 | + [self.textLayer setString:[[NSString alloc]initWithFormat:@"%ld",(NSInteger)(grade*100)]]; | ||
| 206 | + [self.textLayer setFrame:CGRectMake(0, textStartPosY, textWidth, textheigt)]; | ||
| 207 | + self.textLayer.contentsScale = [UIScreen mainScreen].scale; | ||
| 208 | + | ||
| 209 | +} | ||
| 210 | + | ||
| 211 | +-(CABasicAnimation*)fadeAnimation | ||
| 212 | +{ | ||
| 213 | + CABasicAnimation* fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; | ||
| 214 | + fadeAnimation.fromValue = [NSNumber numberWithFloat:0.0]; | ||
| 215 | + fadeAnimation.toValue = [NSNumber numberWithFloat:1.0]; | ||
| 216 | + fadeAnimation.duration = 2.0; | ||
| 217 | + | ||
| 218 | + return fadeAnimation; | ||
| 219 | +} | ||
| 220 | + | ||
| 156 | @end | 221 | @end |
| @@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||
| 11 | #import "PNChartLabel.h" | 11 | #import "PNChartLabel.h" |
| 12 | #import "PNLineChartData.h" | 12 | #import "PNLineChartData.h" |
| 13 | #import "PNLineChartDataItem.h" | 13 | #import "PNLineChartDataItem.h" |
| 14 | +#import <CoreText/CoreText.h> | ||
| 14 | 15 | ||
| 15 | @interface PNLineChart () | 16 | @interface PNLineChart () |
| 16 | 17 | ||
| @@ -21,6 +22,9 @@ | @@ -21,6 +22,9 @@ | ||
| 21 | @property (nonatomic) NSMutableArray *pointPath; // Array of point path, one for each line | 22 | @property (nonatomic) NSMutableArray *pointPath; // Array of point path, one for each line |
| 22 | @property (nonatomic) NSMutableArray *endPointsOfPath; // Array of start and end points of each line path, one for each line | 23 | @property (nonatomic) NSMutableArray *endPointsOfPath; // Array of start and end points of each line path, one for each line |
| 23 | 24 | ||
| 25 | +// display grade | ||
| 26 | +@property (nonatomic) NSMutableArray *gradeStringPaths; | ||
| 27 | + | ||
| 24 | @end | 28 | @end |
| 25 | 29 | ||
| 26 | @implementation PNLineChart | 30 | @implementation PNLineChart |
| @@ -312,6 +316,7 @@ | @@ -312,6 +316,7 @@ | ||
| 312 | { | 316 | { |
| 313 | _chartPath = [[NSMutableArray alloc] init]; | 317 | _chartPath = [[NSMutableArray alloc] init]; |
| 314 | _pointPath = [[NSMutableArray alloc] init]; | 318 | _pointPath = [[NSMutableArray alloc] init]; |
| 319 | + _gradeStringPaths = [NSMutableArray array]; | ||
| 315 | 320 | ||
| 316 | [self calculateChartPath:_chartPath andPointsPath:_pointPath andPathKeyPoints:_pathPoints andPathStartEndPoints:_endPointsOfPath]; | 321 | [self calculateChartPath:_chartPath andPointsPath:_pointPath andPathKeyPoints:_pathPoints andPathStartEndPoints:_endPointsOfPath]; |
| 317 | // Draw each line | 322 | // Draw each line |
| @@ -350,6 +355,12 @@ | @@ -350,6 +355,12 @@ | ||
| 350 | } | 355 | } |
| 351 | 356 | ||
| 352 | [CATransaction commit]; | 357 | [CATransaction commit]; |
| 358 | + | ||
| 359 | + NSMutableArray* textLayerArray = [self.gradeStringPaths objectAtIndex:lineIndex]; | ||
| 360 | + for (CATextLayer* textLayer in textLayerArray) { | ||
| 361 | + CABasicAnimation* fadeAnimation = [self fadeAnimation]; | ||
| 362 | + [textLayer addAnimation:fadeAnimation forKey:nil]; | ||
| 363 | + } | ||
| 353 | 364 | ||
| 354 | UIGraphicsEndImageContext(); | 365 | UIGraphicsEndImageContext(); |
| 355 | } | 366 | } |
| @@ -374,6 +385,10 @@ | @@ -374,6 +385,10 @@ | ||
| 374 | [chartPath insertObject:progressline atIndex:lineIndex]; | 385 | [chartPath insertObject:progressline atIndex:lineIndex]; |
| 375 | [pointsPath insertObject:pointPath atIndex:lineIndex]; | 386 | [pointsPath insertObject:pointPath atIndex:lineIndex]; |
| 376 | 387 | ||
| 388 | + | ||
| 389 | + NSMutableArray* gradePathArray = [NSMutableArray array]; | ||
| 390 | + [self.gradeStringPaths addObject:gradePathArray]; | ||
| 391 | + | ||
| 377 | if (!_showLabel) { | 392 | if (!_showLabel) { |
| 378 | _chartCavanHeight = self.frame.size.height - 2 * _yLabelHeight; | 393 | _chartCavanHeight = self.frame.size.height - 2 * _yLabelHeight; |
| 379 | _chartCavanWidth = self.frame.size.width; | 394 | _chartCavanWidth = self.frame.size.width; |
| @@ -411,6 +426,11 @@ | @@ -411,6 +426,11 @@ | ||
| 411 | [pointPath moveToPoint:CGPointMake(circleCenter.x + (inflexionWidth / 2), circleCenter.y)]; | 426 | [pointPath moveToPoint:CGPointMake(circleCenter.x + (inflexionWidth / 2), circleCenter.y)]; |
| 412 | [pointPath addArcWithCenter:circleCenter radius:inflexionWidth / 2 startAngle:0 endAngle:2 * M_PI clockwise:YES]; | 427 | [pointPath addArcWithCenter:circleCenter radius:inflexionWidth / 2 startAngle:0 endAngle:2 * M_PI clockwise:YES]; |
| 413 | 428 | ||
| 429 | + //jet text display text | ||
| 430 | + CATextLayer* textLayer = [self createTextLayer]; | ||
| 431 | + [self setGradeFrame:textLayer grade:yValue pointCenter:circleCenter width:inflexionWidth]; | ||
| 432 | + [gradePathArray addObject:textLayer]; | ||
| 433 | + | ||
| 414 | if ( i != 0 ) { | 434 | if ( i != 0 ) { |
| 415 | 435 | ||
| 416 | // calculate the point for line | 436 | // calculate the point for line |
| @@ -442,6 +462,11 @@ | @@ -442,6 +462,11 @@ | ||
| 442 | [pointPath addLineToPoint:CGPointMake(squareCenter.x - (inflexionWidth / 2), squareCenter.y + (inflexionWidth / 2))]; | 462 | [pointPath addLineToPoint:CGPointMake(squareCenter.x - (inflexionWidth / 2), squareCenter.y + (inflexionWidth / 2))]; |
| 443 | [pointPath closePath]; | 463 | [pointPath closePath]; |
| 444 | 464 | ||
| 465 | + // text display text | ||
| 466 | + CATextLayer* textLayer = [self createTextLayer]; | ||
| 467 | + [self setGradeFrame:textLayer grade:yValue pointCenter:squareCenter width:inflexionWidth]; | ||
| 468 | + [gradePathArray addObject:textLayer]; | ||
| 469 | + | ||
| 445 | if ( i != 0 ) { | 470 | if ( i != 0 ) { |
| 446 | 471 | ||
| 447 | // calculate the point for line | 472 | // calculate the point for line |
| @@ -475,6 +500,11 @@ | @@ -475,6 +500,11 @@ | ||
| 475 | [pointPath addLineToPoint:endPoint]; | 500 | [pointPath addLineToPoint:endPoint]; |
| 476 | [pointPath closePath]; | 501 | [pointPath closePath]; |
| 477 | 502 | ||
| 503 | + // text display text | ||
| 504 | + CATextLayer* textLayer = [self createTextLayer]; | ||
| 505 | + [self setGradeFrame:textLayer grade:yValue pointCenter:middlePoint width:inflexionWidth]; | ||
| 506 | + [gradePathArray addObject:textLayer]; | ||
| 507 | + | ||
| 478 | if ( i != 0 ) { | 508 | if ( i != 0 ) { |
| 479 | // calculate the point for triangle | 509 | // calculate the point for triangle |
| 480 | float distance = sqrt(pow(x - last_x, 2) + pow(y - last_y, 2) ) * 1.4 ; | 510 | float distance = sqrt(pow(x - last_x, 2) + pow(y - last_y, 2) ) * 1.4 ; |
| @@ -963,4 +993,48 @@ | @@ -963,4 +993,48 @@ | ||
| 963 | return squareImageView; | 993 | return squareImageView; |
| 964 | } | 994 | } |
| 965 | 995 | ||
| 996 | +#pragma mark setter and getter | ||
| 997 | + | ||
| 998 | +-(CATextLayer*)createTextLayer | ||
| 999 | +{ | ||
| 1000 | + CATextLayer * textLayer = [[CATextLayer alloc]init]; | ||
| 1001 | + [textLayer setString:@"0"]; | ||
| 1002 | + [textLayer setAlignmentMode:kCAAlignmentCenter]; | ||
| 1003 | + [textLayer setForegroundColor:[[UIColor blackColor] CGColor]]; | ||
| 1004 | + return textLayer; | ||
| 1005 | +} | ||
| 1006 | + | ||
| 1007 | +-(void)setGradeFrame:(CATextLayer*)textLayer grade:(CGFloat)grade pointCenter:(CGPoint)pointCenter width:(CGFloat)width | ||
| 1008 | +{ | ||
| 1009 | + CGFloat textheigt = width*3; | ||
| 1010 | + CGFloat textWidth = width*4; | ||
| 1011 | + CGFloat textStartPosY; | ||
| 1012 | + | ||
| 1013 | + if (pointCenter.y > textheigt) { | ||
| 1014 | + textStartPosY = pointCenter.y - textheigt; | ||
| 1015 | + } | ||
| 1016 | + else { | ||
| 1017 | + textStartPosY = pointCenter.y; | ||
| 1018 | + } | ||
| 1019 | + | ||
| 1020 | + [self.layer addSublayer:textLayer]; | ||
| 1021 | + [textLayer setFontSize:textheigt/2]; | ||
| 1022 | + | ||
| 1023 | + [textLayer setString:[[NSString alloc]initWithFormat:@"%ld",(NSInteger)(grade*100)]]; | ||
| 1024 | + [textLayer setFrame:CGRectMake(0, 0, textWidth, textheigt)]; | ||
| 1025 | + [textLayer setPosition:CGPointMake(pointCenter.x, textStartPosY)]; | ||
| 1026 | + textLayer.contentsScale = [UIScreen mainScreen].scale; | ||
| 1027 | + | ||
| 1028 | +} | ||
| 1029 | + | ||
| 1030 | +-(CABasicAnimation*)fadeAnimation | ||
| 1031 | +{ | ||
| 1032 | + CABasicAnimation* fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; | ||
| 1033 | + fadeAnimation.fromValue = [NSNumber numberWithFloat:0.0]; | ||
| 1034 | + fadeAnimation.toValue = [NSNumber numberWithFloat:1.0]; | ||
| 1035 | + fadeAnimation.duration = 2.0; | ||
| 1036 | + | ||
| 1037 | + return fadeAnimation; | ||
| 1038 | +} | ||
| 1039 | + | ||
| 966 | @end | 1040 | @end |
-
Please register or login to post a comment