LoopStatsView.swift 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import Charts
  2. import SwiftUI
  3. struct LoopStatsView: View {
  4. let loopStatRecords: [LoopStatRecord]
  5. let selectedDuration: Stat.StateModel.Duration
  6. let statsData: [(category: String, count: Int, percentage: Double)]
  7. var body: some View {
  8. VStack(spacing: 20) {
  9. Chart(statsData, id: \.category) { data in
  10. BarMark(
  11. x: .value("Percentage", data.percentage),
  12. y: .value("Category", data.category)
  13. )
  14. .cornerRadius(5)
  15. .foregroundStyle(data.category == "Successful Loops" ? Color.blue.gradient : Color.green.gradient)
  16. .annotation(position: .overlay) {
  17. HStack {
  18. Text(annotationText(for: data))
  19. .font(.callout)
  20. .foregroundStyle(.white)
  21. }
  22. }
  23. }
  24. .chartYAxis {
  25. AxisMarks { value in
  26. if let category = value.as(String.self) {
  27. AxisValueLabel {
  28. Text(category)
  29. .font(.footnote)
  30. }
  31. }
  32. }
  33. }
  34. .chartXAxis {
  35. AxisMarks(position: .bottom) { value in
  36. if let percentage = value.as(Double.self) {
  37. AxisValueLabel {
  38. Text("\(Int(percentage))%")
  39. .font(.footnote)
  40. }
  41. AxisGridLine()
  42. }
  43. }
  44. }
  45. .chartXScale(domain: 0 ... 100)
  46. .frame(height: 200)
  47. .padding()
  48. }
  49. }
  50. private func annotationText(for data: (category: String, count: Int, percentage: Double)) -> String {
  51. if data.category == "Loop Success Rate" {
  52. switch selectedDuration {
  53. case .Day,
  54. .Today:
  55. return "\(data.count) Loops"
  56. case .Month,
  57. .Total,
  58. .Week:
  59. let maxLoopsPerDay = 288.0
  60. let averageLoopsPerDay = Double(data.count) / maxLoopsPerDay * 100
  61. return "\(Int(round(averageLoopsPerDay))) Loops per day"
  62. }
  63. } else {
  64. // For Glucose Count, show different text based on duration
  65. switch selectedDuration {
  66. case .Day,
  67. .Today:
  68. return "\(data.count) Readings"
  69. case .Month,
  70. .Total,
  71. .Week:
  72. return "\(data.count) Readings per day"
  73. }
  74. }
  75. }
  76. }