HealthImport/HealthImport/Workouts/HeartRateGraph.swift
2024-03-20 14:51:46 +01:00

81 lines
2.2 KiB
Swift

import SwiftUI
import Charts
struct HeartRateGraph: View {
let measurements: [HRSample]
let width: CGFloat
init(measurements: [HRSample], width: CGFloat = 5.0) {
self.measurements = measurements
self.width = width
self.maximumValue = measurements.map { $0.max }.max() ?? 100
self.minimumValue = measurements.map { $0.min }.min() ?? 80
}
private let maximumValue: Int
private let minimumValue: Int
var range: ClosedRange<Int> {
(minimumValue-10)...(maximumValue+10)
}
var body: some View {
ZStack {
Chart(measurements, id: \.id) {
BarMark(x: .value("Time Start", $0.startDate),
yStart: .value("BPM Min", $0.min - 1),
yEnd: .value("BPM Max", $0.max + 1),
width: .inset(1))
.clipShape(Capsule())
.foregroundStyle(.red)
}
.chartYScale(domain: range)
.chartXAxis {
AxisMarks {
AxisValueLabel()
AxisGridLine(stroke: .init())
}
}
.chartYAxis {
AxisMarks {
AxisValueLabel()
}
}
.chartYAxis(.hidden)
HStack {
Spacer()
VStack(alignment: .trailing) {
Text("\(maximumValue)")
Spacer()
Text("\(minimumValue)")
}
.foregroundStyle(Color.primary.opacity(0.8))
.font(.caption)
}
}
}
}
#Preview {
let now = Date.now
let count = 50
let interval = TimeInterval(600)
let samples = (0..<count).map {
let start = now.addingTimeInterval(TimeInterval($0) * interval)
return HRSample(date: start,
duration: interval,
min: ($0 * 5) % 100 + 50,
max: ($0 * 5) % 100 + 70)
}
return HeartRateGraph(measurements: samples)
.padding(5)
.background(Color.gray.opacity(0.7))
.clipShape(RoundedRectangle(cornerSize: .init(width: 8, height: 8)))
.frame(height: 120)
.padding()
}