You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
2.8 KiB
126 lines
2.8 KiB
//
|
|
// Stat.swift
|
|
// LeCountdown
|
|
//
|
|
// Created by Laurent Morvillier on 20/02/2023.
|
|
//
|
|
|
|
import Foundation
|
|
import CoreData
|
|
|
|
enum Stat: Int, CaseIterable {
|
|
case count
|
|
case totalDuration
|
|
case averageDuration
|
|
|
|
var localizedName: String {
|
|
switch self {
|
|
case .count: return NSLocalizedString("Count", comment: "")
|
|
case .totalDuration: return NSLocalizedString("Duration", comment: "")
|
|
case .averageDuration: return NSLocalizedString("Average duration", comment: "")
|
|
}
|
|
}
|
|
|
|
var field: String {
|
|
switch self {
|
|
case .count:
|
|
return "duration"
|
|
case .totalDuration:
|
|
return "duration"
|
|
case .averageDuration:
|
|
return "duration"
|
|
}
|
|
}
|
|
|
|
var function: String {
|
|
switch self {
|
|
case .count:
|
|
return "count:"
|
|
case .totalDuration:
|
|
return "sum:"
|
|
case .averageDuration:
|
|
return "average:"
|
|
}
|
|
}
|
|
|
|
var stringIdentifier: String {
|
|
return self.function + self.field
|
|
}
|
|
|
|
var type: NSAttributeType {
|
|
switch self {
|
|
case .count:
|
|
return .integer32AttributeType
|
|
default:
|
|
return .doubleAttributeType
|
|
}
|
|
}
|
|
|
|
var calendarYUnit: Calendar.Component? {
|
|
switch self {
|
|
case .totalDuration, .averageDuration:
|
|
return .hour
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
struct Point: Identifiable {
|
|
var date: Date
|
|
var value: NSNumber
|
|
|
|
var id: Date { date }
|
|
|
|
}
|
|
|
|
struct ChartPoint: Identifiable {
|
|
var index: Int
|
|
var label: String
|
|
var value: NSNumber
|
|
|
|
var id: Int { index }
|
|
}
|
|
|
|
struct StatValue: Identifiable {
|
|
|
|
var id: Int { return self.stat.rawValue }
|
|
|
|
var stat: Stat
|
|
var value: NSDecimalNumber
|
|
var points: [Point] = []
|
|
|
|
var formattedValue: String {
|
|
|
|
switch self.stat {
|
|
case .averageDuration, .totalDuration:
|
|
return self.value.doubleValue.minuteSecond
|
|
default:
|
|
let formatter: NumberFormatter = NumberFormatter()
|
|
return formatter.string(from: self.value) ?? "--"
|
|
}
|
|
|
|
}
|
|
|
|
func chartPoint(timeFrame: TimeFrame) -> [ChartPoint] {
|
|
|
|
var chartPoints: [ChartPoint] = []
|
|
|
|
for (i, point) in self.points.enumerated() {
|
|
|
|
let identifier: String
|
|
switch timeFrame {
|
|
case .all: identifier = point.date.formattedYear
|
|
case .year: identifier = point.date.formattedMonth
|
|
case .month: identifier = point.date.formattedDay
|
|
}
|
|
|
|
let cp = ChartPoint(index: i, label: identifier, value: point.value)
|
|
chartPoints.append(cp)
|
|
}
|
|
|
|
return chartPoints
|
|
}
|
|
|
|
}
|
|
|