kevinzhow

Merge branch 'master' of github.com:kevinzhow/PNChart

@@ -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
@@ -38,12 +39,14 @@ @@ -38,12 +39,14 @@
38 39
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:@"%0.f",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
@@ -10,7 +10,6 @@ @@ -10,7 +10,6 @@
10 #import "PNColor.h" 10 #import "PNColor.h"
11 #import "PNChartLabel.h" 11 #import "PNChartLabel.h"
12 12
13 -  
14 @interface PNBarChart () { 13 @interface PNBarChart () {
15 NSMutableArray *_xChartLabels; 14 NSMutableArray *_xChartLabels;
16 NSMutableArray *_yChartLabels; 15 NSMutableArray *_yChartLabels;
@@ -62,53 +61,64 @@ @@ -62,53 +61,64 @@
62 _showChartBorder = NO; 61 _showChartBorder = NO;
63 _yChartLabelWidth = 18; 62 _yChartLabelWidth = 18;
64 _rotateForXAxisText = false; 63 _rotateForXAxisText = false;
  64 +
  65 + yLabelFormatter = ^(CGFloat yValue){
  66 + return [NSString stringWithFormat:@"%1.f",yValue];
  67 + };
65 } 68 }
66 69
67 - (void)setYValues:(NSArray *)yValues 70 - (void)setYValues:(NSArray *)yValues
68 { 71 {
69 _yValues = yValues; 72 _yValues = yValues;
  73 + //make the _yLabelSum value dependant of the distinct values of yValues to avoid duplicates on yAxis
  74 +
  75 + if (_showLabel) {
  76 + [self __addYCoordinateLabelsValues];
  77 + }
  78 +}
70 79
71 - //make the _yLabelSum value dependant of the distinct values of yValues to avoid duplicates on yAxis 80 +#pragma mark - Private Method
72 - int yLabelsDifTotal = (int)[NSSet setWithArray:yValues].count; 81 +#pragma mark - 添加柱状图的Y轴坐标
73 - _yLabelSum = yLabelsDifTotal % 2 == 0 ? yLabelsDifTotal : yLabelsDifTotal + 1; 82 +- (void)__addYCoordinateLabelsValues{
74 - 83 +
75 - if (_yMaxValue) { 84 + [self viewCleanupForCollection:_yChartLabels];
76 - _yValueMax = _yMaxValue; 85 +
  86 + NSArray *yAxisValues = _yLabels ? _yLabels : _yValues;
  87 + if (_yMaxValue) {
  88 + _yValueMax = _yMaxValue;
  89 + } else {
  90 + [self getYValueMax:yAxisValues];
  91 + }
  92 +
  93 + if (_yLabelSum==4) {
  94 + _yLabelSum = yAxisValues.count;
  95 + (_yLabelSum % 2 == 0) ? _yLabelSum : _yLabelSum++;
  96 + }
  97 +
  98 + float sectionHeight = (self.frame.size.height - _chartMargin * 2 - kXLabelHeight) / _yLabelSum;
  99 + for (int i = 0; i < _yLabelSum; i++) {
  100 + NSString *labelText;
  101 + if (_yLabels) {
  102 + float yAsixValue = [_yLabels[_yLabels.count - i - 1] floatValue];
  103 + labelText= _yLabelFormatter(yAsixValue);
77 } else { 104 } else {
78 - [self getYValueMax:yValues]; 105 + labelText = _yLabelFormatter((float)_yValueMax * ( (_yLabelSum - i) / (float)_yLabelSum ));
79 } 106 }
80 107
81 - if (_yChartLabels) { 108 + CGRect frame = (CGRect){0, sectionHeight * i + _chartMargin - kYLabelHeight/2.0, _yChartLabelWidth, kYLabelHeight};
82 - [self viewCleanupForCollection:_yChartLabels]; 109 + PNChartLabel *label = [[PNChartLabel alloc] initWithFrame:frame];
83 - }else{ 110 + label.font = _labelFont;
84 - _yLabels = [NSMutableArray new]; 111 + label.textColor = _labelTextColor;
85 - } 112 + [label setTextAlignment:NSTextAlignmentRight];
  113 + label.text = labelText;
  114 + [self addSubview:label];
86 115
87 - if (_showLabel) { 116 + [_yChartLabels addObject:label];
88 - //Add y labels 117 + }
89 -  
90 - float yLabelSectionHeight = (self.frame.size.height - _chartMargin * 2 - kXLabelHeight) / _yLabelSum;  
91 -  
92 - for (int index = 0; index < _yLabelSum; index++) {  
93 -  
94 - NSString *labelText = _yLabelFormatter((float)_yValueMax * ( (_yLabelSum - index) / (float)_yLabelSum ));  
95 -  
96 - PNChartLabel * label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0,  
97 - yLabelSectionHeight * index + _chartMargin - kYLabelHeight/2.0,  
98 - _yChartLabelWidth,  
99 - kYLabelHeight)];  
100 - label.font = _labelFont;  
101 - label.textColor = _labelTextColor;  
102 - [label setTextAlignment:NSTextAlignmentRight];  
103 - label.text = labelText;  
104 -  
105 - [_yChartLabels addObject:label];  
106 - [self addSubview:label];  
107 -  
108 - }  
109 - }  
110 } 118 }
111 119
  120 +
  121 +
112 -(void)updateChartData:(NSArray *)data{ 122 -(void)updateChartData:(NSArray *)data{
113 self.yValues = data; 123 self.yValues = data;
114 [self updateBar]; 124 [self updateBar];
@@ -135,9 +145,10 @@ @@ -135,9 +145,10 @@
135 }else{ 145 }else{
136 _xChartLabels = [NSMutableArray new]; 146 _xChartLabels = [NSMutableArray new];
137 } 147 }
138 - 148 +
139 - if (_showLabel) { 149 + _xLabelWidth = (self.frame.size.width - _chartMargin * 2) / [xLabels count];
140 - _xLabelWidth = (self.frame.size.width - _chartMargin * 2) / [xLabels count]; 150 +
  151 + if (_showLabel) {
141 int labelAddCount = 0; 152 int labelAddCount = 0;
142 for (int index = 0; index < _xLabels.count; index++) { 153 for (int index = 0; index < _xLabels.count; index++) {
143 labelAddCount += 1; 154 labelAddCount += 1;
@@ -238,7 +249,7 @@ @@ -238,7 +249,7 @@
238 float value = [valueString floatValue]; 249 float value = [valueString floatValue];
239 250
240 float grade = (float)value / (float)_yValueMax; 251 float grade = (float)value / (float)_yValueMax;
241 - 252 +
242 if (isnan(grade)) { 253 if (isnan(grade)) {
243 grade = 0; 254 grade = 0;
244 } 255 }
@@ -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;
@@ -394,7 +409,7 @@ @@ -394,7 +409,7 @@
394 if (!(_yValueMax - _yValueMin)) { 409 if (!(_yValueMax - _yValueMin)) {
395 innerGrade = 0.5; 410 innerGrade = 0.5;
396 } else { 411 } else {
397 - innerGrade = (yValue - _yValueMin) / (_yValueMax - _yValueMin) == 0 ? 0.5 : (yValue - _yValueMin) / (_yValueMax - _yValueMin); 412 + innerGrade = (yValue - _yValueMin) / (_yValueMax - _yValueMin);
398 } 413 }
399 414
400 CGFloat offSetX = (_chartCavanWidth) / (chartData.itemCount); 415 CGFloat offSetX = (_chartCavanWidth) / (chartData.itemCount);
@@ -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
@@ -103,7 +103,12 @@ @@ -103,7 +103,12 @@
103 self.barChart.labelMarginTop = 5.0; 103 self.barChart.labelMarginTop = 5.0;
104 [self.barChart setXLabels:@[@"SEP 1",@"SEP 2",@"SEP 3",@"SEP 4",@"SEP 5",@"SEP 6",@"SEP 7"]]; 104 [self.barChart setXLabels:@[@"SEP 1",@"SEP 2",@"SEP 3",@"SEP 4",@"SEP 5",@"SEP 6",@"SEP 7"]];
105 self.barChart.rotateForXAxisText = true ; 105 self.barChart.rotateForXAxisText = true ;
  106 +
  107 + self.barChart.yLabelSum=5;
  108 + self.barChart.yMaxValue=100;
  109 +
106 [self.barChart setYValues:@[@1,@24,@12,@18,@30,@10,@21]]; 110 [self.barChart setYValues:@[@1,@24,@12,@18,@30,@10,@21]];
  111 +// self.barChart.yLabels = @[@0,@20,@40,@60];
107 [self.barChart setStrokeColors:@[PNGreen,PNGreen,PNRed,PNGreen,PNGreen,PNYellow,PNGreen]]; 112 [self.barChart setStrokeColors:@[PNGreen,PNGreen,PNRed,PNGreen,PNGreen,PNYellow,PNGreen]];
108 // Adding gradient 113 // Adding gradient
109 self.barChart.barColorGradientStart = [UIColor blueColor]; 114 self.barChart.barColorGradientStart = [UIColor blueColor];