BolusStatsView.swift 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import Charts
  2. import SwiftUI
  3. struct BolusStatsView: View {
  4. let bolusStats: [BolusStats]
  5. @Binding var selectedDays: Int
  6. @Binding var selectedEndDate: Date
  7. var body: some View {
  8. StatCard {
  9. VStack(alignment: .leading, spacing: 8) {
  10. Text("Bolus Distribution")
  11. .font(.headline)
  12. Chart(bolusStats) { stat in
  13. // External Bolus (Bottom)
  14. BarMark(
  15. x: .value("Date", stat.date, unit: .day),
  16. y: .value("Amount", stat.external)
  17. )
  18. .foregroundStyle(by: .value("Type", "External"))
  19. // SMB (Middle)
  20. BarMark(
  21. x: .value("Date", stat.date, unit: .day),
  22. y: .value("Amount", stat.smb)
  23. )
  24. .foregroundStyle(by: .value("Type", "SMB"))
  25. // Manual Bolus (Top)
  26. BarMark(
  27. x: .value("Date", stat.date, unit: .day),
  28. y: .value("Amount", stat.manualBolus)
  29. )
  30. .foregroundStyle(by: .value("Type", "Manual"))
  31. }
  32. .chartForegroundStyleScale([
  33. "Manual": Color.teal,
  34. "SMB": Color.blue,
  35. "External": Color.purple
  36. ])
  37. .chartLegend(position: .top, alignment: .leading, spacing: 12)
  38. .frame(height: 200)
  39. .chartXAxis {
  40. bolusStatsChartXAxisMarks
  41. }
  42. .chartYAxis {
  43. bolusStatsChartYAxisMarks
  44. }
  45. }
  46. }
  47. }
  48. private var bolusStatsChartXAxisMarks: some AxisContent {
  49. AxisMarks { value in
  50. if let date = value.as(Date.self) {
  51. AxisValueLabel {
  52. if selectedDays < 8 {
  53. Text(date, format: .dateTime.weekday(.abbreviated))
  54. } else {
  55. Text(date, format: .dateTime.day().month(.defaultDigits))
  56. }
  57. }
  58. AxisGridLine()
  59. }
  60. }
  61. }
  62. private var bolusStatsChartYAxisMarks: some AxisContent {
  63. AxisMarks(position: .leading) { value in
  64. if let amount = value.as(Double.self) {
  65. AxisValueLabel {
  66. Text(amount.formatted(.number.precision(.fractionLength(1))) + " U")
  67. }
  68. AxisGridLine()
  69. }
  70. }
  71. }
  72. }