Merge pull request #250 from pkclsoft/master
Enhancements to Bar and Line Charts
Showing
10 changed files
with
110 additions
and
67 deletions
PNChart/PNBar.h
100644 → 100755
| @@ -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 |
PNChart/PNBar.m
100644 → 100755
| @@ -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; |
PNChart/PNBarChart.h
100644 → 100755
| @@ -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 |
PNChart/PNBarChart.m
100644 → 100755
| @@ -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; |
PNChart/PNLineChart.h
100644 → 100755
| @@ -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. |
PNChart/PNLineChart.m
100644 → 100755
| @@ -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 |
PNChart/PNLineChartData.h
100644 → 100755
| @@ -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 | /** |
PNChart/PNLineChartData.m
100644 → 100755
| @@ -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 |
PNChart/PNLineChartDataItem.h
100644 → 100755
| @@ -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 |
PNChart/PNLineChartDataItem.m
100644 → 100755
| @@ -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; |
-
Please register or login to post a comment