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,58 +9,47 @@ @@ -9,58 +9,47 @@
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
13 -@implementation PNLineChart  
14 15
15 -- (id)initWithFrame:(CGRect)frame 16 +//------------------------------------------------------------------------------------------------
16 -{ 17 +// private interface declaration
17 - self = [super initWithFrame:frame]; 18 +//------------------------------------------------------------------------------------------------
18 - if (self) { 19 +@interface PNLineChart ()
19 - // Initialization code  
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 - }  
35 20
36 - return self; 21 +@property (nonatomic,strong) NSMutableArray *chartLineArray; // Array[CAShapeLayer]
37 -}  
38 22
39 --(void)setYValues:(NSArray *)yValues 23 +- (void)setDefaultValues;
40 -{  
41 - _yValues = yValues;  
42 24
43 - float max = 0; 25 +@end
44 - for (NSString * valueString in yValues) {  
45 - float value = [valueString floatValue];  
46 - if (value > max) {  
47 - max = value;  
48 - }  
49 - }  
50 26
51 - //Min value for Y label  
52 - if (max < 5) {  
53 - max = 5;  
54 - }  
55 27
56 - _yValueMax = (float)max; 28 +//------------------------------------------------------------------------------------------------
  29 +// public interface implementation
  30 +//------------------------------------------------------------------------------------------------
  31 +@implementation PNLineChart
57 32
58 - if (_showLabel) { 33 +#pragma mark initialization
59 - [self setYLabels:yValues]; 34 +
  35 +- (id)initWithCoder:(NSCoder *)coder {
  36 + self = [super initWithCoder:coder];
  37 + if (self) {
  38 + [self setDefaultValues];
60 } 39 }
  40 + return self;
  41 +}
61 42
  43 +- (id)initWithFrame:(CGRect)frame {
  44 + self = [super initWithFrame:frame];
  45 + if (self) {
  46 + [self setDefaultValues];
  47 + }
  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
@@ -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,11 +119,16 @@ @@ -136,11 +119,16 @@
136 119
137 -(void)strokeChart 120 -(void)strokeChart
138 { 121 {
  122 + for (NSUInteger a = 0; a < self.chartData.count; a++) {
  123 + PNLineChartData *chartData = self.chartData[a];
  124 + CAShapeLayer *chartLine = (CAShapeLayer *) self.chartLineArray[a];
  125 +
139 UIGraphicsBeginImageContext(self.frame.size); 126 UIGraphicsBeginImageContext(self.frame.size);
140 127
141 _progressline = [UIBezierPath bezierPath]; 128 _progressline = [UIBezierPath bezierPath];
142 129
143 - CGFloat firstValue = [[_yValues objectAtIndex:0] floatValue]; 130 + PNLineChartDataItem *firstDataItem = chartData.getData(0);
  131 + CGFloat firstValue = firstDataItem.y;
144 132
145 CGFloat xPosition = _xLabelWidth; 133 CGFloat xPosition = _xLabelWidth;
146 134
@@ -149,52 +137,114 @@ @@ -149,52 +137,114 @@
149 xPosition = 0; 137 xPosition = 0;
150 } 138 }
151 139
152 - float grade = (float)firstValue / (float)_yValueMax; 140 + CGFloat grade = (float)firstValue / _yValueMax;
153 -  
154 141
155 [_progressline moveToPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)]; 142 [_progressline moveToPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)];
156 [_pathPoints addObject:[NSValue valueWithCGPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)]]; 143 [_pathPoints addObject:[NSValue valueWithCGPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)]];
157 [_progressline setLineWidth:3.0]; 144 [_progressline setLineWidth:3.0];
158 [_progressline setLineCapStyle:kCGLineCapRound]; 145 [_progressline setLineCapStyle:kCGLineCapRound];
159 [_progressline setLineJoinStyle:kCGLineJoinRound]; 146 [_progressline setLineJoinStyle:kCGLineJoinRound];
160 - NSInteger index = 0;  
161 - for (NSString * valueString in _yValues) {  
162 - float value = [valueString floatValue];  
163 147
164 - float grade = (float)value / (float)_yValueMax; 148 + NSInteger index = 0;
165 - if (index != 0) { 149 + for (NSUInteger i = 0; i < chartData.itemCount; i++) {
166 150
  151 + PNLineChartDataItem *dataItem = chartData.getData(i);
  152 + float value = dataItem.y;
167 153
168 - CGPoint point = CGPointMake(index * _xLabelWidth + 30.0 + _xLabelWidth /2.0, _chartCavanHeight - (grade * _chartCavanHeight) + _xLabelHeight); 154 + CGFloat innerGrade = value / _yValueMax;
  155 + if (index != 0) {
  156 + CGPoint point = CGPointMake(index * _xLabelWidth + 30.0 + _xLabelWidth / 2.0, _chartCavanHeight - (innerGrade * _chartCavanHeight) + _xLabelHeight);
169 [_pathPoints addObject:[NSValue valueWithCGPoint:point]]; 157 [_pathPoints addObject:[NSValue valueWithCGPoint:point]];
170 [_progressline addLineToPoint:point]; 158 [_progressline addLineToPoint:point];
171 [_progressline moveToPoint:point]; 159 [_progressline moveToPoint:point];
172 } 160 }
173 -  
174 index += 1; 161 index += 1;
175 } 162 }
176 - [_progressline stroke];  
177 163
178 - _chartLine.path = _progressline.CGPath; 164 + // setup the color of the chart line
179 - if (_strokeColor) { 165 + if (chartData.color) {
180 - _chartLine.strokeColor = [_strokeColor CGColor]; 166 + chartLine.strokeColor = [chartData.color CGColor];
181 }else{ 167 }else{
182 - _chartLine.strokeColor = [PNGreen CGColor]; 168 + chartLine.strokeColor = [PNGreen CGColor];
183 } 169 }
184 170
  171 + [_progressline stroke];
  172 +
  173 + chartLine.path = _progressline.CGPath;
185 174
186 CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 175 CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
187 pathAnimation.duration = 1.0; 176 pathAnimation.duration = 1.0;
188 pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 177 pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
189 pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; 178 pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
190 pathAnimation.toValue = [NSNumber numberWithFloat:1.0f]; 179 pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
191 - [_chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; 180 + [chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
192 181
193 - _chartLine.strokeEnd = 1.0; 182 + chartLine.strokeEnd = 1.0;
194 183
195 UIGraphicsEndImageContext(); 184 UIGraphicsEndImageContext();
  185 + }
  186 +}
  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 + }
  231 +
  232 + [self setNeedsDisplay];
  233 + }
196 } 234 }
197 235
  236 +#pragma mark private methods
198 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 ```