Add basic storage, temperature history display

This commit is contained in:
Christoph Hagen
2023-06-08 09:52:20 +02:00
parent 002eb11dc1
commit 147cd6a306
22 changed files with 843 additions and 211 deletions

View File

@ -17,9 +17,6 @@ struct DeviceInfoView: View {
@Binding
var isPresented: Bool
@Binding
var updateToggle: Bool
private var runTimeString: String {
let number = info.numberOfSecondsRunning
@ -101,6 +98,10 @@ struct DeviceInfoView: View {
}
}
var updateText: String {
return "Updated \(info.receivedDate.timePassedText)"
}
var body: some View {
VStack(alignment: .leading, spacing: 5) {
HStack {
@ -164,9 +165,11 @@ struct DeviceInfoView: View {
Spacer()
HStack {
Spacer()
Text("Updated \(info.receivedDate.timePassedText)")
.font(.footnote)
.textCase(.uppercase)
TimelineView(.periodic(from: Date(), by: 1)) { context in
Text(updateText)
.font(.footnote)
.textCase(.uppercase)
}
Spacer()
}
}.padding()
@ -175,11 +178,8 @@ struct DeviceInfoView: View {
struct DeviceInfoView_Previews: PreviewProvider {
static var previews: some View {
DeviceInfoView(
info: .mock,
isPresented: .constant(true),
updateToggle: .constant(true))
.previewLayout(.fixed(width: 375, height: 600))
DeviceInfoView(info: .mock, isPresented: .constant(true))
.previewLayout(.fixed(width: 375, height: 600))
}
}

View File

@ -0,0 +1,28 @@
import SwiftUI
struct HistoryList: View {
@EnvironmentObject
var storage: TemperatureStorage
var body: some View {
NavigationView {
List(storage.dailyMeasurementCounts) { day in
NavigationLink(destination: {
TemperatureDayOverview(storage: storage, dateIndex: day.dateIndex)
}) {
HistoryListRow(entry: day)
}
}
.navigationTitle("History")
.navigationBarTitleDisplayMode(.large)
}
}
}
struct HistoryList_Previews: PreviewProvider {
static var previews: some View {
HistoryList()
.environmentObject(TemperatureStorage(lastMeasurements: TemperatureMeasurement.mockData))
}
}

View File

@ -0,0 +1,29 @@
import SwiftUI
import SFSafeSymbols
private let df: DateFormatter = {
let df = DateFormatter()
df.dateStyle = .short
df.timeStyle = .none
return df
}()
struct HistoryListRow: View {
let entry: MeasurementDailyCount
var body: some View {
HStack {
Image(systemSymbol: .calendar)
Text(df.string(from: entry.date))
Spacer()
Text("\(entry.count)")
}
}
}
struct HistoryListRow_Previews: PreviewProvider {
static var previews: some View {
HistoryListRow(entry: .init(dateIndex: Date().dateIndex, count: 123))
}
}

View File

@ -0,0 +1,85 @@
import SwiftUI
import Charts
struct TemperatureDayOverview: View {
let storage: TemperatureStorage
@State
var points: [TemperatureMeasurement] = []
init(storage: TemperatureStorage, dateIndex: Int) {
self.storage = storage
let points = storage.loadMeasurements(for: dateIndex)
print("Loaded \(points.count) points for date \(dateIndex)")
self.points = points
update()
}
mutating func update() {
self.upperTempLimit = max(40, points.maximumValue() ?? 40)
self.lowerTempLimit = min(-20, points.minimumValue() ?? -20)
let startDay = points.first?.date.dateIndex ?? Date().dateIndex
self.pastDateLimit = Date(dateIndex: startDay)
let endDay = (points.last?.date.dateIndex ?? Date().dateIndex) + 1
self.futureDateLimit = Date(dateIndex: endDay)
}
var upperTempLimit: Double = 40.0
var lowerTempLimit: Double = -20
var pastDateLimit: Date = Date().startOfDay
var futureDateLimit: Date = Date().startOfNextDay
var body: some View {
Chart {
ForEach(points) { point in
if let s = point.sensor0.optionalValue {
LineMark(
x: .value("Date", point.date),
y: .value("Temperature", s))
.foregroundStyle(by: .value("Type", "Sensor 0"))
}
if let s = point.sensor1.optionalValue {
LineMark(
x: .value("Date", point.date),
y: .value("Temperature", s))
.foregroundStyle(by: .value("Type", "Sensor 1"))
}
}
}
.aspectRatio(2.6, contentMode: .fit)
//.chartXScale(domain: pastDateLimit...futureDateLimit)
.chartYScale(domain: lowerTempLimit...upperTempLimit)
.chartXAxis {
AxisMarks(preset: .automatic)
AxisMarks.init(values: AxisMarkValues.stride(by: .hour)) {
AxisGridLine()
}
}
.chartYAxis {
AxisMarks(position: .trailing, values: .automatic) { value in
AxisValueLabel(multiLabelAlignment: .trailing) {
if let intValue = value.as(Int.self) {
Text("\(intValue)°")
.font(.system(size: 10))
//.foregroundColor(.white)
}
}
}
AxisMarks.init(values: AxisMarkValues.stride(by: 5)) {
AxisGridLine()
}
}
.padding()
}
}
struct TemperatureDayOverview_Previews: PreviewProvider {
static var previews: some View {
TemperatureDayOverview(storage: TemperatureStorage.mock, dateIndex: Date().dateIndex)
.previewLayout(.fixed(width: 350, height: 150))
//.background(.gray)
}
}

View File

@ -3,7 +3,8 @@ import Charts
struct TemperatureHistoryChart: View {
let points: [TemperatureMeasurement]
@Binding
var points: [TemperatureMeasurement]
let upperTempLimit = 40.0
let lowerTempLimit = -20.0
@ -16,13 +17,13 @@ struct TemperatureHistoryChart: View {
ForEach(points) { point in
if let s = point.sensor0.optionalValue {
LineMark(
x: .value("Date", point.secondsAgo),
x: .value("Date", point.secondsToNow),
y: .value("Temperature", s))
.foregroundStyle(Color.red)
}
if let s = point.sensor1.optionalValue {
LineMark(
x: .value("Date", point.secondsAgo),
x: .value("Date", point.secondsToNow),
y: .value("Temperature", s))
.foregroundStyle(by: .value("Type", "Sensor 1"))
}
@ -36,13 +37,12 @@ struct TemperatureHistoryChart: View {
AxisMarks(position: .trailing, values: .automatic) { value in
AxisValueLabel(multiLabelAlignment: .trailing) {
if let intValue = value.as(Int.self) {
Text("\(intValue) km")
Text("\(intValue)°")
.font(.system(size: 10))
.foregroundColor(.white)
}
}
}
//AxisMarks(position: .trailing, stroke: StrokeStyle(lineWidth: 0))
}
.padding()
}
@ -51,7 +51,7 @@ struct TemperatureHistoryChart: View {
struct TemperatureHistoryChart_Previews: PreviewProvider {
static var previews: some View {
TemperatureHistoryChart(
points: TemperatureMeasurement.mockData)
points: .constant(TemperatureMeasurement.mockData))
.previewLayout(.fixed(width: 350, height: 150))
.background(.gray)
}