Kevin

Merge pull request #31 from Np2x/master

fixed #29, #24 & #23
... ... @@ -11,6 +11,8 @@
#import "PNChart.h"
#import "PNColor.h"
#import "PNLineChart.h"
#import "PNLineChartData.h"
#import "PNLineChartDataItem.h"
#import "PNBarChart.h"
#import "PNCircleChart.h"
#import "PNChartDelegate.h"
... ...
... ... @@ -11,9 +11,8 @@
#import <QuartzCore/QuartzCore.h>
#import "PNChartDelegate.h"
#define chartMargin 10
#define yLabelMargin 15
#define yLabelHeight 11
@interface PNLineChart : UIView
... ... @@ -30,19 +29,29 @@
@property (strong, nonatomic) NSArray * yLabels;
/**
* Array of `LineChartData` objects, one for each line.
*/
* Array of `LineChartData` objects, one for each line.
*/
@property (strong, nonatomic) NSArray *chartData;
@property (strong, nonatomic) NSMutableArray * pathPoints;
@property (nonatomic) CGFloat xLabelWidth;
@property (nonatomic) float yValueMax;
@property (nonatomic) CGFloat yValueMax;
@property (nonatomic) CGFloat yValueMin;
@property (nonatomic) NSInteger yLabelNum;
@property (nonatomic) CGFloat yLabelHeight;
@property (nonatomic) CGFloat chartCavanHeight;
@property (nonatomic) CGFloat chartCavanWidth;
@property (nonatomic) CGFloat chartMargin;
@property (nonatomic) float chartCavanHeight;
@property (nonatomic) float xLabelHeight;
@property (nonatomic) BOOL showLabel;
... ...
... ... @@ -54,34 +54,35 @@
-(void)setYLabels:(NSArray *)yLabels
{
float level = _yValueMax / 5.0;
CGFloat yStep = (_yValueMax-_yValueMin) / _yLabelNum;
CGFloat yStepHeight = _chartCavanHeight / _yLabelNum;
NSInteger index = 0;
NSInteger num = [yLabels count] + 1;
NSInteger num = _yLabelNum+1;
while (num > 0) {
CGFloat levelHeight = _chartCavanHeight /5.0;
PNChartLabel * label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0,_chartCavanHeight - index * levelHeight + (levelHeight - yLabelHeight) , 20.0, yLabelHeight)];
PNChartLabel * label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (_chartCavanHeight - index * yStepHeight), _chartMargin, _yLabelHeight)];
[label setTextAlignment:NSTextAlignmentRight];
label.text = [NSString stringWithFormat:@"%1.f",level * index];
label.text = [NSString stringWithFormat:@"%1.f",_yValueMin + (yStep * index)];
[self addSubview:label];
index +=1 ;
num -= 1;
}
}
-(void)setXLabels:(NSArray *)xLabels
{
_xLabels = xLabels;
NSString* labelText;
if(_showLabel){
_xLabelWidth = (self.frame.size.width - chartMargin - 30.0)/[xLabels count];
_xLabelWidth = _chartCavanWidth/[xLabels count];
for(int index = 0; index < xLabels.count; index++)
{
NSString* labelText = xLabels[index];
PNChartLabel * label = [[PNChartLabel alloc] initWithFrame:CGRectMake(index * _xLabelWidth + 30.0, self.frame.size.height - 30.0, _xLabelWidth, 20.0)];
labelText = xLabels[index];
PNChartLabel * label = [[PNChartLabel alloc] initWithFrame:CGRectMake(2*_chartMargin + (index * _xLabelWidth) - (_xLabelWidth / 2), _chartMargin + _chartCavanHeight, _xLabelWidth, _chartMargin)];
[label setTextAlignment:NSTextAlignmentCenter];
label.text = labelText;
[self addSubview:label];
... ... @@ -137,44 +138,45 @@
for (NSUInteger lineIndex = 0; lineIndex < self.chartData.count; lineIndex++) {
PNLineChartData *chartData = self.chartData[lineIndex];
CAShapeLayer *chartLine = (CAShapeLayer *) self.chartLineArray[lineIndex];
CGFloat yValue;
CGFloat innerGrade;
CGPoint point;
UIGraphicsBeginImageContext(self.frame.size);
UIBezierPath * progressline = [UIBezierPath bezierPath];
[_chartPath addObject:progressline];
PNLineChartDataItem *firstDataItem = chartData.getData(0);
CGFloat firstValue = firstDataItem.y;
CGFloat xPosition = _xLabelWidth;
if(!_showLabel){
_chartCavanHeight = self.frame.size.height - _xLabelHeight*2;
xPosition = 0;
_chartCavanHeight = self.frame.size.height - 2*_yLabelHeight;
_chartCavanWidth = self.frame.size.width;
_chartMargin = 0.0;
_xLabelWidth = (_chartCavanWidth / ([_xLabels count] -1));
}
CGFloat grade = (float)firstValue / _yValueMax;
NSMutableArray * linePointsArray = [[NSMutableArray alloc] init];
[progressline moveToPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)];
[linePointsArray addObject:[NSValue valueWithCGPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)]];
[progressline setLineWidth:3.0];
[progressline setLineCapStyle:kCGLineCapRound];
[progressline setLineJoinStyle:kCGLineJoinRound];
NSInteger index = 0;
for (NSUInteger i = 0; i < chartData.itemCount; i++) {
PNLineChartDataItem *dataItem = chartData.getData(i);
float value = dataItem.y;
CGFloat innerGrade = value / _yValueMax;
if (index != 0) {
CGPoint point = CGPointMake(index * _xLabelWidth + 30.0 + _xLabelWidth / 2.0, _chartCavanHeight - (innerGrade * _chartCavanHeight) + _xLabelHeight);
[linePointsArray addObject:[NSValue valueWithCGPoint:point]];
yValue = chartData.getData(i).y;
innerGrade = (yValue - _yValueMin) / ( _yValueMax - _yValueMin);
point = CGPointMake(2*_chartMargin + (i * _xLabelWidth), _chartCavanHeight - (innerGrade * _chartCavanHeight) + ( _yLabelHeight /2 ));
if (i != 0) {
[progressline addLineToPoint:point];
[progressline moveToPoint:point];
}
index += 1;
[progressline moveToPoint:point];
[linePointsArray addObject:[NSValue valueWithCGPoint:point]];
}
[_pathPoints addObject:[linePointsArray copy]];
// setup the color of the chart line
... ... @@ -183,38 +185,39 @@
}else{
chartLine.strokeColor = [PNGreen CGColor];
}
[progressline stroke];
chartLine.path = progressline.CGPath;
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration = 1.0;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
[chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
chartLine.strokeEnd = 1.0;
UIGraphicsEndImageContext();
}
}
- (void)setChartData:(NSArray *)data {
if (data != _chartData) {
NSMutableArray *yLabelsArray = [NSMutableArray arrayWithCapacity:data.count];
CGFloat yMax = 0.0f;
CGFloat yMin = MAXFLOAT;
CGFloat yValue;
// remove all shape layers before adding new ones
for (CALayer *layer in self.chartLineArray) {
[layer removeFromSuperlayer];
}
self.chartLineArray = [NSMutableArray arrayWithCapacity:data.count];
for (PNLineChartData *chartData in data) {
// create as many chart line layers as there are data-lines
CAShapeLayer *chartLine = [CAShapeLayer layer];
chartLine.lineCap = kCALineCapRound;
... ... @@ -224,27 +227,32 @@
chartLine.strokeEnd = 0.0;
[self.layer addSublayer:chartLine];
[self.chartLineArray addObject:chartLine];
for (NSUInteger i = 0; i < chartData.itemCount; i++) {
PNLineChartDataItem *dataItem = chartData.getData(i);
CGFloat yValue = dataItem.y;
yValue = chartData.getData(i).y;
[yLabelsArray addObject:[NSString stringWithFormat:@"%2f", yValue]];
yMax = fmaxf(yMax, dataItem.y);
yMax = fmaxf(yMax, yValue);
yMin = fminf(yMin, yValue);
}
}
// Min value for Y label
if (yMax < 5) {
yMax = 5.0f;
}
if (yMin < 0){
yMin = 0.0f;
}
_yValueMin = yMin;
_yValueMax = yMax;
_chartData = data;
if (_showLabel) {
[self setYLabels:yLabelsArray];
}
[self setNeedsDisplay];
}
}
... ... @@ -259,8 +267,14 @@
_showLabel = YES;
_pathPoints = [[NSMutableArray alloc] init];
self.userInteractionEnabled = YES;
_xLabelHeight = 20.0;
_chartCavanHeight = self.frame.size.height - chartMargin * 2 - _xLabelHeight*2 ;
_yLabelNum = 5.0;
_yLabelHeight = [[[[PNChartLabel alloc] init] font] pointSize];
_chartMargin = 30;
_chartCavanWidth = self.frame.size.width - _chartMargin *2;
_chartCavanHeight = self.frame.size.height - _chartMargin * 2;
}
@end
... ...