Peter Easdown

1. PNBar now allows you to specify a color for the label.

2. You can specify the border color for a PNBarChart
3. Fixed some problems in PNBarChart whereby the top and bottom margins were not being respected.
4. PNLineChart now has the same margin properties as PNBarChart so that you can overlay them and have the bars and the points in the LineChart line-up nicely.
5. You can now specify for a PNLineChart that points display their value using a font, format and color, just above the point itself.
6. A PNLineChartDataItem can now have two values, a raw value for displaying via the formatter, and the graded value which is used to determine the position of the data point.  The former is new.  This allows you to have multiple line charts that have different min-max values and yet overlay them.  The new value can then be used to display a value meaningful to the user whilst the old value is used to render the chart point.
@@ -26,6 +26,9 @@ @@ -26,6 +26,9 @@
26 @property (nonatomic) CAShapeLayer *gradeLayer; 26 @property (nonatomic) CAShapeLayer *gradeLayer;
27 @property (nonatomic) CATextLayer* textLayer; 27 @property (nonatomic) CATextLayer* textLayer;
28 28
  29 +/** Text color for all bars in the chart. */
  30 +@property (nonatomic) UIColor * labelTextColor;
  31 +
29 @property (nonatomic, assign) BOOL isNegative; //!< 是否是负数 32 @property (nonatomic, assign) BOOL isNegative; //!< 是否是负数
30 @property (nonatomic, assign) BOOL isShowNumber; //!< 是否显示numbers 33 @property (nonatomic, assign) BOOL isShowNumber; //!< 是否显示numbers
31 @end 34 @end
@@ -181,7 +181,7 @@ @@ -181,7 +181,7 @@
181 _textLayer = [[CATextLayer alloc]init]; 181 _textLayer = [[CATextLayer alloc]init];
182 [_textLayer setString:@"0"]; 182 [_textLayer setString:@"0"];
183 [_textLayer setAlignmentMode:kCAAlignmentCenter]; 183 [_textLayer setAlignmentMode:kCAAlignmentCenter];
184 - [_textLayer setForegroundColor:[[UIColor colorWithRed:178/255.0 green:178/255. blue:178/255.0 alpha:1.0] CGColor]]; 184 + [_textLayer setForegroundColor:[_labelTextColor CGColor]];
185 _textLayer.hidden = YES; 185 _textLayer.hidden = YES;
186 186
187 } 187 }
@@ -189,6 +189,11 @@ @@ -189,6 +189,11 @@
189 return _textLayer; 189 return _textLayer;
190 } 190 }
191 191
  192 +- (void) setLabelTextColor:(UIColor *)labelTextColor {
  193 + _labelTextColor = labelTextColor;
  194 + [_textLayer setForegroundColor:[_labelTextColor CGColor]];
  195 +}
  196 +
192 -(void)setGradeFrame:(CGFloat)grade startPosY:(CGFloat)startPosY 197 -(void)setGradeFrame:(CGFloat)grade startPosY:(CGFloat)startPosY
193 { 198 {
194 CGFloat textheigt = self.bounds.size.height*self.grade; 199 CGFloat textheigt = self.bounds.size.height*self.grade;
@@ -63,6 +63,8 @@ typedef NSString *(^PNYLabelFormatter)(CGFloat yLabelValue); @@ -63,6 +63,8 @@ typedef NSString *(^PNYLabelFormatter)(CGFloat yLabelValue);
63 /** Controls whether the chart border line should be displayed. */ 63 /** Controls whether the chart border line should be displayed. */
64 @property (nonatomic) BOOL showChartBorder; 64 @property (nonatomic) BOOL showChartBorder;
65 65
  66 +@property (nonatomic) UIColor *chartBorderColor;
  67 +
66 /** Controls whether the chart Horizontal separator should be displayed. */ 68 /** Controls whether the chart Horizontal separator should be displayed. */
67 @property (nonatomic, assign) BOOL showLevelLine; 69 @property (nonatomic, assign) BOOL showLevelLine;
68 70
@@ -62,6 +62,7 @@ @@ -62,6 +62,7 @@
62 _chartMarginBottom = 25.0; 62 _chartMarginBottom = 25.0;
63 _barRadius = 2.0; 63 _barRadius = 2.0;
64 _showChartBorder = NO; 64 _showChartBorder = NO;
  65 + _chartBorderColor = PNLightGrey;
65 _showLevelLine = NO; 66 _showLevelLine = NO;
66 _yChartLabelWidth = 18; 67 _yChartLabelWidth = 18;
67 _rotateForXAxisText = false; 68 _rotateForXAxisText = false;
@@ -234,7 +235,7 @@ @@ -234,7 +235,7 @@
234 } 235 }
235 236
236 bar = [[PNBar alloc] initWithFrame:CGRectMake(barXPosition, //Bar X position 237 bar = [[PNBar alloc] initWithFrame:CGRectMake(barXPosition, //Bar X position
237 - self.frame.size.height - chartCavanHeight - kXLabelHeight - _chartMarginTop , //Bar Y position 238 + self.frame.size.height - chartCavanHeight - kXLabelHeight - _chartMarginBottom + _chartMarginTop , //Bar Y position
238 barWidth, // Bar witdh 239 barWidth, // Bar witdh
239 self.showLevelLine ? chartCavanHeight/2.0:chartCavanHeight)]; //Bar height 240 self.showLevelLine ? chartCavanHeight/2.0:chartCavanHeight)]; //Bar height
240 241
@@ -249,6 +250,10 @@ @@ -249,6 +250,10 @@
249 }else{ 250 }else{
250 bar.barColor = [self barColorAtIndex:index]; 251 bar.barColor = [self barColorAtIndex:index];
251 } 252 }
  253 +
  254 + if (self.labelTextColor) {
  255 + bar.labelTextColor = self.labelTextColor;
  256 + }
252 257
253 // Add gradient 258 // Add gradient
254 if (self.isGradientShow) { 259 if (self.isGradientShow) {
@@ -309,13 +314,13 @@ @@ -309,13 +314,13 @@
309 314
310 UIBezierPath *progressline = [UIBezierPath bezierPath]; 315 UIBezierPath *progressline = [UIBezierPath bezierPath];
311 316
312 - [progressline moveToPoint:CGPointMake(_chartMarginLeft, self.frame.size.height - kXLabelHeight - _chartMarginTop)]; 317 + [progressline moveToPoint:CGPointMake(_chartMarginLeft, self.frame.size.height - kXLabelHeight - _chartMarginBottom + _chartMarginTop)];
313 - [progressline addLineToPoint:CGPointMake(self.frame.size.width - _chartMarginRight, self.frame.size.height - kXLabelHeight - _chartMarginTop)]; 318 + [progressline addLineToPoint:CGPointMake(self.frame.size.width - _chartMarginRight, self.frame.size.height - kXLabelHeight - _chartMarginBottom + _chartMarginTop)];
314 319
315 [progressline setLineWidth:1.0]; 320 [progressline setLineWidth:1.0];
316 [progressline setLineCapStyle:kCGLineCapSquare]; 321 [progressline setLineCapStyle:kCGLineCapSquare];
317 _chartBottomLine.path = progressline.CGPath; 322 _chartBottomLine.path = progressline.CGPath;
318 - _chartBottomLine.strokeColor = PNLightGrey.CGColor; 323 + _chartBottomLine.strokeColor = [_chartBorderColor CGColor];;
319 324
320 CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 325 CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
321 pathAnimation.duration = 0.5; 326 pathAnimation.duration = 0.5;
@@ -344,7 +349,7 @@ @@ -344,7 +349,7 @@
344 [progressLeftline setLineWidth:1.0]; 349 [progressLeftline setLineWidth:1.0];
345 [progressLeftline setLineCapStyle:kCGLineCapSquare]; 350 [progressLeftline setLineCapStyle:kCGLineCapSquare];
346 _chartLeftLine.path = progressLeftline.CGPath; 351 _chartLeftLine.path = progressLeftline.CGPath;
347 - _chartLeftLine.strokeColor = PNLightGrey.CGColor; 352 + _chartLeftLine.strokeColor = [_chartBorderColor CGColor];
348 353
349 CABasicAnimation *pathLeftAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 354 CABasicAnimation *pathLeftAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
350 pathLeftAnimation.duration = 0.5; 355 pathLeftAnimation.duration = 0.5;
@@ -45,11 +45,14 @@ @@ -45,11 +45,14 @@
45 @property (nonatomic) UIColor *yLabelColor; 45 @property (nonatomic) UIColor *yLabelColor;
46 @property (nonatomic) CGFloat chartCavanHeight; 46 @property (nonatomic) CGFloat chartCavanHeight;
47 @property (nonatomic) CGFloat chartCavanWidth; 47 @property (nonatomic) CGFloat chartCavanWidth;
48 -@property (nonatomic) CGFloat chartMargin;  
49 @property (nonatomic) BOOL showLabel; 48 @property (nonatomic) BOOL showLabel;
50 @property (nonatomic) BOOL showGenYLabels; 49 @property (nonatomic) BOOL showGenYLabels;
51 @property (nonatomic) BOOL thousandsSeparator; 50 @property (nonatomic) BOOL thousandsSeparator;
52 51
  52 +@property (nonatomic) CGFloat chartMarginLeft;
  53 +@property (nonatomic) CGFloat chartMarginRight;
  54 +@property (nonatomic) CGFloat chartMarginTop;
  55 +@property (nonatomic) CGFloat chartMarginBottom;
53 56
54 /** 57 /**
55 * Controls whether to show the coordinate axis. Default is NO. 58 * Controls whether to show the coordinate axis. Default is NO.
@@ -70,19 +70,19 @@ @@ -70,19 +70,19 @@
70 } 70 }
71 71
72 if (yStep == 0.0) { 72 if (yStep == 0.0) {
73 - PNChartLabel *minLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)_chartCavanHeight, (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; 73 + PNChartLabel *minLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)_chartCavanHeight, (NSInteger)_chartMarginBottom, (NSInteger)_yLabelHeight)];
74 minLabel.text = [self formatYLabel:0.0]; 74 minLabel.text = [self formatYLabel:0.0];
75 [self setCustomStyleForYLabel:minLabel]; 75 [self setCustomStyleForYLabel:minLabel];
76 [self addSubview:minLabel]; 76 [self addSubview:minLabel];
77 [_yChartLabels addObject:minLabel]; 77 [_yChartLabels addObject:minLabel];
78 78
79 - PNChartLabel *midLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)(_chartCavanHeight / 2), (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; 79 + PNChartLabel *midLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)(_chartCavanHeight / 2), (NSInteger)_chartMarginBottom, (NSInteger)_yLabelHeight)];
80 midLabel.text = [self formatYLabel:_yValueMax]; 80 midLabel.text = [self formatYLabel:_yValueMax];
81 [self setCustomStyleForYLabel:midLabel]; 81 [self setCustomStyleForYLabel:midLabel];
82 [self addSubview:midLabel]; 82 [self addSubview:midLabel];
83 [_yChartLabels addObject:midLabel]; 83 [_yChartLabels addObject:midLabel];
84 84
85 - PNChartLabel *maxLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, 0.0, (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; 85 + PNChartLabel *maxLabel = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, 0.0, (NSInteger)_chartMarginBottom, (NSInteger)_yLabelHeight)];
86 maxLabel.text = [self formatYLabel:_yValueMax * 2]; 86 maxLabel.text = [self formatYLabel:_yValueMax * 2];
87 [self setCustomStyleForYLabel:maxLabel]; 87 [self setCustomStyleForYLabel:maxLabel];
88 [self addSubview:maxLabel]; 88 [self addSubview:maxLabel];
@@ -94,7 +94,7 @@ @@ -94,7 +94,7 @@
94 94
95 while (num > 0) 95 while (num > 0)
96 { 96 {
97 - PNChartLabel *label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)(_chartCavanHeight - index * yStepHeight), (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; 97 + PNChartLabel *label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (NSInteger)(_chartCavanHeight - index * yStepHeight), (NSInteger)_chartMarginBottom, (NSInteger)_yLabelHeight)];
98 [label setTextAlignment:NSTextAlignmentRight]; 98 [label setTextAlignment:NSTextAlignmentRight];
99 label.text = [self formatYLabel:_yValueMin + (yStep * index)]; 99 label.text = [self formatYLabel:_yValueMin + (yStep * index)];
100 [self setCustomStyleForYLabel:label]; 100 [self setCustomStyleForYLabel:label];
@@ -143,7 +143,7 @@ @@ -143,7 +143,7 @@
143 143
144 NSInteger y = (NSInteger)(_chartCavanHeight - index * yStepHeight); 144 NSInteger y = (NSInteger)(_chartCavanHeight - index * yStepHeight);
145 145
146 - PNChartLabel *label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, y, (NSInteger)_chartMargin, (NSInteger)_yLabelHeight)]; 146 + PNChartLabel *label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, y, (NSInteger)_chartMarginLeft * 0.9, (NSInteger)_yLabelHeight)];
147 [label setTextAlignment:NSTextAlignmentRight]; 147 [label setTextAlignment:NSTextAlignmentRight];
148 label.text = labelText; 148 label.text = labelText;
149 [self setCustomStyleForYLabel:label]; 149 [self setCustomStyleForYLabel:label];
@@ -174,7 +174,7 @@ @@ -174,7 +174,7 @@
174 if (_showLabel) { 174 if (_showLabel) {
175 xLabelWidth = _chartCavanWidth / [xLabels count]; 175 xLabelWidth = _chartCavanWidth / [xLabels count];
176 } else { 176 } else {
177 - xLabelWidth = (self.frame.size.width) / [xLabels count]; 177 + xLabelWidth = (self.frame.size.width - _chartMarginLeft - _chartMarginRight) / [xLabels count];
178 } 178 }
179 179
180 return [self setXLabels:xLabels withWidth:xLabelWidth]; 180 return [self setXLabels:xLabels withWidth:xLabelWidth];
@@ -198,10 +198,10 @@ @@ -198,10 +198,10 @@
198 for (int index = 0; index < xLabels.count; index++) { 198 for (int index = 0; index < xLabels.count; index++) {
199 labelText = xLabels[index]; 199 labelText = xLabels[index];
200 200
201 - NSInteger x = 2 * _chartMargin + (index * _xLabelWidth) - (_xLabelWidth / 2); 201 + NSInteger x = (index * _xLabelWidth + _chartMarginLeft + _xLabelWidth /2.0 );
202 - NSInteger y = _chartMargin + _chartCavanHeight; 202 + NSInteger y = _chartMarginBottom + _chartCavanHeight;
203 203
204 - PNChartLabel *label = [[PNChartLabel alloc] initWithFrame:CGRectMake(x, y, (NSInteger)_xLabelWidth, (NSInteger)_chartMargin)]; 204 + PNChartLabel *label = [[PNChartLabel alloc] initWithFrame:CGRectMake(x, y, (NSInteger)_xLabelWidth, (NSInteger)_chartMarginBottom)];
205 [label setTextAlignment:NSTextAlignmentCenter]; 205 [label setTextAlignment:NSTextAlignmentCenter];
206 label.text = labelText; 206 label.text = labelText;
207 [self setCustomStyleForXLabel:label]; 207 [self setCustomStyleForXLabel:label];
@@ -392,7 +392,7 @@ @@ -392,7 +392,7 @@
392 if (!_showLabel) { 392 if (!_showLabel) {
393 _chartCavanHeight = self.frame.size.height - 2 * _yLabelHeight; 393 _chartCavanHeight = self.frame.size.height - 2 * _yLabelHeight;
394 _chartCavanWidth = self.frame.size.width; 394 _chartCavanWidth = self.frame.size.width;
395 - _chartMargin = chartData.inflexionPointWidth; 395 + //_chartMargin = chartData.inflexionPointWidth;
396 _xLabelWidth = (_chartCavanWidth / ([_xLabels count] - 1)); 396 _xLabelWidth = (_chartCavanWidth / ([_xLabels count] - 1));
397 } 397 }
398 398
@@ -412,10 +412,9 @@ @@ -412,10 +412,9 @@
412 innerGrade = (yValue - _yValueMin) / (_yValueMax - _yValueMin); 412 innerGrade = (yValue - _yValueMin) / (_yValueMax - _yValueMin);
413 } 413 }
414 414
415 - CGFloat offSetX = (_chartCavanWidth) / (chartData.itemCount); 415 + int x = i * _xLabelWidth + _chartMarginLeft + _xLabelWidth /2.0;
416 416
417 - int x = 2 * _chartMargin + (i * offSetX); 417 + int y = _chartCavanHeight - (innerGrade * _chartCavanHeight) + (_yLabelHeight / 2) + _chartMarginTop - _chartMarginBottom;
418 - int y = _chartCavanHeight - (innerGrade * _chartCavanHeight) + (_yLabelHeight / 2);  
419 418
420 // Circular point 419 // Circular point
421 if (chartData.inflexionPointStyle == PNLineChartPointStyleCircle) { 420 if (chartData.inflexionPointStyle == PNLineChartPointStyleCircle) {
@@ -427,9 +426,9 @@ @@ -427,9 +426,9 @@
427 [pointPath addArcWithCenter:circleCenter radius:inflexionWidth / 2 startAngle:0 endAngle:2 * M_PI clockwise:YES]; 426 [pointPath addArcWithCenter:circleCenter radius:inflexionWidth / 2 startAngle:0 endAngle:2 * M_PI clockwise:YES];
428 427
429 //jet text display text 428 //jet text display text
430 -// CATextLayer* textLayer = [self createTextLayer]; 429 + if (chartData.showPointLabel == YES) {
431 -// [self setGradeFrame:textLayer grade:yValue pointCenter:circleCenter width:inflexionWidth]; 430 + [gradePathArray addObject:[self createPointLabelFor:chartData.getData(i).rawY pointCenter:circleCenter width:inflexionWidth withChartData:chartData]];
432 -// [gradePathArray addObject:textLayer]; 431 + }
433 432
434 if ( i != 0 ) { 433 if ( i != 0 ) {
435 434
@@ -463,9 +462,9 @@ @@ -463,9 +462,9 @@
463 [pointPath closePath]; 462 [pointPath closePath];
464 463
465 // text display text 464 // text display text
466 -// CATextLayer* textLayer = [self createTextLayer]; 465 + if (chartData.showPointLabel == YES) {
467 -// [self setGradeFrame:textLayer grade:yValue pointCenter:squareCenter width:inflexionWidth]; 466 + [gradePathArray addObject:[self createPointLabelFor:chartData.getData(i).rawY pointCenter:squareCenter width:inflexionWidth withChartData:chartData]];
468 -// [gradePathArray addObject:textLayer]; 467 + }
469 468
470 if ( i != 0 ) { 469 if ( i != 0 ) {
471 470
@@ -501,9 +500,9 @@ @@ -501,9 +500,9 @@
501 [pointPath closePath]; 500 [pointPath closePath];
502 501
503 // text display text 502 // text display text
504 -// CATextLayer* textLayer = [self createTextLayer]; 503 + if (chartData.showPointLabel == YES) {
505 -// [self setGradeFrame:textLayer grade:yValue pointCenter:middlePoint width:inflexionWidth]; 504 + [gradePathArray addObject:[self createPointLabelFor:chartData.getData(i).rawY pointCenter:middlePoint width:inflexionWidth withChartData:chartData]];
506 -// [gradePathArray addObject:textLayer]; 505 + }
507 506
508 if ( i != 0 ) { 507 if ( i != 0 ) {
509 // calculate the point for triangle 508 // calculate the point for triangle
@@ -684,19 +683,19 @@ @@ -684,19 +683,19 @@
684 CGContextSetLineWidth(ctx, self.axisWidth); 683 CGContextSetLineWidth(ctx, self.axisWidth);
685 CGContextSetStrokeColorWithColor(ctx, [self.axisColor CGColor]); 684 CGContextSetStrokeColorWithColor(ctx, [self.axisColor CGColor]);
686 685
687 - CGFloat xAxisWidth = CGRectGetWidth(rect) - _chartMargin / 2; 686 + CGFloat xAxisWidth = CGRectGetWidth(rect) - (_chartMarginLeft + _chartMarginRight) / 2;
688 - CGFloat yAxisHeight = _chartMargin + _chartCavanHeight; 687 + CGFloat yAxisHeight = _chartMarginBottom + _chartCavanHeight;
689 688
690 // draw coordinate axis 689 // draw coordinate axis
691 - CGContextMoveToPoint(ctx, _chartMargin + yAxisOffset, 0); 690 + CGContextMoveToPoint(ctx, _chartMarginBottom + yAxisOffset, 0);
692 - CGContextAddLineToPoint(ctx, _chartMargin + yAxisOffset, yAxisHeight); 691 + CGContextAddLineToPoint(ctx, _chartMarginBottom + yAxisOffset, yAxisHeight);
693 CGContextAddLineToPoint(ctx, xAxisWidth, yAxisHeight); 692 CGContextAddLineToPoint(ctx, xAxisWidth, yAxisHeight);
694 CGContextStrokePath(ctx); 693 CGContextStrokePath(ctx);
695 694
696 // draw y axis arrow 695 // draw y axis arrow
697 - CGContextMoveToPoint(ctx, _chartMargin + yAxisOffset - 3, 6); 696 + CGContextMoveToPoint(ctx, _chartMarginBottom + yAxisOffset - 3, 6);
698 - CGContextAddLineToPoint(ctx, _chartMargin + yAxisOffset, 0); 697 + CGContextAddLineToPoint(ctx, _chartMarginBottom + yAxisOffset, 0);
699 - CGContextAddLineToPoint(ctx, _chartMargin + yAxisOffset + 3, 6); 698 + CGContextAddLineToPoint(ctx, _chartMarginBottom + yAxisOffset + 3, 6);
700 CGContextStrokePath(ctx); 699 CGContextStrokePath(ctx);
701 700
702 // draw x axis arrow 701 // draw x axis arrow
@@ -710,7 +709,7 @@ @@ -710,7 +709,7 @@
710 // draw x axis separator 709 // draw x axis separator
711 CGPoint point; 710 CGPoint point;
712 for (NSUInteger i = 0; i < [self.xLabels count]; i++) { 711 for (NSUInteger i = 0; i < [self.xLabels count]; i++) {
713 - point = CGPointMake(2 * _chartMargin + (i * _xLabelWidth), _chartMargin + _chartCavanHeight); 712 + point = CGPointMake(2 * _chartMarginLeft + (i * _xLabelWidth), _chartMarginBottom + _chartCavanHeight);
714 CGContextMoveToPoint(ctx, point.x, point.y - 2); 713 CGContextMoveToPoint(ctx, point.x, point.y - 2);
715 CGContextAddLineToPoint(ctx, point.x, point.y); 714 CGContextAddLineToPoint(ctx, point.x, point.y);
716 CGContextStrokePath(ctx); 715 CGContextStrokePath(ctx);
@@ -719,7 +718,7 @@ @@ -719,7 +718,7 @@
719 // draw y axis separator 718 // draw y axis separator
720 CGFloat yStepHeight = _chartCavanHeight / _yLabelNum; 719 CGFloat yStepHeight = _chartCavanHeight / _yLabelNum;
721 for (NSUInteger i = 0; i < [self.xLabels count]; i++) { 720 for (NSUInteger i = 0; i < [self.xLabels count]; i++) {
722 - point = CGPointMake(_chartMargin + yAxisOffset, (_chartCavanHeight - i * yStepHeight + _yLabelHeight / 2)); 721 + point = CGPointMake(_chartMarginBottom + yAxisOffset, (_chartCavanHeight - i * yStepHeight + _yLabelHeight / 2));
723 CGContextMoveToPoint(ctx, point.x, point.y); 722 CGContextMoveToPoint(ctx, point.x, point.y);
724 CGContextAddLineToPoint(ctx, point.x + 2, point.y); 723 CGContextAddLineToPoint(ctx, point.x + 2, point.y);
725 CGContextStrokePath(ctx); 724 CGContextStrokePath(ctx);
@@ -731,14 +730,14 @@ @@ -731,14 +730,14 @@
731 // draw y unit 730 // draw y unit
732 if ([self.yUnit length]) { 731 if ([self.yUnit length]) {
733 CGFloat height = [PNLineChart sizeOfString:self.yUnit withWidth:30.f font:font].height; 732 CGFloat height = [PNLineChart sizeOfString:self.yUnit withWidth:30.f font:font].height;
734 - CGRect drawRect = CGRectMake(_chartMargin + 10 + 5, 0, 30.f, height); 733 + CGRect drawRect = CGRectMake(_chartMarginLeft + 10 + 5, 0, 30.f, height);
735 [self drawTextInContext:ctx text:self.yUnit inRect:drawRect font:font]; 734 [self drawTextInContext:ctx text:self.yUnit inRect:drawRect font:font];
736 } 735 }
737 736
738 // draw x unit 737 // draw x unit
739 if ([self.xUnit length]) { 738 if ([self.xUnit length]) {
740 CGFloat height = [PNLineChart sizeOfString:self.xUnit withWidth:30.f font:font].height; 739 CGFloat height = [PNLineChart sizeOfString:self.xUnit withWidth:30.f font:font].height;
741 - CGRect drawRect = CGRectMake(CGRectGetWidth(rect) - _chartMargin + 5, _chartMargin + _chartCavanHeight - height / 2, 25.f, height); 740 + CGRect drawRect = CGRectMake(CGRectGetWidth(rect) - _chartMarginLeft + 5, _chartMarginBottom + _chartCavanHeight - height / 2, 25.f, height);
742 [self drawTextInContext:ctx text:self.xUnit inRect:drawRect font:font]; 741 [self drawTextInContext:ctx text:self.xUnit inRect:drawRect font:font];
743 } 742 }
744 } 743 }
@@ -766,15 +765,23 @@ @@ -766,15 +765,23 @@
766 _yLabelNum = 5.0; 765 _yLabelNum = 5.0;
767 _yLabelHeight = [[[[PNChartLabel alloc] init] font] pointSize]; 766 _yLabelHeight = [[[[PNChartLabel alloc] init] font] pointSize];
768 767
769 - _chartMargin = 40; 768 +// _chartMargin = 40;
  769 +
  770 + _chartMarginLeft = 25.0;
  771 + _chartMarginRight = 25.0;
  772 + _chartMarginTop = 25.0;
  773 + _chartMarginBottom = 25.0;
  774 +
  775 + _yLabelFormat = @"%1.f";
770 776
771 - _chartCavanWidth = self.frame.size.width - _chartMargin * 2; 777 + _chartCavanWidth = self.frame.size.width - _chartMarginLeft - _chartMarginRight;
772 - _chartCavanHeight = self.frame.size.height - _chartMargin * 2; 778 + _chartCavanHeight = self.frame.size.height - _chartMarginBottom - _chartMarginTop;
773 779
774 // Coordinate Axis Default Values 780 // Coordinate Axis Default Values
775 _showCoordinateAxis = NO; 781 _showCoordinateAxis = NO;
776 _axisColor = [UIColor colorWithRed:0.4f green:0.4f blue:0.4f alpha:1.f]; 782 _axisColor = [UIColor colorWithRed:0.4f green:0.4f blue:0.4f alpha:1.f];
777 _axisWidth = 1.f; 783 _axisWidth = 1.f;
  784 +
778 } 785 }
779 786
780 #pragma mark - tools 787 #pragma mark - tools
@@ -1001,36 +1008,38 @@ @@ -1001,36 +1008,38 @@
1001 1008
1002 #pragma mark setter and getter 1009 #pragma mark setter and getter
1003 1010
1004 --(CATextLayer*)createTextLayer 1011 +-(CATextLayer*) createPointLabelFor:(CGFloat)grade pointCenter:(CGPoint)pointCenter width:(CGFloat)width withChartData:(PNLineChartData*)chartData
1005 { 1012 {
1006 - CATextLayer * textLayer = [[CATextLayer alloc]init]; 1013 + CATextLayer *textLayer = [[CATextLayer alloc]init];
1007 - [textLayer setString:@"0"];  
1008 [textLayer setAlignmentMode:kCAAlignmentCenter]; 1014 [textLayer setAlignmentMode:kCAAlignmentCenter];
1009 - [textLayer setForegroundColor:[[UIColor blackColor] CGColor]]; 1015 + [textLayer setForegroundColor:[chartData.pointLabelColor CGColor]];
1010 - return textLayer; 1016 + [textLayer setBackgroundColor:[[[UIColor whiteColor] colorWithAlphaComponent:0.8] CGColor]];
1011 -} 1017 + [textLayer setCornerRadius:textLayer.fontSize/8.0];
1012 -  
1013 --(void)setGradeFrame:(CATextLayer*)textLayer grade:(CGFloat)grade pointCenter:(CGPoint)pointCenter width:(CGFloat)width  
1014 -{  
1015 - CGFloat textheigt = width*3;  
1016 - CGFloat textWidth = width*8;  
1017 - CGFloat textStartPosY;  
1018 1018
1019 - if (pointCenter.y > textheigt) { 1019 + if (chartData.pointLabelFont != nil) {
1020 - textStartPosY = pointCenter.y - textheigt; 1020 + [textLayer setFont:(__bridge CFTypeRef)(chartData.pointLabelFont)];
1021 - } 1021 + textLayer.fontSize = [chartData.pointLabelFont pointSize];
1022 - else {  
1023 - textStartPosY = pointCenter.y;  
1024 } 1022 }
1025 1023
  1024 + CGFloat textHeight = textLayer.fontSize * 1.1;
  1025 + CGFloat textWidth = width*8;
  1026 + CGFloat textStartPosY;
  1027 +
  1028 + textStartPosY = pointCenter.y - textLayer.fontSize;
  1029 +
1026 [self.layer addSublayer:textLayer]; 1030 [self.layer addSublayer:textLayer];
1027 - [textLayer setFontSize:textheigt/2];  
1028 1031
1029 - [textLayer setString:[[NSString alloc]initWithFormat:@"%d",(int)(grade*100)]]; 1032 + if (chartData.pointLabelFormat != nil) {
1030 - [textLayer setFrame:CGRectMake(0, 0, textWidth, textheigt)]; 1033 + [textLayer setString:[[NSString alloc]initWithFormat:chartData.pointLabelFormat, grade]];
  1034 + } else {
  1035 + [textLayer setString:[[NSString alloc]initWithFormat:_yLabelFormat, grade]];
  1036 + }
  1037 +
  1038 + [textLayer setFrame:CGRectMake(0, 0, textWidth, textHeight)];
1031 [textLayer setPosition:CGPointMake(pointCenter.x, textStartPosY)]; 1039 [textLayer setPosition:CGPointMake(pointCenter.x, textStartPosY)];
1032 textLayer.contentsScale = [UIScreen mainScreen].scale; 1040 textLayer.contentsScale = [UIScreen mainScreen].scale;
1033 1041
  1042 + return textLayer;
1034 } 1043 }
1035 1044
1036 -(CABasicAnimation*)fadeAnimation 1045 -(CABasicAnimation*)fadeAnimation
@@ -25,6 +25,11 @@ typedef PNLineChartDataItem *(^LCLineChartDataGetter)(NSUInteger item); @@ -25,6 +25,11 @@ typedef PNLineChartDataItem *(^LCLineChartDataGetter)(NSUInteger item);
25 @property (copy) LCLineChartDataGetter getData; 25 @property (copy) LCLineChartDataGetter getData;
26 @property (strong, nonatomic) NSString *dataTitle; 26 @property (strong, nonatomic) NSString *dataTitle;
27 27
  28 +@property (nonatomic) BOOL showPointLabel;
  29 +@property (nonatomic) UIColor *pointLabelColor;
  30 +@property (nonatomic) UIFont *pointLabelFont;
  31 +@property (nonatomic) NSString *pointLabelFormat;
  32 +
28 @property (nonatomic, assign) PNLineChartPointStyle inflexionPointStyle; 33 @property (nonatomic, assign) PNLineChartPointStyle inflexionPointStyle;
29 34
30 /** 35 /**
@@ -23,6 +23,9 @@ @@ -23,6 +23,9 @@
23 _inflexionPointWidth = 6.f; 23 _inflexionPointWidth = 6.f;
24 _lineWidth = 2.f; 24 _lineWidth = 2.f;
25 _alpha = 1.f; 25 _alpha = 1.f;
  26 + _showPointLabel = NO;
  27 + _pointLabelColor = [UIColor blackColor];
  28 + _pointLabelFormat = @"%1.f";
26 } 29 }
27 30
28 @end 31 @end
@@ -9,7 +9,9 @@ @@ -9,7 +9,9 @@
9 @interface PNLineChartDataItem : NSObject 9 @interface PNLineChartDataItem : NSObject
10 10
11 + (PNLineChartDataItem *)dataItemWithY:(CGFloat)y; 11 + (PNLineChartDataItem *)dataItemWithY:(CGFloat)y;
  12 ++ (PNLineChartDataItem *)dataItemWithY:(CGFloat)y andRawY:(CGFloat)rawY;
12 13
13 @property (readonly) CGFloat y; // should be within the y range 14 @property (readonly) CGFloat y; // should be within the y range
  15 +@property (readonly) CGFloat rawY; // this is the raw value, used for point label.
14 16
15 @end 17 @end
@@ -7,9 +7,10 @@ @@ -7,9 +7,10 @@
7 7
8 @interface PNLineChartDataItem () 8 @interface PNLineChartDataItem ()
9 9
10 -- (id)initWithY:(CGFloat)y; 10 +- (id)initWithY:(CGFloat)y andRawY:(CGFloat)rawY;
11 11
12 -@property (readwrite) CGFloat y; // should be within the y range 12 +@property (readwrite) CGFloat y; // should be within the y range
  13 +@property (readwrite) CGFloat rawY; // this is the raw value, used for point label.
13 14
14 @end 15 @end
15 16
@@ -17,13 +18,18 @@ @@ -17,13 +18,18 @@
17 18
18 + (PNLineChartDataItem *)dataItemWithY:(CGFloat)y 19 + (PNLineChartDataItem *)dataItemWithY:(CGFloat)y
19 { 20 {
20 - return [[PNLineChartDataItem alloc] initWithY:y]; 21 + return [[PNLineChartDataItem alloc] initWithY:y andRawY:y];
21 } 22 }
22 23
23 -- (id)initWithY:(CGFloat)y 24 ++ (PNLineChartDataItem *)dataItemWithY:(CGFloat)y andRawY:(CGFloat)rawY {
  25 + return [[PNLineChartDataItem alloc] initWithY:y andRawY:rawY];
  26 +}
  27 +
  28 +- (id)initWithY:(CGFloat)y andRawY:(CGFloat)rawY
24 { 29 {
25 if ((self = [super init])) { 30 if ((self = [super init])) {
26 self.y = y; 31 self.y = y;
  32 + self.rawY = rawY;
27 } 33 }
28 34
29 return self; 35 return self;