7
7
//
8
8
9
9
#import " MPGraphView.h"
10
+ #import " UIBezierPath+curved.h"
10
11
11
- // Based on code from Erica Sadun
12
-
13
- void getPointsFromBezier (void *info, const CGPathElement *element);
14
- NSArray *pointsFromBezierPath (UIBezierPath *bpath);
15
-
16
-
17
- #define VALUE (_INDEX_ ) [NSValue valueWithCGPoint: points[_INDEX_]]
18
- #define POINT (_INDEX_ ) [(NSValue *)[points objectAtIndex: _INDEX_] CGPointValue ]
19
-
20
- @implementation UIBezierPath (Smoothing)
21
-
22
- // Get points from Bezier Curve
23
- void getPointsFromBezier (void *info, const CGPathElement *element)
24
- {
25
- NSMutableArray *bezierPoints = (__bridge NSMutableArray *)info;
26
-
27
- // Retrieve the path element type and its points
28
- CGPathElementType type = element->type ;
29
- CGPoint *points = element->points ;
30
-
31
- // Add the points if they're available (per type)
32
- if (type != kCGPathElementCloseSubpath )
33
- {
34
- [bezierPoints addObject: VALUE (0 )];
35
- if ((type != kCGPathElementAddLineToPoint ) &&
36
- (type != kCGPathElementMoveToPoint ))
37
- [bezierPoints addObject: VALUE (1 )];
38
- }
39
- if (type == kCGPathElementAddCurveToPoint )
40
- [bezierPoints addObject: VALUE (2 )];
41
- }
42
-
43
- NSArray *pointsFromBezierPath (UIBezierPath *bpath)
44
- {
45
- NSMutableArray *points = [NSMutableArray array ];
46
- CGPathApply (bpath.CGPath , (__bridge void *)points, getPointsFromBezier);
47
- return points;
48
- }
49
-
50
- - (UIBezierPath*)smoothedPathWithGranularity : (NSInteger )granularity ;
51
- {
52
- NSMutableArray *points = [pointsFromBezierPath (self ) mutableCopy ];
53
-
54
- if (points.count < 4 ) return [self copy ];
55
-
56
- // Add control points to make the math make sense
57
- [points insertObject: [points objectAtIndex: 0 ] atIndex: 0 ];
58
- [points addObject: [points lastObject ]];
59
-
60
- UIBezierPath *smoothedPath = [self copy ];
61
- [smoothedPath removeAllPoints ];
62
-
63
- [smoothedPath moveToPoint: POINT (0 )];
64
-
65
- for (NSUInteger index = 1 ; index < points.count - 2 ; index ++)
66
- {
67
- CGPoint p0 = POINT (index - 1 );
68
- CGPoint p1 = POINT (index );
69
- CGPoint p2 = POINT (index + 1 );
70
- CGPoint p3 = POINT (index + 2 );
71
-
72
- // now add n points starting at p1 + dx/dy up until p2 using Catmull-Rom splines
73
- for (int i = 1 ; i < granularity; i++)
74
- {
75
- float t = (float ) i * (1 .0f / (float ) granularity);
76
- float tt = t * t;
77
- float ttt = tt * t;
78
-
79
- CGPoint pi ; // intermediate point
80
- pi .x = 0.5 * (2 *p1.x +(p2.x -p0.x )*t + (2 *p0.x -5 *p1.x +4 *p2.x -p3.x )*tt + (3 *p1.x -p0.x -3 *p2.x +p3.x )*ttt);
81
- pi .y = 0.5 * (2 *p1.y +(p2.y -p0.y )*t + (2 *p0.y -5 *p1.y +4 *p2.y -p3.y )*tt + (3 *p1.y -p0.y -3 *p2.y +p3.y )*ttt);
82
- [smoothedPath addLineToPoint: pi ];
83
- }
84
-
85
- // Now add p2
86
- [smoothedPath addLineToPoint: p2];
87
- }
88
-
89
- // finish by adding the last point
90
- [smoothedPath addLineToPoint: POINT (points.count - 1 )];
91
-
92
- return smoothedPath;
93
- }
94
-
95
-
96
- @end
97
-
98
- @interface MPButton : UIButton
99
-
100
- @end
101
-
102
- @implementation MPButton
103
-
104
- - (BOOL )pointInside : (CGPoint )point withEvent : (UIEvent *)event {
105
-
106
- return CGRectContainsPoint (CGRectInset (self.bounds , -25 , -25 ), point);
107
-
108
- }
109
-
110
- @end
111
12
112
13
@implementation MPGraphView
113
14
114
15
115
-
116
16
+ (Class )layerClass {
117
17
return [CAShapeLayer class ];
118
18
}
@@ -255,7 +155,7 @@ - (void)tap:(UIButton *)button{
255
155
256
156
label=[[UILabel alloc ] initWithFrame: CGRectMake (0 , 0 , 80 , 20 )];
257
157
label.textAlignment =NSTextAlignmentCenter;
258
- label.textColor =self.detailTextColor ? self.detailTextColor : ( _graphColor ? _graphColor : (_fillColors. count ? [UIColor colorWithCGColor: (CGColorRef )[_fillColors firstObject ]] : self.graphColor ) );
158
+ label.textColor =self.detailTextColor ? self.detailTextColor : ( self. graphColor ? self. graphColor : (self. fillColors . count ? [UIColor colorWithCGColor: (CGColorRef )[self .fillColors firstObject ]] : self.graphColor ) );
259
159
label.backgroundColor =self.detailBackgroundColor ;
260
160
label.layer .borderColor =label.textColor .CGColor ;
261
161
label.layer .borderWidth =.5 ;
@@ -275,54 +175,6 @@ - (void)tap:(UIButton *)button{
275
175
}
276
176
277
177
278
-
279
-
280
-
281
- - (NSMutableArray *)pointsForArray : (NSArray *)dict {
282
-
283
- CGFloat min,max,avg;
284
-
285
- min=max=[[dict firstObject ] floatValue ];
286
-
287
-
288
- for (NSInteger i=0 ; i<dict.count ; i++) {
289
-
290
- CGFloat val=[[dict objectAtIndex: i] floatValue ];
291
-
292
- if (val>max) {
293
- max=val;
294
- }
295
-
296
- if (val<min) {
297
- min=val;
298
- }
299
-
300
- avg+=val;
301
- }
302
-
303
- avg/=dict.count ;
304
-
305
-
306
- NSMutableArray *pointsArray=[[NSMutableArray alloc ] init ];
307
-
308
- if (max!=min){
309
- for (NSString *p in dict) {
310
-
311
- CGFloat val=[p floatValue ];
312
-
313
- val=((val-min)/(max-min));
314
-
315
- [pointsArray addObject: @(val)];
316
- }
317
-
318
- }else [pointsArray addObject: @(1 )];
319
-
320
- return pointsArray;
321
- }
322
-
323
-
324
-
325
-
326
178
- (void )animate {
327
179
328
180
self.waitToUpdate =NO ;
@@ -393,7 +245,8 @@ - (void)displayPoint:(UIButton *)button{
393
245
394
246
}
395
247
396
- #pragma mark setters
248
+
249
+ #pragma mark Setters
397
250
398
251
-(void )setFillColors : (NSArray *)fillColors {
399
252
@@ -427,90 +280,11 @@ -(void)setFillColors:(NSArray *)fillColors{
427
280
428
281
}
429
282
430
- - (void )setValues : (NSArray *)values {
431
-
432
- if (values) {
433
-
434
- _values=[values copy ];
435
-
436
- points=[self pointsForArray: _values];
437
-
438
-
439
- [self setNeedsDisplay ];
440
- }
441
-
442
- }
443
-
444
283
-(void )setCurved : (BOOL )curved {
445
284
_curved=curved;
446
285
[self setNeedsDisplay ];
447
286
}
448
287
449
- - (void )setAlgorithm : (GraphPointsAlgorithm)customAlgorithm numberOfPoints : (NSUInteger )numberOfPoints {
450
-
451
- _numberOfPoints=numberOfPoints;
452
- _customAlgorithm=customAlgorithm;
453
-
454
- NSMutableArray * values=[[NSMutableArray alloc ] init ];
455
-
456
- for (NSUInteger i=0 ; i<numberOfPoints; i++) {
457
- [values addObject: @(customAlgorithm (i))];
458
- }
459
-
460
- self.values =values;
461
-
462
- [self setNeedsDisplay ];
463
- }
464
-
465
- #pragma mark Getters
466
-
467
- - (NSNumberFormatter *)detailLabelFormatter {
468
-
469
- if (!_detailLabelFormatter) {
470
- _detailLabelFormatter=[[NSNumberFormatter alloc ] init ];
471
- _detailLabelFormatter.locale =[NSLocale currentLocale ];
472
- _detailLabelFormatter.numberStyle =NSNumberFormatterDecimalStyle;
473
- }
474
-
475
- return _detailLabelFormatter;
476
- }
477
-
478
- - (UIColor *)graphColor {
479
-
480
- return _graphColor ? _graphColor : [UIColor blueColor ];
481
-
482
- }
483
-
484
-
485
- - (UIColor *)detailBackgroundColor {
486
-
487
- return _detailBackgroundColor ? _detailBackgroundColor : [UIColor whiteColor ];
488
-
489
- }
490
-
491
-
492
-
493
- - (CGFloat )animationDuration {
494
- return _animationDuration>0.0 ? _animationDuration : ANIMATIONDURATION;
495
- }
496
-
497
-
498
- #pragma mark Internal
499
-
500
- - (UIView *)hitTest : (CGPoint )point withEvent : (UIEvent *)event {
501
-
502
- UIView *view=[super hitTest: point withEvent: event];
503
-
504
- if (view==self && label.superview ) {
505
- [UIView animateWithDuration: .15 animations: ^{
506
- label.transform =CGAffineTransformMakeScale (0 , 0 );
507
- }completion: ^(BOOL finished) {
508
- [label removeFromSuperview ]; label=nil ;
509
- }];
510
- }
511
-
512
- return view;
513
- }
514
288
515
289
516
290
@end
0 commit comments