start of graphs

release
Laurent 3 years ago
parent a7ec081bd9
commit 0e311d6134
  1. 16
      LeCountdown/Model/Model+Extensions.swift
  2. 12
      LeCountdown/Stats/Context+Calculations.swift
  3. 17
      LeCountdown/Stats/Stat.swift
  4. 4
      LeCountdown/Views/Stats/ActivityView.swift
  5. 45
      LeCountdown/Views/Stats/StatsView.swift

@ -67,6 +67,8 @@ extension Stopwatch {
extension Record {
var count: Double { return 1.0 }
public override func didChangeValue(forKey key: String) {
super.didChangeValue(forKey: key)
@ -98,7 +100,19 @@ extension Record {
return "no details"
}
}
func point(stat: Stat) -> Point? {
if let start {
switch stat {
case .count:
return Point(date: start, value: NSNumber(value: 1))
case .totalDuration, .averageDuration:
return Point(date: start, value: NSNumber(value: self.duration))
}
}
return nil
}
}
extension Activity {

@ -36,7 +36,10 @@ extension NSManagedObjectContext {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Record")
let basePredicate = NSPredicate(format: "start != nil")
var predicates: [NSPredicate] = []
predicates.append(basePredicate)
predicates.append(NSPredicate(format: "activity = %@", activity))
if let filter {
predicates.append(filter.predicate)
@ -74,7 +77,14 @@ extension NSManagedObjectContext {
}
if let value {
let sv = StatValue(stat: stat, value: value)
let request = Record.fetchRequest()
if let filter {
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [basePredicate, filter.predicate])
}
let records: [Record] = try self.fetch(request)
let points = records.compactMap { $0.point(stat:stat) }
let sv = StatValue(stat: stat, value: value, records: points)
statValues.append(sv)
}
}

@ -55,6 +55,22 @@ enum Stat: Int, CaseIterable {
return .doubleAttributeType
}
}
// var keyPath: KeyPath<Record, NSNumber> {
// switch self {
// case .count: return \Record.count
// case .averageDuration, .totalDuration: return \Record.duration
// }
// }
}
struct Point: Identifiable {
var date: Date
var value: NSNumber
var id: Date { date }
}
struct StatValue: Identifiable {
@ -63,6 +79,7 @@ struct StatValue: Identifiable {
var stat: Stat
var value: NSDecimalNumber
var records: [Point] = []
var formattedValue: String {

@ -43,11 +43,9 @@ struct ActivityView: View {
StatsView(activity: self.activity)
.environment(\.managedObjectContext, viewContext)
.background(.red)
.foregroundColor(.white)
RecordsView(activity: self.activity)
.environment(\.managedObjectContext, viewContext)
.frame(maxWidth: .infinity)
// .frame(maxWidth: .infinity)
}
}

@ -7,6 +7,7 @@
import SwiftUI
import CoreData
import Charts
class StatModel: ObservableObject {
@ -59,11 +60,11 @@ struct StatsView: View {
} else {
VStack(alignment: .leading) {
ForEach(self.model.statValues) { statValue in
StatView(name: statValue.stat.localizedName, value: statValue.formattedValue).padding(.vertical)
StatGraphView(statValue: statValue)
// .padding(.vertical)
}
}
}
Spacer()
}
.onAppear() {
self.model.compute(activity: self.activity, filter: self.filter)
@ -75,13 +76,43 @@ struct StatsView: View {
struct StatView: View {
var name: String
var value: String
var statValue: StatValue
var body: some View {
VStack(alignment: .leading) {
Text(self.name.uppercased()).font(.footnote)
Text(self.value).font(.system(.title, weight: .bold))
Text(self.statValue.stat.localizedName.uppercased())
.font(.footnote)
Text(self.statValue.formattedValue)
.font(.system(.title, weight: .bold))
}
}
}
struct StatGraphView: View {
var statValue: StatValue
var body: some View {
VStack {
HStack {
Text(self.statValue.stat.localizedName.uppercased())
// .font(.footnote)
Text(self.statValue.formattedValue)
// .font(.system(.title, weight: .bold))
}
Chart(self.statValue.records) { point in
let stat: Stat = self.statValue.stat
switch stat {
case .count, .totalDuration:
BarMark(x: .value("name", point.date, unit: .month),
y: .value("value", point.value.doubleValue))
default:
LineMark(x: .value("name", point.date, unit: .month),
y: .value("value", point.value.doubleValue))
}
}
}
}
@ -89,7 +120,7 @@ struct StatView: View {
struct StatView_Previews: PreviewProvider {
static var previews: some View {
StatView(name: "Duration", value: "3")
StatView(statValue: StatValue(stat: .count, value: NSDecimalNumber(integerLiteral: 3)))
}
}

Loading…
Cancel
Save