Add basic storage, temperature history display
This commit is contained in:
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
28
TempTrack/Views/HistoryList.swift
Normal file
28
TempTrack/Views/HistoryList.swift
Normal 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))
|
||||
}
|
||||
}
|
29
TempTrack/Views/HistoryListRow.swift
Normal file
29
TempTrack/Views/HistoryListRow.swift
Normal 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))
|
||||
}
|
||||
}
|
85
TempTrack/Views/TemperatureDayOverview.swift
Normal file
85
TempTrack/Views/TemperatureDayOverview.swift
Normal 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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
Reference in New Issue
Block a user