ironOS native ios app
1//
2// TemperatureGraph.swift
3// Tinkcil
4//
5
6import Charts
7import SwiftUI
8
9private struct ChartDataPoint: Identifiable {
10 let id: String
11 let timestamp: Date
12 let value: Int
13 let series: String
14}
15
16struct TemperatureGraph: View {
17 let history: [TemperaturePoint]
18 let currentSetpoint: Int
19 var windowSeconds: TimeInterval = 6
20 var showAxes: Bool = false
21 var tempLineWidth: CGFloat = 2.5
22 var setpointLineWidth: CGFloat = 1.5
23
24 private var chartData: [ChartDataPoint] {
25 var data: [ChartDataPoint] = []
26 for point in history {
27 data.append(ChartDataPoint(
28 id: "\(point.id)-setpoint",
29 timestamp: point.timestamp,
30 value: Int(point.setpoint),
31 series: "Setpoint"
32 ))
33 data.append(ChartDataPoint(
34 id: "\(point.id)-temp",
35 timestamp: point.timestamp,
36 value: Int(point.actualTemp),
37 series: "Temp"
38 ))
39 }
40 return data
41 }
42
43 private var lineColor: Color {
44 guard let last = history.last else { return .blue }
45 let temp = last.actualTemp
46 if temp < 150 { return .blue }
47 if temp < 300 { return .orange }
48 return .red
49 }
50
51 private func chartDataWithEdge(now: Date, windowSeconds: TimeInterval) -> [ChartDataPoint] {
52 var data: [ChartDataPoint] = []
53
54 // Add point at left edge to extend line to screen edge
55 if let first = history.first {
56 let windowStart = now.addingTimeInterval(-windowSeconds)
57 let leftEdge = windowStart.addingTimeInterval(-0.5)
58 data.append(ChartDataPoint(
59 id: "left-setpoint",
60 timestamp: leftEdge,
61 value: Int(first.setpoint),
62 series: "Setpoint"
63 ))
64 data.append(ChartDataPoint(
65 id: "left-temp",
66 timestamp: leftEdge,
67 value: Int(first.actualTemp),
68 series: "Temp"
69 ))
70 }
71
72 data.append(contentsOf: chartData)
73
74 // Add point at right edge to extend line to screen edge (1 sec ahead)
75 if let last = history.last {
76 let rightEdge = now.addingTimeInterval(1)
77 data.append(ChartDataPoint(
78 id: "edge-setpoint",
79 timestamp: rightEdge,
80 value: currentSetpoint,
81 series: "Setpoint"
82 ))
83 data.append(ChartDataPoint(
84 id: "edge-temp",
85 timestamp: rightEdge,
86 value: Int(last.actualTemp),
87 series: "Temp"
88 ))
89 }
90 return data
91 }
92
93 var body: some View {
94 TimelineView(.animation(paused: false)) { timeline in
95 let now = timeline.date
96 let xDomain = now.addingTimeInterval(-windowSeconds)...now.addingTimeInterval(1)
97
98 Chart(chartDataWithEdge(now: now, windowSeconds: windowSeconds)) { point in
99 LineMark(
100 x: .value("Time", point.timestamp),
101 y: .value("Value", point.value),
102 series: .value("Series", point.series)
103 )
104 .foregroundStyle(point.series == "Setpoint" ? Color.gray.opacity(0.4) : lineColor)
105 .lineStyle(StrokeStyle(lineWidth: point.series == "Setpoint" ? setpointLineWidth : tempLineWidth, lineCap: .round))
106 }
107 .chartXAxis(showAxes ? .automatic : .hidden)
108 .chartYAxis(showAxes ? .automatic : .hidden)
109 .chartLegend(.hidden)
110 .chartYScale(domain: 0...500)
111 .chartXScale(domain: xDomain)
112 .padding(.horizontal, showAxes ? 0 : -20)
113 }
114 }
115}