Kevin

Merge pull request #41 from snappr/master

Less Precise Line Chart
@@ -97,11 +97,13 @@ @@ -97,11 +97,13 @@
97 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 97 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
98 { 98 {
99 [self touchPoint:touches withEvent:event]; 99 [self touchPoint:touches withEvent:event];
  100 + [self touchKeyPoint:touches withEvent:event];
100 } 101 }
101 102
102 -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 103 -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
103 { 104 {
104 [self touchPoint:touches withEvent:event]; 105 [self touchPoint:touches withEvent:event];
  106 + [self touchKeyPoint:touches withEvent:event];
105 } 107 }
106 108
107 -(void)touchPoint:(NSSet *)touches withEvent:(UIEvent *)event 109 -(void)touchPoint:(NSSet *)touches withEvent:(UIEvent *)event
@@ -109,26 +111,59 @@ @@ -109,26 +111,59 @@
109 //Get the point user touched 111 //Get the point user touched
110 UITouch *touch = [touches anyObject]; 112 UITouch *touch = [touches anyObject];
111 CGPoint touchPoint = [touch locationInView:self]; 113 CGPoint touchPoint = [touch locationInView:self];
  114 +
  115 + for (int p = _pathPoints.count - 1; p >= 0; p--) {
  116 + NSArray *linePointsArray = _pathPoints[p];
  117 +
  118 + for (int i = 0; i < linePointsArray.count - 1; i += 1) {
  119 + CGPoint p1 = [linePointsArray[i] CGPointValue];
  120 + CGPoint p2 = [linePointsArray[i+1] CGPointValue];
  121 +
  122 + // Closest distance from point to line
  123 + float distance = fabsf(((p2.x - p1.x)*(touchPoint.y - p1.y))-((p1.x-touchPoint.x)*(p1.y-p2.y)));
  124 + distance /= hypot(p2.x-p1.x, p1.y-p2.y);
  125 +
  126 + if (distance <= 5.0) {
  127 + // Conform to delegate parameters, figure out what bezier path this CGPoint belongs to.
112 for (UIBezierPath *path in _chartPath) { 128 for (UIBezierPath *path in _chartPath) {
113 - CGPathRef originalPath = path.CGPath; 129 + BOOL pointContainsPath = CGPathContainsPoint(path.CGPath, NULL, p1, NO);
114 - CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(originalPath, NULL, 3.0, kCGLineCapRound, kCGLineJoinRound, 3.0); 130 +
115 - BOOL pathContainsPoint = CGPathContainsPoint(strokedPath, NULL, touchPoint, NO); 131 + if (pointContainsPath) {
116 - if (pathContainsPoint)  
117 - {  
118 [_delegate userClickedOnLinePoint:touchPoint lineIndex:[_chartPath indexOfObject:path]]; 132 [_delegate userClickedOnLinePoint:touchPoint lineIndex:[_chartPath indexOfObject:path]];
119 - for (NSArray *linePointsArray in _pathPoints) { 133 + return;
120 - for (NSValue *val in linePointsArray) {  
121 - CGPoint p = [val CGPointValue];  
122 - if (p.x + 3.0 > touchPoint.x && p.x - 3.0 < touchPoint.x && p.y + 3.0 > touchPoint.y && p.y - 3.0 < touchPoint.y ) {  
123 - //Call the delegate and pass the point and index of the point  
124 - [_delegate userClickedOnLineKeyPoint:touchPoint lineIndex:[_pathPoints indexOfObject:linePointsArray] andPointIndex:[linePointsArray indexOfObject:val]];  
125 } 134 }
126 } 135 }
127 } 136 }
128 -  
129 } 137 }
130 } 138 }
  139 +}
  140 +
  141 +-(void)touchKeyPoint:(NSSet *)touches withEvent:(UIEvent *)event
  142 +{
  143 + //Get the point user touched
  144 + UITouch *touch = [touches anyObject];
  145 + CGPoint touchPoint = [touch locationInView:self];
  146 +
  147 + for (int p = _pathPoints.count - 1; p >= 0; p--) {
  148 + NSArray *linePointsArray = _pathPoints[p];
  149 +
  150 + for (int i = 0; i < linePointsArray.count - 1; i += 1) {
  151 + CGPoint p1 = [linePointsArray[i] CGPointValue];
  152 + CGPoint p2 = [linePointsArray[i+1] CGPointValue];
131 153
  154 + float distanceToP1 = fabsf(hypot(touchPoint.x - p1.x, touchPoint.y - p1.y));
  155 + float distanceToP2 = hypot(touchPoint.x - p2.x, touchPoint.y - p2.y);
  156 +
  157 + float distance = MIN(distanceToP1, distanceToP2);
  158 +
  159 + if (distance <= 10.0) {
  160 + [_delegate userClickedOnLineKeyPoint:touchPoint
  161 + lineIndex:p
  162 + andPointIndex:(distance == distanceToP2 ? i+1 : i)];
  163 + return;
  164 + }
  165 + }
  166 + }
132 } 167 }
133 168
134 -(void)strokeChart 169 -(void)strokeChart