Hello!
I am working on an Expense Tracker app where a user inputs their expense & the data is stored in Firestore.
I have one page where I display all payments & I display the data by fetching all from Firestore. And this query works without an issue.
func getAllPayments() {
db.collection("payments")
.order(by: "paymentDate", descending: true)
.addSnapshotListener { querySnapshot, error in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
self.payments = documents.compactMap { (queryDocumentSnapshot) -> Payment? in
return try? queryDocumentSnapshot.data(as: Payment.self)
}
}
}
But I also want to display some Swift Charts with filtered data based on current day, current month, current year. Have been searching around but completely stumped! I feel like I need another function using the one above to filter the full amount of data? But just canāt get to it!
My model, I have a paymentDate, which stores the date:
struct Payment: Hashable, Identifiable, Codable {
var id:String? = UUID().uuidString
var paymentName:String
var paymentAmount:Double
var paymentCurrency:String
var paymentCategory:String
var paymentPlan:String
var paymentDate:Date
}
The chart page that I am using for Month (& have a pretty identical one for Day). At the bottom Iām currenty calling the getAllPayments function, which is why I am getting all payments but just not sure how to filter it down to the right dates.
struct MonthlySpend: View {
@EnvironmentObject var paymentModel:PaymentModel
var primaryColor = "Primary"
var secondaryColor = "Secondary"
var secondaryText = "SecondaryText"
var body: some View {
ZStack {
PopoutCard()
.frame(height:300)
VStack {
HStack {
Text("MONTH")
.font(.system(size: 18, weight: .bold))
Spacer()
VStack (alignment: .trailing) {
Text("$500")
.foregroundColor(Color(primaryColor))
.font(.system(size: 18, weight: .bold))
Text("SPENT")
.font(.system(size: 12))
}
}
.padding()
Chart {
RuleMark(y: .value("Average", 380))
.foregroundStyle(Color(primaryColor))
.lineStyle(StrokeStyle(lineWidth: 1, dash: [5]))
.annotation(alignment: .leading) {
Text("Avg.")
.font(.caption)
.foregroundColor(Color(secondaryText))
}
ForEach(paymentModel.payments, id: \.paymentDate) { payment in
BarMark(
x: .value("month", payment.paymentDate, unit: .month),
y: .value("Amount", payment.paymentAmount)
)
}
}
.frame(height: 180)
.padding()
.chartXAxis {
AxisMarks() { date in
AxisValueLabel()
}
}
}
.onAppear() {
self.paymentModel.getAllPayments()
}
}
}
}