64 lines
2.4 KiB
Swift
64 lines
2.4 KiB
Swift
import SwiftUI
|
|
import Charts
|
|
import CoreData
|
|
|
|
struct MPGTrendChartView: View {
|
|
let fuelLogs: [FuelLog]
|
|
|
|
// Compute trend data by sorting logs by date ascending
|
|
// and calculating MPG for each interval where fullTank is true.
|
|
var trendData: [(date: Date, mpg: Double)] {
|
|
let sortedLogs = fuelLogs.sorted { ($0.date ?? Date()) < ($1.date ?? Date()) }
|
|
var data: [(Date, Double)] = []
|
|
// Start from index 1 because we need a previous log to compute the difference.
|
|
for i in 1..<sortedLogs.count {
|
|
let previous = sortedLogs[i - 1]
|
|
let current = sortedLogs[i]
|
|
if current.fullTank, !current.missedPrevious, let date = current.date,
|
|
current.odometer > previous.odometer,
|
|
current.fuelVolume > 0 {
|
|
let mpg = (current.odometer - previous.odometer) / current.fuelVolume
|
|
data.append((date, mpg))
|
|
}
|
|
}
|
|
return data
|
|
}
|
|
|
|
var body: some View {
|
|
VStack {
|
|
if trendData.isEmpty {
|
|
Text("No MPG trend data available.")
|
|
.foregroundColor(.secondary)
|
|
} else {
|
|
Chart {
|
|
// Enumerate the trend data to get an index for each data point.
|
|
ForEach(Array(trendData.enumerated()), id: \.element.date) { index, point in
|
|
LineMark(
|
|
x: .value("Date", point.date),
|
|
y: .value("MPG", point.mpg)
|
|
)
|
|
PointMark(
|
|
x: .value("Date", point.date),
|
|
y: .value("MPG", point.mpg)
|
|
)
|
|
.annotation(position: .top) {
|
|
// This annotation displays the data point number and the MPG value.
|
|
Text("\(point.mpg, specifier: "%.1f")")
|
|
.font(.caption2)
|
|
.foregroundColor(.blue)
|
|
}
|
|
}
|
|
}
|
|
.chartXAxis {
|
|
AxisMarks(values: .automatic(desiredCount: 6))
|
|
}
|
|
.chartYAxis {
|
|
AxisMarks(values: .automatic(desiredCount: 8))
|
|
}
|
|
}
|
|
}
|
|
.padding()
|
|
.navigationTitle("MPG Trend")
|
|
}
|
|
}
|