@@ -13,6 +13,10 @@ public struct Line: View {
1313 @State private var didCellAppear : Bool = false
1414
1515 var curvedLines : Bool = true
16+ var path : Path {
17+ Path . quadCurvedPathWithPoints ( points: chartData. normalisedPoints,
18+ step: CGPoint ( x: 1.0 , y: 1.0 ) )
19+ }
1620
1721 /// The content and behavior of the `Line`.
1822 /// Draw the background if showing the full line (?) and the `showBackground` option is set. Above that draw the line, and then the data indicator if the graph is currently being touched.
@@ -31,12 +35,13 @@ public struct Line: View {
3135 style: style,
3236 trimTo: didCellAppear ? 1.0 : 0.0 )
3337 . animation ( . easeIn)
34- // if self.showIndicator {
35- // IndicatorPoint()
36- // .position(self.getClosestPointOnPath(touchLocation: self.touchLocation))
37- // .rotationEffect(.degrees(180), anchor: .center)
38- // .rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
39- // }
38+ if self . showIndicator {
39+ IndicatorPoint ( )
40+ . position ( self . getClosestPointOnPath ( geometry: geometry,
41+ touchLocation: self . touchLocation) )
42+ . rotationEffect ( . degrees( 180 ) , anchor: . center)
43+ . rotation3DEffect ( . degrees( 180 ) , axis: ( x: 0 , y: 1 , z: 0 ) )
44+ }
4045 }
4146 . onAppear {
4247 didCellAppear = true
@@ -49,7 +54,7 @@ public struct Line: View {
4954 . onChanged ( { value in
5055 self . touchLocation = value. location
5156 self . showIndicator = true
52- // self.getClosestDataPoint(point: self.getClosestPointOnPath( touchLocation: value.location) )
57+ self . getClosestDataPoint ( geometry : geometry , touchLocation: value. location)
5358 self . chartValue. interactionInProgress = true
5459 } )
5560 . onEnded ( { value in
@@ -64,24 +69,30 @@ public struct Line: View {
6469
6570// MARK: - Private functions
6671
67- //extension Line {
68- // /// Calculate point closest to where the user touched
69- // /// - Parameter touchLocation: location in view where touched
70- // /// - Returns: `CGPoint` of data point on chart
71- // private func getClosestPointOnPath(touchLocation: CGPoint) -> CGPoint {
72- // let closest = self.path.point(to: touchLocation.x)
73- // return closest
74- // }
75- //
72+ extension Line {
73+ /// Calculate point closest to where the user touched
74+ /// - Parameter touchLocation: location in view where touched
75+ /// - Returns: `CGPoint` of data point on chart
76+ private func getClosestPointOnPath( geometry: GeometryProxy , touchLocation: CGPoint ) -> CGPoint {
77+ let geometryWidth = geometry. frame ( in: . local) . width
78+ let normalisedTouchLocationX = ( touchLocation. x / geometryWidth) * CGFloat( chartData. normalisedPoints. count - 1 )
79+ let closest = self . path. point ( to: normalisedTouchLocationX)
80+ var denormClosest = closest. denormalize ( with: geometry)
81+ denormClosest. x = denormClosest. x / CGFloat( chartData. normalisedPoints. count - 1 )
82+ denormClosest. y = denormClosest. y / CGFloat( chartData. normalisedRange)
83+ return denormClosest
84+ }
85+
7686// /// Figure out where closest touch point was
7787// /// - Parameter point: location of data point on graph, near touch location
78- // private func getClosestDataPoint(point: CGPoint) {
79- // let index = Int(round((point.x)/step.x))
80- // if (index >= 0 && index < self.chartData.data.count){
81- // self.chartValue.currentValue = self.chartData.points[index]
82- // }
83- // }
84- //}
88+ private func getClosestDataPoint( geometry: GeometryProxy , touchLocation: CGPoint ) {
89+ let geometryWidth = geometry. frame ( in: . local) . width
90+ let index = Int ( round ( ( touchLocation. x / geometryWidth) * CGFloat( chartData. points. count - 1 ) ) )
91+ if ( index >= 0 && index < self . chartData. data. count) {
92+ self . chartValue. currentValue = self . chartData. points [ index]
93+ }
94+ }
95+ }
8596
8697struct Line_Previews : PreviewProvider {
8798 /// Predefined style, black over white, for preview
0 commit comments