-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDashboardChart.swift
More file actions
113 lines (97 loc) · 2.9 KB
/
DashboardChart.swift
File metadata and controls
113 lines (97 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//
// DashboardChart.swift
// Stanford360
//
// Created by Kelly Bonilla Guzmán on 3/2/25.
//
// SPDX-FileCopyrightText: 2025 Stanford University
//
// SPDX-License-Identifier: MIT
//
import Charts
import Foundation
import SwiftUI
struct DashboardChart: View {
@Environment(ActivityManager.self) private var activityManager
@Environment(HydrationManager.self) private var hydrationManager
@Environment(ProteinManager.self) private var proteinManager
var timeFrame: TimeFrame
private var dates: [Date] {
let (startDate, endDate) = timeFrame.dateRange()
var dates: [Date] = []
let calendar = Calendar.current
var currentDate = calendar.startOfDay(for: startDate)
while currentDate <= endDate {
dates.append(currentDate)
currentDate = calendar.date(byAdding: .day, value: 1, to: currentDate) ?? Date()
}
return dates
}
var body: some View {
Chart {
ForEach(dates, id: \.self) { date in
let activities = getActivities(from: date)
LineMark(
x: .value("Week", date),
y: .value("Activity Minutes", activityManager.getTotalActivityMinutes(activities)),
series: .value("Metric", "Activity")
)
.applyChartStyle(color: Color.activityColor)
let hydration = getHydration(from: date)
LineMark(
x: .value("Week", date),
y: .value("Hydration Ounces", hydrationManager.getTotalHydrationOunces(hydration)),
series: .value("Metric", "Hydration")
)
.applyChartStyle(color: Color.hydrationColor)
let meals = getMeals(from: date)
LineMark(
x: .value("Week", date),
y: .value("Protein Grams", proteinManager.getTotalProteinGrams(meals)),
series: .value("Metric", "Protein")
)
.applyChartStyle(color: Color.proteinColor)
}
goalLine()
}
.frame(height: 300)
.padding(.leading, 40)
.padding(.trailing, 10)
.chartXAxis {
AxisMarks(values: .stride(by: .day)) { value in
if let date = value.as(Date.self) {
AxisValueLabel(date.formatted(.dateTime.weekday(.abbreviated)))
}
}
}
}
private func getActivities(from date: Date) -> [Activity] {
activityManager.activitiesByDate[date] ?? []
}
private func getHydration(from date: Date) -> [HydrationLog] {
hydrationManager.hydrationByDate[date] ?? []
}
private func getMeals(from date: Date) -> [Meal] {
proteinManager.mealsByDate[date] ?? []
}
}
extension LineMark {
func applyChartStyle(color: Color) -> some ChartContent {
self
.foregroundStyle(color)
.symbol {
Circle()
.fill(color)
.frame(width: 5, height: 5)
}
}
}
#Preview {
@Previewable @State var activityManager = ActivityManager(activities: activitiesData)
@Previewable @State var hydrationManager = HydrationManager(hydration: hydrationData)
@Previewable @State var proteinManager = ProteinManager(meals: mealsData)
DashboardChart(timeFrame: .week)
.environment(activityManager)
.environment(hydrationManager)
.environment(proteinManager)
}