Apple Fitness workout fixer + Strava uploader
1import SwiftUI
2import Charts
3
4struct ActivityGraphView: View {
5 let samples: [IntensitySample]
6 let metric: IntensityMetric
7 let lowerBound: Double
8 let upperBound: Double
9
10 var body: some View {
11 Chart {
12 ForEach(samples) { sample in
13 AreaMark(
14 x: .value("Time", sample.date),
15 y: .value(metric.label, sample.value)
16 )
17 .foregroundStyle(
18 .linearGradient(
19 colors: [.blue.opacity(0.3), .blue.opacity(0.05)],
20 startPoint: .top,
21 endPoint: .bottom
22 )
23 )
24
25 LineMark(
26 x: .value("Time", sample.date),
27 y: .value(metric.label, sample.value)
28 )
29 .foregroundStyle(.blue)
30 .lineStyle(StrokeStyle(lineWidth: 1.5))
31 }
32
33 // Dimming overlay for trimmed start region
34 if lowerBound > 0, let startDate = samples.first?.date, let endDate = samples.last?.date {
35 let trimStart = startDate.addingTimeInterval(
36 lowerBound * endDate.timeIntervalSince(startDate)
37 )
38 RectangleMark(
39 xStart: .value("", startDate),
40 xEnd: .value("", trimStart)
41 )
42 .foregroundStyle(Color(.systemBackground).opacity(0.7))
43 }
44
45 // Dimming overlay for trimmed end region
46 if upperBound < 1, let startDate = samples.first?.date, let endDate = samples.last?.date {
47 let trimEnd = startDate.addingTimeInterval(
48 upperBound * endDate.timeIntervalSince(startDate)
49 )
50 RectangleMark(
51 xStart: .value("", trimEnd),
52 xEnd: .value("", endDate)
53 )
54 .foregroundStyle(Color(.systemBackground).opacity(0.7))
55 }
56 }
57 .chartXAxis(.hidden)
58 .chartYAxis {
59 AxisMarks(position: .leading, values: .automatic(desiredCount: 3)) { value in
60 AxisGridLine()
61 AxisValueLabel {
62 if let v = value.as(Double.self) {
63 Text("\(Int(v))")
64 .font(.caption2)
65 }
66 }
67 }
68 }
69 .chartYAxisLabel(metric.label, position: .leading)
70 }
71}