MealStatsView.swift 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import Charts
  2. import SwiftUI
  3. struct MealStatsView: View {
  4. let mealStats: [MealStats]
  5. let selectedDuration: Stat.StateModel.Duration
  6. var body: some View {
  7. StatCard {
  8. VStack(alignment: .leading, spacing: 8) {
  9. Text("Macronutrients")
  10. .font(.headline)
  11. Chart(mealStats) { stat in
  12. // Carbs Bar
  13. BarMark(
  14. x: .value("Date", stat.date, unit: .day),
  15. y: .value("Amount", stat.carbs),
  16. width: .ratio(0.6)
  17. )
  18. .foregroundStyle(Color.orange)
  19. .position(by: .value("Nutrient", "Carbs"))
  20. // Fat Bar
  21. BarMark(
  22. x: .value("Date", stat.date, unit: .day),
  23. y: .value("Amount", stat.fat),
  24. width: .ratio(0.6)
  25. )
  26. .foregroundStyle(Color.yellow)
  27. .position(by: .value("Nutrient", "Fat"))
  28. // Protein Bar
  29. BarMark(
  30. x: .value("Date", stat.date, unit: .day),
  31. y: .value("Amount", stat.protein),
  32. width: .ratio(0.6)
  33. )
  34. .foregroundStyle(Color.green)
  35. .position(by: .value("Nutrient", "Protein"))
  36. }
  37. .chartForegroundStyleScale([
  38. "Carbs": Color.orange,
  39. "Fat": Color.yellow,
  40. "Protein": Color.green
  41. ])
  42. .chartLegend(position: .top, alignment: .leading, spacing: 12)
  43. .frame(height: 200)
  44. .chartXAxis {
  45. mealChartXAxisMarks
  46. }
  47. .chartYAxis {
  48. mealChartYAxisMarks
  49. }
  50. }
  51. }
  52. }
  53. private var mealChartXAxisMarks: some AxisContent {
  54. AxisMarks { value in
  55. if let date = value.as(Date.self) {
  56. AxisValueLabel {
  57. switch selectedDuration {
  58. case .Day,
  59. .Today,
  60. .Week:
  61. Text(date, format: .dateTime.weekday(.abbreviated))
  62. case .Month,
  63. .Total:
  64. Text(date, format: .dateTime.day().month(.defaultDigits))
  65. }
  66. }
  67. AxisGridLine()
  68. }
  69. }
  70. }
  71. private var mealChartYAxisMarks: some AxisContent {
  72. AxisMarks(position: .leading) { value in
  73. if let amount = value.as(Double.self) {
  74. AxisValueLabel {
  75. Text("\(Int(amount))g")
  76. }
  77. AxisGridLine()
  78. }
  79. }
  80. }
  81. }