| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import Charts
- import SwiftUI
- struct MealStatsView: View {
- let mealStats: [MealStats]
- let selectedDuration: Stat.StateModel.Duration
- private var hasData: Bool {
- mealStats.contains { $0.carbs > 0 || $0.fat > 0 || $0.protein > 0 }
- }
- var body: some View {
- ScrollView {
- if mealStats.isEmpty || !hasData {
- ContentUnavailableView(
- "No Meal Data",
- systemImage: "fork.knife",
- description: Text("Meal statistics will appear here once data is available.")
- )
- } else {
- StatCard {
- VStack(alignment: .leading, spacing: 8) {
- Text("Macronutrients")
- .font(.headline)
- Chart(mealStats) { stat in
- // Carbs Bar
- BarMark(
- x: .value("Date", stat.date, unit: .day),
- y: .value("Amount", stat.carbs),
- width: .ratio(0.6)
- )
- .foregroundStyle(Color.orange)
- .position(by: .value("Nutrient", "Carbs"))
- // Fat Bar
- BarMark(
- x: .value("Date", stat.date, unit: .day),
- y: .value("Amount", stat.fat),
- width: .ratio(0.6)
- )
- .foregroundStyle(Color.yellow)
- .position(by: .value("Nutrient", "Fat"))
- // Protein Bar
- BarMark(
- x: .value("Date", stat.date, unit: .day),
- y: .value("Amount", stat.protein),
- width: .ratio(0.6)
- )
- .foregroundStyle(Color.green)
- .position(by: .value("Nutrient", "Protein"))
- }
- .chartForegroundStyleScale([
- "Carbs": Color.orange,
- "Fat": Color.yellow,
- "Protein": Color.green
- ])
- .chartLegend(position: .top, alignment: .leading, spacing: 12)
- .frame(height: 200)
- .chartXAxis {
- mealChartXAxisMarks
- }
- .chartYAxis {
- mealChartYAxisMarks
- }
- }
- }
- .padding()
- }
- }
- }
- private var mealChartXAxisMarks: some AxisContent {
- AxisMarks { value in
- if let date = value.as(Date.self) {
- AxisValueLabel {
- switch selectedDuration {
- case .Day,
- .Today,
- .Week:
- Text(date, format: .dateTime.weekday(.abbreviated))
- case .Month,
- .Total:
- Text(date, format: .dateTime.day().month(.defaultDigits))
- }
- }
- AxisGridLine()
- }
- }
- }
- private var mealChartYAxisMarks: some AxisContent {
- AxisMarks(position: .leading) { value in
- if let amount = value.as(Double.self) {
- AxisValueLabel {
- Text("\(Int(amount))g")
- }
- AxisGridLine()
- }
- }
- }
- }
|