neo

removed defines from PNLineChart.h (not typesafe)

fixed issue #24
@@ -11,9 +11,8 @@ @@ -11,9 +11,8 @@
11 #import <QuartzCore/QuartzCore.h> 11 #import <QuartzCore/QuartzCore.h>
12 #import "PNChartDelegate.h" 12 #import "PNChartDelegate.h"
13 13
14 -#define chartMargin 10 14 +
15 -#define yLabelMargin 15 15 +
16 -#define yLabelHeight 11  
17 16
18 @interface PNLineChart : UIView 17 @interface PNLineChart : UIView
19 18
@@ -30,19 +29,31 @@ @@ -30,19 +29,31 @@
30 @property (strong, nonatomic) NSArray * yLabels; 29 @property (strong, nonatomic) NSArray * yLabels;
31 30
32 /** 31 /**
33 -* Array of `LineChartData` objects, one for each line. 32 + * Array of `LineChartData` objects, one for each line.
34 -*/ 33 + */
35 @property (strong, nonatomic) NSArray *chartData; 34 @property (strong, nonatomic) NSArray *chartData;
36 35
37 @property (strong, nonatomic) NSMutableArray * pathPoints; 36 @property (strong, nonatomic) NSMutableArray * pathPoints;
38 37
39 @property (nonatomic) CGFloat xLabelWidth; 38 @property (nonatomic) CGFloat xLabelWidth;
40 39
41 -@property (nonatomic) float yValueMax; 40 +@property (nonatomic) CGFloat xLabelHeight;
  41 +
  42 +@property (nonatomic) CGFloat yValueMax;
  43 +
  44 +@property (nonatomic) CGFloat yValueMin;
  45 +
  46 +@property (nonatomic) NSInteger yLabelNum;
  47 +
  48 +@property (nonatomic) CGFloat yLabelHeight;
  49 +
  50 +@property (nonatomic) CGFloat chartCavanHeight;
  51 +
  52 +@property (nonatomic) CGFloat chartCavanWidth;
  53 +
  54 +@property (nonatomic) CGFloat chartMargin;
42 55
43 -@property (nonatomic) float chartCavanHeight;  
44 56
45 -@property (nonatomic) float xLabelHeight;  
46 57
47 @property (nonatomic) BOOL showLabel; 58 @property (nonatomic) BOOL showLabel;
48 59
@@ -54,21 +54,22 @@ @@ -54,21 +54,22 @@
54 54
55 -(void)setYLabels:(NSArray *)yLabels 55 -(void)setYLabels:(NSArray *)yLabels
56 { 56 {
57 - 57 +
58 - float level = _yValueMax / 5.0; 58 + float yStep = (_yValueMax-_yValueMin) / _yLabelNum;
59 - 59 + CGFloat yStepHeight = _chartCavanHeight / _yLabelNum;
  60 +
  61 +
60 NSInteger index = 0; 62 NSInteger index = 0;
61 - NSInteger num = [yLabels count] + 1; 63 + NSInteger num = _yLabelNum+1;
62 while (num > 0) { 64 while (num > 0) {
63 - CGFloat levelHeight = _chartCavanHeight /5.0; 65 + PNChartLabel * label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0, (_chartCavanHeight - index * yStepHeight), _chartMargin, _yLabelHeight)];
64 - PNChartLabel * label = [[PNChartLabel alloc] initWithFrame:CGRectMake(0.0,_chartCavanHeight - index * levelHeight + (levelHeight - yLabelHeight) , 20.0, yLabelHeight)];  
65 [label setTextAlignment:NSTextAlignmentRight]; 66 [label setTextAlignment:NSTextAlignmentRight];
66 - label.text = [NSString stringWithFormat:@"%1.f",level * index]; 67 + label.text = [NSString stringWithFormat:@"%1.f",_yValueMin + (yStep * index)];
67 [self addSubview:label]; 68 [self addSubview:label];
68 index +=1 ; 69 index +=1 ;
69 num -= 1; 70 num -= 1;
70 } 71 }
71 - 72 +
72 } 73 }
73 74
74 -(void)setXLabels:(NSArray *)xLabels 75 -(void)setXLabels:(NSArray *)xLabels
@@ -76,12 +77,12 @@ @@ -76,12 +77,12 @@
76 _xLabels = xLabels; 77 _xLabels = xLabels;
77 78
78 if(_showLabel){ 79 if(_showLabel){
79 - _xLabelWidth = (self.frame.size.width - chartMargin - 30.0)/[xLabels count]; 80 + _xLabelWidth = _chartCavanWidth/[xLabels count];
80 81
81 for(int index = 0; index < xLabels.count; index++) 82 for(int index = 0; index < xLabels.count; index++)
82 { 83 {
83 NSString* labelText = xLabels[index]; 84 NSString* labelText = xLabels[index];
84 - PNChartLabel * label = [[PNChartLabel alloc] initWithFrame:CGRectMake(index * _xLabelWidth + 30.0, self.frame.size.height - 30.0, _xLabelWidth, 20.0)]; 85 + PNChartLabel * label = [[PNChartLabel alloc] initWithFrame:CGRectMake(2*_chartMargin + (index * _xLabelWidth) - (_xLabelWidth / 2), _chartMargin + _chartCavanHeight, _xLabelWidth, _chartMargin)];
85 [label setTextAlignment:NSTextAlignmentCenter]; 86 [label setTextAlignment:NSTextAlignmentCenter];
86 label.text = labelText; 87 label.text = labelText;
87 [self addSubview:label]; 88 [self addSubview:label];
@@ -137,44 +138,47 @@ @@ -137,44 +138,47 @@
137 for (NSUInteger lineIndex = 0; lineIndex < self.chartData.count; lineIndex++) { 138 for (NSUInteger lineIndex = 0; lineIndex < self.chartData.count; lineIndex++) {
138 PNLineChartData *chartData = self.chartData[lineIndex]; 139 PNLineChartData *chartData = self.chartData[lineIndex];
139 CAShapeLayer *chartLine = (CAShapeLayer *) self.chartLineArray[lineIndex]; 140 CAShapeLayer *chartLine = (CAShapeLayer *) self.chartLineArray[lineIndex];
140 - 141 +
141 UIGraphicsBeginImageContext(self.frame.size); 142 UIGraphicsBeginImageContext(self.frame.size);
142 UIBezierPath * progressline = [UIBezierPath bezierPath]; 143 UIBezierPath * progressline = [UIBezierPath bezierPath];
143 [_chartPath addObject:progressline]; 144 [_chartPath addObject:progressline];
144 145
145 - PNLineChartDataItem *firstDataItem = chartData.getData(0); 146 + CGFloat xPosition = _chartMargin;
146 - CGFloat firstValue = firstDataItem.y; 147 +
147 -  
148 - CGFloat xPosition = _xLabelWidth;  
149 -  
150 if(!_showLabel){ 148 if(!_showLabel){
151 - _chartCavanHeight = self.frame.size.height - _xLabelHeight*2; 149 + //heuristic don't know why
  150 + _yLabelHeight = 2;
  151 + _chartCavanHeight = self.frame.size.height - 2*_yLabelHeight;
  152 + _chartCavanWidth = self.frame.size.width;
  153 + _yLabelHeight = 5.0;
  154 + _chartMargin = 0.0;
  155 + _xLabelWidth = (_chartCavanWidth / ([_xLabels count] -1));
152 xPosition = 0; 156 xPosition = 0;
153 } 157 }
154 - 158 +
155 - CGFloat grade = (float)firstValue / _yValueMax;  
156 NSMutableArray * linePointsArray = [[NSMutableArray alloc] init]; 159 NSMutableArray * linePointsArray = [[NSMutableArray alloc] init];
157 - [progressline moveToPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)];  
158 - [linePointsArray addObject:[NSValue valueWithCGPoint:CGPointMake( xPosition, _chartCavanHeight - grade * _chartCavanHeight + _xLabelHeight)]];  
159 [progressline setLineWidth:3.0]; 160 [progressline setLineWidth:3.0];
160 [progressline setLineCapStyle:kCGLineCapRound]; 161 [progressline setLineCapStyle:kCGLineCapRound];
161 [progressline setLineJoinStyle:kCGLineJoinRound]; 162 [progressline setLineJoinStyle:kCGLineJoinRound];
162 -  
163 163
164 - NSInteger index = 0; 164 + PNLineChartDataItem *dataItem;
  165 +
  166 +
165 for (NSUInteger i = 0; i < chartData.itemCount; i++) { 167 for (NSUInteger i = 0; i < chartData.itemCount; i++) {
166 - 168 +
167 - PNLineChartDataItem *dataItem = chartData.getData(i); 169 + dataItem = chartData.getData(i);
168 float value = dataItem.y; 170 float value = dataItem.y;
169 - 171 +
170 - CGFloat innerGrade = value / _yValueMax; 172 + CGFloat innerGrade = (value - _yValueMin) / ( _yValueMax - _yValueMin);
171 - if (index != 0) { 173 +
172 - CGPoint point = CGPointMake(index * _xLabelWidth + 30.0 + _xLabelWidth / 2.0, _chartCavanHeight - (innerGrade * _chartCavanHeight) + _xLabelHeight); 174 + CGPoint point = CGPointMake(2*_chartMargin + (i * _xLabelWidth), _chartCavanHeight - (innerGrade * _chartCavanHeight) + ( _yLabelHeight /2 ));
173 - [linePointsArray addObject:[NSValue valueWithCGPoint:point]]; 175 +
  176 + if (i != 0) {
174 [progressline addLineToPoint:point]; 177 [progressline addLineToPoint:point];
175 - [progressline moveToPoint:point];  
176 } 178 }
177 - index += 1; 179 +
  180 + [progressline moveToPoint:point];
  181 + [linePointsArray addObject:[NSValue valueWithCGPoint:point]];
178 } 182 }
179 [_pathPoints addObject:[linePointsArray copy]]; 183 [_pathPoints addObject:[linePointsArray copy]];
180 // setup the color of the chart line 184 // setup the color of the chart line
@@ -183,38 +187,38 @@ @@ -183,38 +187,38 @@
183 }else{ 187 }else{
184 chartLine.strokeColor = [PNGreen CGColor]; 188 chartLine.strokeColor = [PNGreen CGColor];
185 } 189 }
186 - 190 +
187 [progressline stroke]; 191 [progressline stroke];
188 - 192 +
189 chartLine.path = progressline.CGPath; 193 chartLine.path = progressline.CGPath;
190 - 194 +
191 CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 195 CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
192 pathAnimation.duration = 1.0; 196 pathAnimation.duration = 1.0;
193 pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 197 pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
194 pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; 198 pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
195 pathAnimation.toValue = [NSNumber numberWithFloat:1.0f]; 199 pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
196 [chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; 200 [chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
197 - 201 +
198 chartLine.strokeEnd = 1.0; 202 chartLine.strokeEnd = 1.0;
199 - 203 +
200 UIGraphicsEndImageContext(); 204 UIGraphicsEndImageContext();
201 } 205 }
202 } 206 }
203 207
204 - (void)setChartData:(NSArray *)data { 208 - (void)setChartData:(NSArray *)data {
205 if (data != _chartData) { 209 if (data != _chartData) {
206 - 210 +
207 NSMutableArray *yLabelsArray = [NSMutableArray arrayWithCapacity:data.count]; 211 NSMutableArray *yLabelsArray = [NSMutableArray arrayWithCapacity:data.count];
208 CGFloat yMax = 0.0f; 212 CGFloat yMax = 0.0f;
209 - 213 + CGFloat yMin = MAXFLOAT;
210 // remove all shape layers before adding new ones 214 // remove all shape layers before adding new ones
211 for (CALayer *layer in self.chartLineArray) { 215 for (CALayer *layer in self.chartLineArray) {
212 [layer removeFromSuperlayer]; 216 [layer removeFromSuperlayer];
213 } 217 }
214 self.chartLineArray = [NSMutableArray arrayWithCapacity:data.count]; 218 self.chartLineArray = [NSMutableArray arrayWithCapacity:data.count];
215 - 219 +
216 for (PNLineChartData *chartData in data) { 220 for (PNLineChartData *chartData in data) {
217 - 221 +
218 // create as many chart line layers as there are data-lines 222 // create as many chart line layers as there are data-lines
219 CAShapeLayer *chartLine = [CAShapeLayer layer]; 223 CAShapeLayer *chartLine = [CAShapeLayer layer];
220 chartLine.lineCap = kCALineCapRound; 224 chartLine.lineCap = kCALineCapRound;
@@ -224,27 +228,34 @@ @@ -224,27 +228,34 @@
224 chartLine.strokeEnd = 0.0; 228 chartLine.strokeEnd = 0.0;
225 [self.layer addSublayer:chartLine]; 229 [self.layer addSublayer:chartLine];
226 [self.chartLineArray addObject:chartLine]; 230 [self.chartLineArray addObject:chartLine];
227 - 231 +
228 for (NSUInteger i = 0; i < chartData.itemCount; i++) { 232 for (NSUInteger i = 0; i < chartData.itemCount; i++) {
229 PNLineChartDataItem *dataItem = chartData.getData(i); 233 PNLineChartDataItem *dataItem = chartData.getData(i);
230 CGFloat yValue = dataItem.y; 234 CGFloat yValue = dataItem.y;
231 [yLabelsArray addObject:[NSString stringWithFormat:@"%2f", yValue]]; 235 [yLabelsArray addObject:[NSString stringWithFormat:@"%2f", yValue]];
232 yMax = fmaxf(yMax, dataItem.y); 236 yMax = fmaxf(yMax, dataItem.y);
  237 + yMin = fminf(yMin, dataItem.y);
233 } 238 }
234 } 239 }
235 - 240 +
236 // Min value for Y label 241 // Min value for Y label
237 if (yMax < 5) { 242 if (yMax < 5) {
238 yMax = 5.0f; 243 yMax = 5.0f;
239 } 244 }
  245 + if (yMin < 0){
  246 + yMin = 0.0f;
  247 + }
  248 + NSLog(@"%f",yMin);
  249 +
  250 + _yValueMin = yMin;
240 _yValueMax = yMax; 251 _yValueMax = yMax;
241 - 252 +
242 _chartData = data; 253 _chartData = data;
243 - 254 +
244 if (_showLabel) { 255 if (_showLabel) {
245 [self setYLabels:yLabelsArray]; 256 [self setYLabels:yLabelsArray];
246 } 257 }
247 - 258 +
248 [self setNeedsDisplay]; 259 [self setNeedsDisplay];
249 } 260 }
250 } 261 }
@@ -259,8 +270,17 @@ @@ -259,8 +270,17 @@
259 _showLabel = YES; 270 _showLabel = YES;
260 _pathPoints = [[NSMutableArray alloc] init]; 271 _pathPoints = [[NSMutableArray alloc] init];
261 self.userInteractionEnabled = YES; 272 self.userInteractionEnabled = YES;
262 - _xLabelHeight = 20.0; 273 +
263 - _chartCavanHeight = self.frame.size.height - chartMargin * 2 - _xLabelHeight*2 ; 274 + _yLabelNum = 5.0;
  275 + _yLabelHeight = [[[[PNChartLabel alloc] init] font] pointSize];
  276 +
  277 + _chartMargin = 30;
  278 +
  279 + _xLabelHeight = _chartMargin;
  280 +
  281 +
  282 + _chartCavanWidth = self.frame.size.width - _chartMargin *2;
  283 + _chartCavanHeight = self.frame.size.height - _chartMargin * 2;
264 } 284 }
265 285
266 @end 286 @end