updated PNLineChart to allow the display of multiple lines in the chart
Showing
9 changed files
with
294 additions
and
109 deletions
| @@ -30,6 +30,8 @@ | @@ -30,6 +30,8 @@ | ||
| 30 | 9F55483E18498E0E004073B5 /* PNCircleChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F55483D18498E0E004073B5 /* PNCircleChart.m */; }; | 30 | 9F55483E18498E0E004073B5 /* PNCircleChart.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F55483D18498E0E004073B5 /* PNCircleChart.m */; }; |
| 31 | 9F656B51184A4E34002E5675 /* UICountingLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F656B50184A4E34002E5675 /* UICountingLabel.m */; }; | 31 | 9F656B51184A4E34002E5675 /* UICountingLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F656B50184A4E34002E5675 /* UICountingLabel.m */; }; |
| 32 | 9FA23B10184A5944002DBBA4 /* PCChartsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FA23B0F184A5944002DBBA4 /* PCChartsTableViewController.m */; }; | 32 | 9FA23B10184A5944002DBBA4 /* PCChartsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FA23B0F184A5944002DBBA4 /* PCChartsTableViewController.m */; }; |
| 33 | + AF3EA32ACA7D5DAC2167CABD /* PNLineChartData.m in Sources */ = {isa = PBXBuildFile; fileRef = AF3EAE8875DCB1D0BDF690E0 /* PNLineChartData.m */; }; | ||
| 34 | + AF3EA5ABA289F1726E048CF0 /* PNLineChartDataItem.m in Sources */ = {isa = PBXBuildFile; fileRef = AF3EA2A586F5DB3F10DEF9C0 /* PNLineChartDataItem.m */; }; | ||
| 33 | /* End PBXBuildFile section */ | 35 | /* End PBXBuildFile section */ |
| 34 | 36 | ||
| 35 | /* Begin PBXContainerItemProxy section */ | 37 | /* Begin PBXContainerItemProxy section */ |
| @@ -81,6 +83,10 @@ | @@ -81,6 +83,10 @@ | ||
| 81 | 9FA23B0E184A5944002DBBA4 /* PCChartsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCChartsTableViewController.h; sourceTree = "<group>"; }; | 83 | 9FA23B0E184A5944002DBBA4 /* PCChartsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCChartsTableViewController.h; sourceTree = "<group>"; }; |
| 82 | 9FA23B0F184A5944002DBBA4 /* PCChartsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PCChartsTableViewController.m; sourceTree = "<group>"; }; | 84 | 9FA23B0F184A5944002DBBA4 /* PCChartsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PCChartsTableViewController.m; sourceTree = "<group>"; }; |
| 83 | 9FE9CFB818581102005B8223 /* PNChartDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PNChartDelegate.h; path = PNChart/PNChartDelegate.h; sourceTree = "<group>"; }; | 85 | 9FE9CFB818581102005B8223 /* PNChartDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PNChartDelegate.h; path = PNChart/PNChartDelegate.h; sourceTree = "<group>"; }; |
| 86 | + AF3EA2A586F5DB3F10DEF9C0 /* PNLineChartDataItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PNLineChartDataItem.m; sourceTree = "<group>"; }; | ||
| 87 | + AF3EA71805621F984344CF8D /* PNLineChartData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PNLineChartData.h; sourceTree = "<group>"; }; | ||
| 88 | + AF3EA9564304AC28E21019E4 /* PNLineChartDataItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PNLineChartDataItem.h; sourceTree = "<group>"; }; | ||
| 89 | + AF3EAE8875DCB1D0BDF690E0 /* PNLineChartData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PNLineChartData.m; sourceTree = "<group>"; }; | ||
| 84 | /* End PBXFileReference section */ | 90 | /* End PBXFileReference section */ |
| 85 | 91 | ||
| 86 | /* Begin PBXFrameworksBuildPhase section */ | 92 | /* Begin PBXFrameworksBuildPhase section */ |
| @@ -222,6 +228,10 @@ | @@ -222,6 +228,10 @@ | ||
| 222 | children = ( | 228 | children = ( |
| 223 | 0AF7A8B1182AC604003645C4 /* PNLineChart.h */, | 229 | 0AF7A8B1182AC604003645C4 /* PNLineChart.h */, |
| 224 | 0AF7A8B2182AC604003645C4 /* PNLineChart.m */, | 230 | 0AF7A8B2182AC604003645C4 /* PNLineChart.m */, |
| 231 | + AF3EA2A586F5DB3F10DEF9C0 /* PNLineChartDataItem.m */, | ||
| 232 | + AF3EAE8875DCB1D0BDF690E0 /* PNLineChartData.m */, | ||
| 233 | + AF3EA71805621F984344CF8D /* PNLineChartData.h */, | ||
| 234 | + AF3EA9564304AC28E21019E4 /* PNLineChartDataItem.h */, | ||
| 225 | ); | 235 | ); |
| 226 | name = PNLineChart; | 236 | name = PNLineChart; |
| 227 | sourceTree = "<group>"; | 237 | sourceTree = "<group>"; |
| @@ -357,6 +367,8 @@ | @@ -357,6 +367,8 @@ | ||
| 357 | 0AF7A8B3182AC604003645C4 /* PNLineChart.m in Sources */, | 367 | 0AF7A8B3182AC604003645C4 /* PNLineChart.m in Sources */, |
| 358 | 9F55483E18498E0E004073B5 /* PNCircleChart.m in Sources */, | 368 | 9F55483E18498E0E004073B5 /* PNCircleChart.m in Sources */, |
| 359 | 0AF7A878182AA9F6003645C4 /* PCAppDelegate.m in Sources */, | 369 | 0AF7A878182AA9F6003645C4 /* PCAppDelegate.m in Sources */, |
| 370 | + AF3EA5ABA289F1726E048CF0 /* PNLineChartDataItem.m in Sources */, | ||
| 371 | + AF3EA32ACA7D5DAC2167CABD /* PNLineChartData.m in Sources */, | ||
| 360 | ); | 372 | ); |
| 361 | runOnlyForDeploymentPostprocessing = 0; | 373 | runOnlyForDeploymentPostprocessing = 0; |
| 362 | }; | 374 | }; |
| @@ -8,6 +8,8 @@ | @@ -8,6 +8,8 @@ | ||
| 8 | 8 | ||
| 9 | #import "PCChartsTableViewController.h" | 9 | #import "PCChartsTableViewController.h" |
| 10 | #import "PNChart.h" | 10 | #import "PNChart.h" |
| 11 | +#import "PNLineChartData.h" | ||
| 12 | +#import "PNLineChartDataItem.h" | ||
| 11 | 13 | ||
| 12 | @interface PCChartsTableViewController () | 14 | @interface PCChartsTableViewController () |
| 13 | 15 | ||
| @@ -61,7 +63,26 @@ | @@ -61,7 +63,26 @@ | ||
| 61 | PNLineChart * lineChart = [[PNLineChart alloc] initWithFrame:CGRectMake(0, 135.0, SCREEN_WIDTH, 200.0)]; | 63 | PNLineChart * lineChart = [[PNLineChart alloc] initWithFrame:CGRectMake(0, 135.0, SCREEN_WIDTH, 200.0)]; |
| 62 | lineChart.backgroundColor = [UIColor clearColor]; | 64 | lineChart.backgroundColor = [UIColor clearColor]; |
| 63 | [lineChart setXLabels:@[@"SEP 1",@"SEP 2",@"SEP 3",@"SEP 4",@"SEP 5",@"SEP 6",@"SEP 7"]]; | 65 | [lineChart setXLabels:@[@"SEP 1",@"SEP 2",@"SEP 3",@"SEP 4",@"SEP 5",@"SEP 6",@"SEP 7"]]; |
| 64 | - [lineChart setYValues:@[@1,@24,@12,@18,@30,@10,@21]]; | 66 | + |
| 67 | + // Line Chart Nr.1 | ||
| 68 | + PNLineChartData *data01 = [PNLineChartData new]; | ||
| 69 | + data01.color = [UIColor redColor]; | ||
| 70 | + data01.itemCount = lineChart.xLabels.count; | ||
| 71 | + data01.getData = ^(NSUInteger item) { | ||
| 72 | + CGFloat y = item * 10; | ||
| 73 | + return [PNLineChartDataItem dataItemWithY:y]; | ||
| 74 | + }; | ||
| 75 | + | ||
| 76 | + // Line Chart Nr.2 | ||
| 77 | + PNLineChartData *data02 = [PNLineChartData new]; | ||
| 78 | + data02.color = [UIColor blueColor]; | ||
| 79 | + data02.itemCount = lineChart.xLabels.count; | ||
| 80 | + data02.getData = ^(NSUInteger item) { | ||
| 81 | + CGFloat y = item == 0 ? (item * 5) + 10 : (item * 5); | ||
| 82 | + return [PNLineChartDataItem dataItemWithY:y]; | ||
| 83 | + }; | ||
| 84 | + | ||
| 85 | + lineChart.chartData = @[data01, data02]; | ||
| 65 | [lineChart strokeChart]; | 86 | [lineChart strokeChart]; |
| 66 | 87 | ||
| 67 | lineChart.delegate = self; | 88 | lineChart.delegate = self; |
| @@ -29,7 +29,10 @@ | @@ -29,7 +29,10 @@ | ||
| 29 | 29 | ||
| 30 | @property (strong, nonatomic) NSArray * yLabels; | 30 | @property (strong, nonatomic) NSArray * yLabels; |
| 31 | 31 | ||
| 32 | -@property (strong, nonatomic) NSArray * yValues; | 32 | +/** |
| 33 | +* Array of `LineChartData` objects, one for each line. | ||
| 34 | +*/ | ||
| 35 | +@property (strong, nonatomic) NSArray *chartData; | ||
| 33 | 36 | ||
| 34 | @property (strong, nonatomic) NSMutableArray * pathPoints; | 37 | @property (strong, nonatomic) NSMutableArray * pathPoints; |
| 35 | 38 | ||
| @@ -41,10 +44,6 @@ | @@ -41,10 +44,6 @@ | ||
| 41 | 44 | ||
| 42 | @property (nonatomic) float xLabelHeight; | 45 | @property (nonatomic) float xLabelHeight; |
| 43 | 46 | ||
| 44 | -@property (nonatomic,strong) CAShapeLayer * chartLine; | ||
| 45 | - | ||
| 46 | -@property (nonatomic, strong) UIColor * strokeColor; | ||
| 47 | - | ||
| 48 | @property (nonatomic) BOOL showLabel; | 47 | @property (nonatomic) BOOL showLabel; |
| 49 | 48 | ||
| 50 | @property (nonatomic, strong) UIBezierPath *progressline; | 49 | @property (nonatomic, strong) UIBezierPath *progressline; |
| @@ -9,61 +9,50 @@ | @@ -9,61 +9,50 @@ | ||
| 9 | #import "PNLineChart.h" | 9 | #import "PNLineChart.h" |
| 10 | #import "PNColor.h" | 10 | #import "PNColor.h" |
| 11 | #import "PNChartLabel.h" | 11 | #import "PNChartLabel.h" |
| 12 | +#import "PNLineChartData.h" | ||
| 13 | +#import "PNLineChartDataItem.h" | ||
| 12 | 14 | ||
| 15 | + | ||
| 16 | +//------------------------------------------------------------------------------------------------ | ||
| 17 | +// private interface declaration | ||
| 18 | +//------------------------------------------------------------------------------------------------ | ||
| 19 | +@interface PNLineChart () | ||
| 20 | + | ||
| 21 | +@property (nonatomic,strong) NSMutableArray *chartLineArray; // Array[CAShapeLayer] | ||
| 22 | + | ||
| 23 | +- (void)setDefaultValues; | ||
| 24 | + | ||
| 25 | +@end | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +//------------------------------------------------------------------------------------------------ | ||
| 29 | +// public interface implementation | ||
| 30 | +//------------------------------------------------------------------------------------------------ | ||
| 13 | @implementation PNLineChart | 31 | @implementation PNLineChart |
| 14 | 32 | ||
| 15 | -- (id)initWithFrame:(CGRect)frame | 33 | +#pragma mark initialization |
| 16 | -{ | 34 | + |
| 17 | - self = [super initWithFrame:frame]; | 35 | +- (id)initWithCoder:(NSCoder *)coder { |
| 36 | + self = [super initWithCoder:coder]; | ||
| 18 | if (self) { | 37 | if (self) { |
| 19 | - // Initialization code | 38 | + [self setDefaultValues]; |
| 20 | - self.backgroundColor = [UIColor whiteColor]; | ||
| 21 | - self.clipsToBounds = YES; | ||
| 22 | - _chartLine = [CAShapeLayer layer]; | ||
| 23 | - _chartLine.lineCap = kCALineCapRound; | ||
| 24 | - _chartLine.lineJoin = kCALineJoinBevel; | ||
| 25 | - _chartLine.fillColor = [[UIColor whiteColor] CGColor]; | ||
| 26 | - _chartLine.lineWidth = 3.0; | ||
| 27 | - _chartLine.strokeEnd = 0.0; | ||
| 28 | - _showLabel = YES; | ||
| 29 | - _pathPoints = [[NSMutableArray alloc] init]; | ||
| 30 | - self.userInteractionEnabled = YES; | ||
| 31 | - _xLabelHeight = 20.0; | ||
| 32 | - _chartCavanHeight = self.frame.size.height - chartMargin * 2 - _xLabelHeight*2 ; | ||
| 33 | - [self.layer addSublayer:_chartLine]; | ||
| 34 | } | 39 | } |
| 35 | - | ||
| 36 | return self; | 40 | return self; |
| 37 | } | 41 | } |
| 38 | 42 | ||
| 39 | --(void)setYValues:(NSArray *)yValues | 43 | +- (id)initWithFrame:(CGRect)frame { |
| 40 | -{ | 44 | + self = [super initWithFrame:frame]; |
| 41 | - _yValues = yValues; | 45 | + if (self) { |
| 42 | - | 46 | + [self setDefaultValues]; |
| 43 | - float max = 0; | ||
| 44 | - for (NSString * valueString in yValues) { | ||
| 45 | - float value = [valueString floatValue]; | ||
| 46 | - if (value > max) { | ||
| 47 | - max = value; | ||
| 48 | - } | ||
| 49 | - } | ||
| 50 | - | ||
| 51 | - //Min value for Y label | ||
| 52 | - if (max < 5) { | ||
| 53 | - max = 5; | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - _yValueMax = (float)max; | ||
| 57 | - | ||
| 58 | - if (_showLabel) { | ||
| 59 | - [self setYLabels:yValues]; | ||
| 60 | } | 47 | } |
| 61 | - | 48 | + return self; |
| 62 | } | 49 | } |
| 63 | 50 | ||
| 51 | +#pragma mark instance methods | ||
| 52 | + | ||
| 64 | -(void)setYLabels:(NSArray *)yLabels | 53 | -(void)setYLabels:(NSArray *)yLabels |
| 65 | { | 54 | { |
| 66 | - | 55 | + |
| 67 | float level = _yValueMax / 5.0; | 56 | float level = _yValueMax / 5.0; |
| 68 | 57 | ||
| 69 | NSInteger index = 0; | 58 | NSInteger index = 0; |
| @@ -99,12 +88,6 @@ | @@ -99,12 +88,6 @@ | ||
| 99 | 88 | ||
| 100 | } | 89 | } |
| 101 | 90 | ||
| 102 | --(void)setStrokeColor:(UIColor *)strokeColor | ||
| 103 | -{ | ||
| 104 | - _strokeColor = strokeColor; | ||
| 105 | - _chartLine.strokeColor = [strokeColor CGColor]; | ||
| 106 | -} | ||
| 107 | - | ||
| 108 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event | 91 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event |
| 109 | { | 92 | { |
| 110 | [self chechPoint:touches withEvent:event]; | 93 | [self chechPoint:touches withEvent:event]; |
| @@ -136,65 +119,132 @@ | @@ -136,65 +119,132 @@ | ||
| 136 | 119 | ||
| 137 | -(void)strokeChart | 120 | -(void)strokeChart |
| 138 | { | 121 | { |
| 139 | - UIGraphicsBeginImageContext(self.frame.size); | 122 | + for (NSUInteger a = 0; a < self.chartData.count; a++) { |
| 140 | - | 123 | + PNLineChartData *chartData = self.chartData[a]; |
| 141 | - _progressline = [UIBezierPath bezierPath]; | 124 | + CAShapeLayer *chartLine = (CAShapeLayer *) self.chartLineArray[a]; |
| 142 | - | ||
| 143 | - CGFloat firstValue = [[_yValues objectAtIndex:0] floatValue]; | ||
| 144 | - | ||
| 145 | - CGFloat xPosition = _xLabelWidth; | ||
| 146 | - | ||
| 147 | - if(!_showLabel){ | ||
| 148 | - _chartCavanHeight = self.frame.size.height - _xLabelHeight*2; | ||
| 149 | - xPosition = 0; | ||
| 150 | - } | ||
| 151 | - | ||
| 152 | - float grade = (float)firstValue / (float)_yValueMax; | ||
| 153 | - | ||
| 154 | 125 | ||
| 155 | - [_progressline moveToPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)]; | 126 | + UIGraphicsBeginImageContext(self.frame.size); |
| 156 | - [_pathPoints addObject:[NSValue valueWithCGPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)]]; | 127 | + |
| 157 | - [_progressline setLineWidth:3.0]; | 128 | + _progressline = [UIBezierPath bezierPath]; |
| 158 | - [_progressline setLineCapStyle:kCGLineCapRound]; | 129 | + |
| 159 | - [_progressline setLineJoinStyle:kCGLineJoinRound]; | 130 | + PNLineChartDataItem *firstDataItem = chartData.getData(0); |
| 160 | - NSInteger index = 0; | 131 | + CGFloat firstValue = firstDataItem.y; |
| 161 | - for (NSString * valueString in _yValues) { | 132 | + |
| 162 | - float value = [valueString floatValue]; | 133 | + CGFloat xPosition = _xLabelWidth; |
| 163 | - | 134 | + |
| 164 | - float grade = (float)value / (float)_yValueMax; | 135 | + if(!_showLabel){ |
| 165 | - if (index != 0) { | 136 | + _chartCavanHeight = self.frame.size.height - _xLabelHeight*2; |
| 166 | - | 137 | + xPosition = 0; |
| 167 | - | 138 | + } |
| 168 | - CGPoint point = CGPointMake(index * _xLabelWidth + 30.0 + _xLabelWidth /2.0, _chartCavanHeight - (grade * _chartCavanHeight) + _xLabelHeight); | 139 | + |
| 169 | - [_pathPoints addObject:[NSValue valueWithCGPoint:point]]; | 140 | + CGFloat grade = (float)firstValue / _yValueMax; |
| 170 | - [_progressline addLineToPoint:point]; | 141 | + |
| 171 | - [_progressline moveToPoint:point]; | 142 | + [_progressline moveToPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)]; |
| 143 | + [_pathPoints addObject:[NSValue valueWithCGPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)]]; | ||
| 144 | + [_progressline setLineWidth:3.0]; | ||
| 145 | + [_progressline setLineCapStyle:kCGLineCapRound]; | ||
| 146 | + [_progressline setLineJoinStyle:kCGLineJoinRound]; | ||
| 147 | + | ||
| 148 | + NSInteger index = 0; | ||
| 149 | + for (NSUInteger i = 0; i < chartData.itemCount; i++) { | ||
| 150 | + | ||
| 151 | + PNLineChartDataItem *dataItem = chartData.getData(i); | ||
| 152 | + float value = dataItem.y; | ||
| 153 | + | ||
| 154 | + CGFloat innerGrade = value / _yValueMax; | ||
| 155 | + if (index != 0) { | ||
| 156 | + CGPoint point = CGPointMake(index * _xLabelWidth + 30.0 + _xLabelWidth / 2.0, _chartCavanHeight - (innerGrade * _chartCavanHeight) + _xLabelHeight); | ||
| 157 | + [_pathPoints addObject:[NSValue valueWithCGPoint:point]]; | ||
| 158 | + [_progressline addLineToPoint:point]; | ||
| 159 | + [_progressline moveToPoint:point]; | ||
| 160 | + } | ||
| 161 | + index += 1; | ||
| 172 | } | 162 | } |
| 173 | - | 163 | + |
| 174 | - index += 1; | 164 | + // setup the color of the chart line |
| 165 | + if (chartData.color) { | ||
| 166 | + chartLine.strokeColor = [chartData.color CGColor]; | ||
| 167 | + }else{ | ||
| 168 | + chartLine.strokeColor = [PNGreen CGColor]; | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + [_progressline stroke]; | ||
| 172 | + | ||
| 173 | + chartLine.path = _progressline.CGPath; | ||
| 174 | + | ||
| 175 | + CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; | ||
| 176 | + pathAnimation.duration = 1.0; | ||
| 177 | + pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; | ||
| 178 | + pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; | ||
| 179 | + pathAnimation.toValue = [NSNumber numberWithFloat:1.0f]; | ||
| 180 | + [chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; | ||
| 181 | + | ||
| 182 | + chartLine.strokeEnd = 1.0; | ||
| 183 | + | ||
| 184 | + UIGraphicsEndImageContext(); | ||
| 175 | } | 185 | } |
| 176 | - [_progressline stroke]; | ||
| 177 | - | ||
| 178 | - _chartLine.path = _progressline.CGPath; | ||
| 179 | - if (_strokeColor) { | ||
| 180 | - _chartLine.strokeColor = [_strokeColor CGColor]; | ||
| 181 | - }else{ | ||
| 182 | - _chartLine.strokeColor = [PNGreen CGColor]; | ||
| 183 | - } | ||
| 184 | - | ||
| 185 | - | ||
| 186 | - CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; | ||
| 187 | - pathAnimation.duration = 1.0; | ||
| 188 | - pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; | ||
| 189 | - pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; | ||
| 190 | - pathAnimation.toValue = [NSNumber numberWithFloat:1.0f]; | ||
| 191 | - [_chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; | ||
| 192 | - | ||
| 193 | - _chartLine.strokeEnd = 1.0; | ||
| 194 | - | ||
| 195 | - UIGraphicsEndImageContext(); | ||
| 196 | } | 186 | } |
| 197 | 187 | ||
| 188 | +- (void)setChartData:(NSArray *)data { | ||
| 189 | + if (data != _chartData) { | ||
| 190 | + | ||
| 191 | + NSMutableArray *yLabelsArray = [NSMutableArray arrayWithCapacity:data.count]; | ||
| 192 | + CGFloat yMax = 0.0f; | ||
| 193 | + | ||
| 194 | + // remove all shape layers before adding new ones | ||
| 195 | + for (CALayer *layer in self.chartLineArray) { | ||
| 196 | + [layer removeFromSuperlayer]; | ||
| 197 | + } | ||
| 198 | + self.chartLineArray = [NSMutableArray arrayWithCapacity:data.count]; | ||
| 199 | + | ||
| 200 | + for (PNLineChartData *chartData in data) { | ||
| 201 | + | ||
| 202 | + // create as many chart line layers as there are data-lines | ||
| 203 | + CAShapeLayer *chartLine = [CAShapeLayer layer]; | ||
| 204 | + chartLine.lineCap = kCALineCapRound; | ||
| 205 | + chartLine.lineJoin = kCALineJoinBevel; | ||
| 206 | + chartLine.fillColor = [[UIColor whiteColor] CGColor]; | ||
| 207 | + chartLine.lineWidth = 3.0; | ||
| 208 | + chartLine.strokeEnd = 0.0; | ||
| 209 | + [self.layer addSublayer:chartLine]; | ||
| 210 | + [self.chartLineArray addObject:chartLine]; | ||
| 211 | + | ||
| 212 | + for (NSUInteger i = 0; i < chartData.itemCount; i++) { | ||
| 213 | + PNLineChartDataItem *dataItem = chartData.getData(i); | ||
| 214 | + CGFloat yValue = dataItem.y; | ||
| 215 | + [yLabelsArray addObject:[NSString stringWithFormat:@"%2f", yValue]]; | ||
| 216 | + yMax = fmaxf(yMax, dataItem.y); | ||
| 217 | + } | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + // Min value for Y label | ||
| 221 | + if (yMax < 5) { | ||
| 222 | + yMax = 5.0f; | ||
| 223 | + } | ||
| 224 | + _yValueMax = yMax; | ||
| 225 | + | ||
| 226 | + _chartData = data; | ||
| 227 | + | ||
| 228 | + if (_showLabel) { | ||
| 229 | + [self setYLabels:yLabelsArray]; | ||
| 230 | + } | ||
| 198 | 231 | ||
| 232 | + [self setNeedsDisplay]; | ||
| 233 | + } | ||
| 234 | +} | ||
| 235 | + | ||
| 236 | +#pragma mark private methods | ||
| 237 | + | ||
| 238 | +- (void)setDefaultValues { | ||
| 239 | + // Initialization code | ||
| 240 | + self.backgroundColor = [UIColor whiteColor]; | ||
| 241 | + self.clipsToBounds = YES; | ||
| 242 | + self.chartLineArray = [NSMutableArray new]; | ||
| 243 | + _showLabel = YES; | ||
| 244 | + _pathPoints = [[NSMutableArray alloc] init]; | ||
| 245 | + self.userInteractionEnabled = YES; | ||
| 246 | + _xLabelHeight = 20.0; | ||
| 247 | + _chartCavanHeight = self.frame.size.height - chartMargin * 2 - _xLabelHeight*2 ; | ||
| 248 | +} | ||
| 199 | 249 | ||
| 200 | @end | 250 | @end |
PNChartDemo/PNLineChartData.h
0 → 100644
| 1 | +// | ||
| 2 | +// Created by Jörg Polakowski on 14/12/13. | ||
| 3 | +// Copyright (c) 2013 kevinzhow. All rights reserved. | ||
| 4 | +// | ||
| 5 | + | ||
| 6 | +#import <Foundation/Foundation.h> | ||
| 7 | + | ||
| 8 | +@class PNLineChartDataItem; | ||
| 9 | + | ||
| 10 | + | ||
| 11 | +typedef PNLineChartDataItem *(^LCLineChartDataGetter)(NSUInteger item); | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | +* | ||
| 15 | +*/ | ||
| 16 | +@interface PNLineChartData : NSObject | ||
| 17 | + | ||
| 18 | +@property (strong) UIColor *color; | ||
| 19 | + | ||
| 20 | +@property NSUInteger itemCount; | ||
| 21 | + | ||
| 22 | +@property (copy) LCLineChartDataGetter getData; | ||
| 23 | + | ||
| 24 | +@end |
PNChartDemo/PNLineChartData.m
0 → 100644
PNChartDemo/PNLineChartDataItem.h
0 → 100644
| 1 | +// | ||
| 2 | +// Created by Jörg Polakowski on 14/12/13. | ||
| 3 | +// Copyright (c) 2013 kevinzhow. All rights reserved. | ||
| 4 | +// | ||
| 5 | + | ||
| 6 | +#import <Foundation/Foundation.h> | ||
| 7 | + | ||
| 8 | +@interface PNLineChartDataItem : NSObject | ||
| 9 | + | ||
| 10 | +@property (readonly) CGFloat y; // should be within the y range | ||
| 11 | + | ||
| 12 | ++ (PNLineChartDataItem *)dataItemWithY:(CGFloat)y; | ||
| 13 | + | ||
| 14 | +@end |
PNChartDemo/PNLineChartDataItem.m
0 → 100644
| 1 | +// | ||
| 2 | +// Created by Jörg Polakowski on 14/12/13. | ||
| 3 | +// Copyright (c) 2013 kevinzhow. All rights reserved. | ||
| 4 | +// | ||
| 5 | + | ||
| 6 | +#import "PNLineChartDataItem.h" | ||
| 7 | + | ||
| 8 | +//------------------------------------------------------------------------------------------------ | ||
| 9 | +// private interface declaration | ||
| 10 | +//------------------------------------------------------------------------------------------------ | ||
| 11 | +@interface PNLineChartDataItem () | ||
| 12 | + | ||
| 13 | +@property (readwrite) CGFloat y; // should be within the y range | ||
| 14 | + | ||
| 15 | +- (id)initWithY:(CGFloat)y; | ||
| 16 | + | ||
| 17 | +@end | ||
| 18 | + | ||
| 19 | +//------------------------------------------------------------------------------------------------ | ||
| 20 | +// public interface implementation | ||
| 21 | +//------------------------------------------------------------------------------------------------ | ||
| 22 | +@implementation PNLineChartDataItem | ||
| 23 | + | ||
| 24 | ++ (PNLineChartDataItem *)dataItemWithY:(CGFloat)y { | ||
| 25 | + return [[PNLineChartDataItem alloc] initWithY:y]; | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +- (id)initWithY:(CGFloat)y { | ||
| 29 | + if ((self = [super init])) { | ||
| 30 | + self.y = y; | ||
| 31 | + } | ||
| 32 | + return self; | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | + | ||
| 36 | +@end |
| @@ -40,7 +40,26 @@ You will need LLVM 3.0 or later in order to build PNChart. | @@ -40,7 +40,26 @@ You will need LLVM 3.0 or later in order to build PNChart. | ||
| 40 | //For LineChart | 40 | //For LineChart |
| 41 | PNLineChart * lineChart = [[PNLineChart alloc] initWithFrame:CGRectMake(0, 135.0, SCREEN_WIDTH, 200.0)]; | 41 | PNLineChart * lineChart = [[PNLineChart alloc] initWithFrame:CGRectMake(0, 135.0, SCREEN_WIDTH, 200.0)]; |
| 42 | [lineChart setXLabels:@[@"SEP 1",@"SEP 2",@"SEP 3",@"SEP 4",@"SEP 5"]]; | 42 | [lineChart setXLabels:@[@"SEP 1",@"SEP 2",@"SEP 3",@"SEP 4",@"SEP 5"]]; |
| 43 | - [lineChart setYValues:@[@1, @10, @2, @6, @3]]; | 43 | + |
| 44 | + // Line Chart Nr.1 | ||
| 45 | + PNLineChartData *data01 = [PNLineChartData new]; | ||
| 46 | + data01.color = [UIColor redColor]; | ||
| 47 | + data01.itemCount = lineChart.xLabels.count; | ||
| 48 | + data01.getData = ^(NSUInteger item) { | ||
| 49 | + CGFloat y = item * 10; | ||
| 50 | + return [PNLineChartDataItem dataItemWithY:y]; | ||
| 51 | + }; | ||
| 52 | + | ||
| 53 | + // Line Chart Nr.2 | ||
| 54 | + PNLineChartData *data02 = [PNLineChartData new]; | ||
| 55 | + data02.color = [UIColor blueColor]; | ||
| 56 | + data02.itemCount = lineChart.xLabels.count; | ||
| 57 | + data02.getData = ^(NSUInteger item) { | ||
| 58 | + CGFloat y = item == 0 ? (item * 5) + 10 : (item * 5); | ||
| 59 | + return [PNLineChartDataItem dataItemWithY:y]; | ||
| 60 | + }; | ||
| 61 | + | ||
| 62 | + lineChart.chartData = @[data01, data02]; | ||
| 44 | [lineChart strokeChart]; | 63 | [lineChart strokeChart]; |
| 45 | 64 | ||
| 46 | ``` | 65 | ``` |
-
Please register or login to post a comment