LoopBarChartView.swift 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import Charts
  2. import SwiftUI
  3. struct LoopBarChartView: View {
  4. let loopStatRecords: [LoopStatRecord]
  5. let selectedInterval: Stat.StateModel.StatsTimeIntervalWithToday
  6. let statsData: [LoopStatsProcessedData]
  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.displayName)
  13. )
  14. .cornerRadius(5)
  15. .foregroundStyle(data.category == .successfulLoop ? Color.blue : Color.green)
  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. if selectedInterval != .today {
  38. AxisValueLabel {
  39. Text("\(Int(percentage))%")
  40. .font(.footnote)
  41. }
  42. }
  43. AxisGridLine()
  44. }
  45. }
  46. }
  47. .chartXScale(domain: 0 ... 100)
  48. .frame(height: 200)
  49. .padding()
  50. }
  51. }
  52. private func annotationText(for data: LoopStatsProcessedData) -> String {
  53. if data.category == .successfulLoop {
  54. switch selectedInterval {
  55. case .day,
  56. .today:
  57. return "\(data.count) " + String(localized: "Loops")
  58. case .month,
  59. .total,
  60. .week:
  61. return "\(data.count) " + String(localized: "Loops per Day")
  62. }
  63. } else {
  64. // For Glucose Count, show different text based on duration
  65. switch selectedInterval {
  66. case .day,
  67. .today:
  68. return "\(data.count) " + String(localized: "Readings")
  69. case .month,
  70. .total,
  71. .week:
  72. return "\(data.count) " + String(localized: "Readings per Day")
  73. }
  74. }
  75. }
  76. }