109 lines
4.4 KiB
Swift
109 lines
4.4 KiB
Swift
//
|
|
// ChartDataBuildable.swift
|
|
// Feels
|
|
//
|
|
// Created by Trey Tartt on 1/17/22.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
typealias Year = Int
|
|
typealias Month = Int
|
|
|
|
protocol ChartDataBuildable {
|
|
associatedtype ChartType: ChartViewItemBuildable
|
|
// [Year: [Month: [View]]
|
|
func buildGridData(withData data: [MoodEntry]) -> [Year: [Month: [ChartType]]]
|
|
}
|
|
|
|
extension ChartDataBuildable {
|
|
public func buildGridData(withData data: [MoodEntry]) -> [Year: [Month: [ChartType]]] {
|
|
var returnData = [Int: [Int: [ChartType]]]()
|
|
|
|
if let earliestEntry = data.first,
|
|
let lastEntry = data.last {
|
|
|
|
let calendar = Calendar.current
|
|
let components = calendar.dateComponents([.year], from: earliestEntry.forDate!)
|
|
let earliestYear = components.year!
|
|
|
|
let latestComponents = calendar.dateComponents([.year], from: lastEntry.forDate!)
|
|
let latestYear = latestComponents.year!
|
|
|
|
for year in earliestYear...latestYear {
|
|
var allMonths = [Int: [ChartType]]()
|
|
|
|
// add back in if months header has leading (-1, ""),
|
|
// and add back gridItem
|
|
// var dayViews = [DayChartView]()
|
|
// for day in 0...32 {
|
|
// let view = DayChartView(color: Mood.missing.color,
|
|
// weekDay: 2,
|
|
// viewType: .text(String(day+1)))
|
|
// dayViews.append(view)
|
|
// }
|
|
// allMonths[0] = dayViews
|
|
|
|
for month in (1...12) {
|
|
var components = DateComponents()
|
|
components.month = month
|
|
components.year = year
|
|
let startDateOfMonth = Calendar.current.date(from: components)!
|
|
|
|
let items = data.filter({ entry in
|
|
let components = calendar.dateComponents([.month, .year], from: startDateOfMonth)
|
|
let entryComponents = calendar.dateComponents([.month, .year], from: entry.forDate!)
|
|
return (components.month == entryComponents.month && components.year == entryComponents.year)
|
|
})
|
|
|
|
allMonths[month] = createViewFor(monthEntries: items, forMonth: startDateOfMonth)
|
|
}
|
|
returnData[year] = allMonths
|
|
}
|
|
}
|
|
return returnData
|
|
}
|
|
|
|
private func createViewFor(monthEntries: [MoodEntry], forMonth month: Date) -> [ChartType] {
|
|
var filledOutArray = [ChartType]()
|
|
|
|
let calendar = Calendar.current
|
|
let range = calendar.range(of: .day, in: .month, for: month)!
|
|
let numDays = range.count
|
|
|
|
for day in 1...numDays {
|
|
if let item = monthEntries.filter({ entry in
|
|
let components = calendar.dateComponents([.day], from: entry.forDate!)
|
|
let date = components.day
|
|
return day == date
|
|
}).first {
|
|
let moodTint: MoodTintable.Type = UserDefaultsStore.moodTintable()
|
|
|
|
let view = ChartType(color: moodTint.color(forMood: item.mood),
|
|
weekDay: Int(item.weekDay),
|
|
shape: UserDefaultsStore.getCustomBGShape())
|
|
filledOutArray.append(view)
|
|
} else {
|
|
let thisDate = Calendar.current.date(bySetting: .day, value: day, of: month)!
|
|
let view = ChartType(color: Mood.placeholder.color,
|
|
weekDay: Calendar.current.component(.weekday, from: thisDate),
|
|
shape: UserDefaultsStore.getCustomBGShape())
|
|
filledOutArray.append(view)
|
|
}
|
|
}
|
|
|
|
for _ in filledOutArray.count...32 {
|
|
let view = ChartType(color: Mood.placeholder.color,
|
|
weekDay: 2,
|
|
shape: UserDefaultsStore.getCustomBGShape())
|
|
filledOutArray.append(view)
|
|
}
|
|
|
|
return filledOutArray
|
|
}
|
|
}
|
|
|
|
struct DayChartViewChartBuilder: ChartDataBuildable {
|
|
typealias ChartType = DayChartView
|
|
}
|