@@ -106,7 +106,7 @@ struct HeartChartView: View {
106106 }
107107
108108 @ChartContentBuilder
109- func chartContent( for point: HeartChartDataPoint ) -> some ChartContent {
109+ func chartContent( for point: HeartChartDataPoint , selected : HeartChartDataPoint ? ) -> some ChartContent {
110110 BarMark (
111111 x: . value( " Time " , point. date) ,
112112 yStart: . value( " Min " , point. min) ,
@@ -115,7 +115,7 @@ struct HeartChartView: View {
115115 )
116116 . foregroundStyle ( darkHeartColor)
117117 . cornerRadius ( 4 )
118- //.clipShape(Capsule() )
118+ . opacity ( selected == nil || selected ? . date == point . date ? 1 : 0.5 )
119119
120120 PointMark (
121121 x: . value( " Time " , point. date) ,
@@ -124,6 +124,7 @@ struct HeartChartView: View {
124124 . foregroundStyle ( heartColor)
125125 . symbolSize ( CGSize ( width: 7 , height: 7 ) )
126126 . symbol ( . circle)
127+ . opacity ( selected == nil || selected? . date == point. date ? 1 : 0.25 )
127128 }
128129
129130 // fixed graph
@@ -142,8 +143,13 @@ struct HeartChartView: View {
142143 let pageMax = Int ( pagePoints. map ( { $0. max } ) . max ( ) ?? 0 )
143144
144145 return Chart {
146+ if let selectedViewHour {
147+ RuleMark ( x: . value( " Selected Hour " , selectedViewHour. date, unit: . hour) )
148+ . foregroundStyle ( Color . gray)
149+ }
150+
145151 ForEach ( pagePoints) { point in
146- chartContent ( for: point)
152+ chartContent ( for: point, selected : selectedViewHour )
147153 }
148154 }
149155 . frame ( height: 280 )
@@ -162,6 +168,26 @@ struct HeartChartView: View {
162168 AxisValueLabel ( )
163169 }
164170 }
171+ . overlay (
172+ GeometryReader { geo in
173+ Color . clear
174+ . contentShape ( Rectangle ( ) )
175+ . gesture ( DragGesture ( minimumDistance: 0 )
176+ . onChanged { value in
177+ let leadingPadding : CGFloat = 8
178+ let yAxisWidth : CGFloat = 40
179+ let adjustedWidth = geo. size. width - yAxisWidth - leadingPadding
180+ let clampedX = min ( max ( value. location. x - leadingPadding, 0 ) , adjustedWidth)
181+ let fraction = clampedX / adjustedWidth
182+ let totalSeconds : TimeInterval = 86400
183+ rawSelectedHour = start. addingTimeInterval ( fraction * totalSeconds)
184+ }
185+ . onEnded { _ in
186+ rawSelectedHour = nil
187+ }
188+ )
189+ }
190+ )
165191 }
166192
167193 var pagedChart : some View {
@@ -208,7 +234,7 @@ struct HeartChartView: View {
208234 }
209235
210236 ForEach ( points) { point in
211- chartContent ( for: point)
237+ chartContent ( for: point, selected : selectedViewHour )
212238 }
213239 }
214240 . frame ( height: 280 )
@@ -310,12 +336,10 @@ struct HeartChartView: View {
310336 }
311337 . onChange ( of: bleManager. heartRate) { _ in
312338 let previousLatest = latestDate
313- let wasAtLatest = scrollPositionDate >= Date ( timeInterval: - 86400 , since: previousLatest)
314339 points = heartPoints ( )
315- if Calendar . current. component ( . hour, from: latestDate) > Calendar . current. component ( . hour, from: previousLatest) {
316- if wasAtLatest {
317- scrollPositionDate = Date ( timeInterval: - 86400 , since: latestDate)
318- }
340+ if !Calendar. current. isDate ( latestDate, inSameDayAs: previousLatest) {
341+ dayOffset = 0
342+ scrollPositionDate = Calendar . current. startOfDay ( for: latestDate)
319343 }
320344 updateDisplayed ( )
321345 updateYScale ( ) // scrollable chart
0 commit comments