Joerg Polakowski

updated PNLineChart to allow the display of multiple lines in the chart

@@ -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
  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
  1 +//
  2 +// Created by Jörg Polakowski on 14/12/13.
  3 +// Copyright (c) 2013 kevinzhow. All rights reserved.
  4 +//
  5 +
  6 +#import "PNLineChartData.h"
  7 +
  8 +@implementation PNLineChartData
  9 +
  10 +@end
  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
  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 ```