Skip to content

Commit 7b30835

Browse files
committed
- Added granular controls to charts, and hid them in a sheet. Now users can click the little gear button by the page title and bring up a window that shows options for that graph as well as a choice of the range of dates to show: all data, the last x [hours/days/weeks], or from and to date pickers.
- Changed buttons to pickers to prevent distortion on smaller screens or while using accessibility settings.
1 parent 1e004bb commit 7b30835

10 files changed

Lines changed: 265 additions & 141 deletions

File tree

Infini-iOS.xcodeproj/project.pbxproj

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@
4242
266F53E426F7FCA6007481A6 /* ChartManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 266F53E326F7FCA6007481A6 /* ChartManager.swift */; };
4343
266F53E626FA7676007481A6 /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 266F53E526FA7676007481A6 /* HomeScreen.swift */; };
4444
266F53EA26FA91F3007481A6 /* DeviceInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 266F53E926FA91F3007481A6 /* DeviceInfo.swift */; };
45-
266F53EC26FAABE7007481A6 /* TimeRangeTabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 266F53EB26FAABE7007481A6 /* TimeRangeTabs.swift */; };
4645
2675CA5A26DC81AA00967E4D /* DFUComplete.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2675CA5926DC81AA00967E4D /* DFUComplete.swift */; };
46+
268E773C27174A2B000DF90D /* ChartSettingsSheetMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 268E773B27174A2B000DF90D /* ChartSettingsSheetMain.swift */; };
47+
268E773F27174B8B000DF90D /* ChartSettingsSheetSliders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 268E773E27174B8B000DF90D /* ChartSettingsSheetSliders.swift */; };
48+
268E774127175830000DF90D /* ChartSettingsSheetDatePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 268E774027175830000DF90D /* ChartSettingsSheetDatePicker.swift */; };
4749
26A40E852704E6F3007966F6 /* SheetManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A40E842704E6F3007966F6 /* SheetManager.swift */; };
4850
26A40E892704E97C007966F6 /* DebugViewBLE.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A40E882704E97C007966F6 /* DebugViewBLE.swift */; };
4951
26A40E8B2704EB22007966F6 /* DebugViewDFU.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A40E8A2704EB22007966F6 /* DebugViewDFU.swift */; };
@@ -133,8 +135,10 @@
133135
266F53E326F7FCA6007481A6 /* ChartManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartManager.swift; sourceTree = "<group>"; };
134136
266F53E526FA7676007481A6 /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = "<group>"; };
135137
266F53E926FA91F3007481A6 /* DeviceInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceInfo.swift; sourceTree = "<group>"; };
136-
266F53EB26FAABE7007481A6 /* TimeRangeTabs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeRangeTabs.swift; sourceTree = "<group>"; };
137138
2675CA5926DC81AA00967E4D /* DFUComplete.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DFUComplete.swift; sourceTree = "<group>"; };
139+
268E773B27174A2B000DF90D /* ChartSettingsSheetMain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartSettingsSheetMain.swift; sourceTree = "<group>"; };
140+
268E773E27174B8B000DF90D /* ChartSettingsSheetSliders.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartSettingsSheetSliders.swift; sourceTree = "<group>"; };
141+
268E774027175830000DF90D /* ChartSettingsSheetDatePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartSettingsSheetDatePicker.swift; sourceTree = "<group>"; };
138142
26A40E842704E6F3007966F6 /* SheetManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SheetManager.swift; sourceTree = "<group>"; };
139143
26A40E882704E97C007966F6 /* DebugViewBLE.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugViewBLE.swift; sourceTree = "<group>"; };
140144
26A40E8A2704EB22007966F6 /* DebugViewDFU.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugViewDFU.swift; sourceTree = "<group>"; };
@@ -213,7 +217,6 @@
213217
263B20B626CD673D00676BF0 /* Chart View Components */ = {
214218
isa = PBXGroup;
215219
children = (
216-
266F53EB26FAABE7007481A6 /* TimeRangeTabs.swift */,
217220
263B20B426CD673900676BF0 /* ChartTabs.swift */,
218221
263B20B926CDF13400676BF0 /* HeartChart.swift */,
219222
263B20BB26CDF20400676BF0 /* BatteryChart.swift */,
@@ -332,6 +335,16 @@
332335
path = "View Utilities";
333336
sourceTree = "<group>";
334337
};
338+
268E773D27174B6D000DF90D /* ChartSettingsSheet */ = {
339+
isa = PBXGroup;
340+
children = (
341+
268E773B27174A2B000DF90D /* ChartSettingsSheetMain.swift */,
342+
268E773E27174B8B000DF90D /* ChartSettingsSheetSliders.swift */,
343+
268E774027175830000DF90D /* ChartSettingsSheetDatePicker.swift */,
344+
);
345+
path = ChartSettingsSheet;
346+
sourceTree = "<group>";
347+
};
335348
26A40E862704E7FD007966F6 /* Debug */ = {
336349
isa = PBXGroup;
337350
children = (
@@ -398,6 +411,7 @@
398411
children = (
399412
26A6316226C4C6D6005AE404 /* BLEConnectView.swift */,
400413
26A40E842704E6F3007966F6 /* SheetManager.swift */,
414+
268E773D27174B6D000DF90D /* ChartSettingsSheet */,
401415
26C5FAD726FC129400921207 /* ArbitraryNotificationView.swift */,
402416
26C5FAE226FEB0A400921207 /* DFUDownloadView.swift */,
403417
26C5FADB26FE7EB000921207 /* SheetCloseButton.swift */,
@@ -583,6 +597,7 @@
583597
2632388826F2576D00D72B43 /* DFUFileSelectButton.swift in Sources */,
584598
26F426EF26C72D7D00D0866B /* ChartView.swift in Sources */,
585599
266F53E426F7FCA6007481A6 /* ChartManager.swift in Sources */,
600+
268E773C27174A2B000DF90D /* ChartSettingsSheetMain.swift in Sources */,
586601
26B2BAF726F139D600FBC9CE /* DebugView.swift in Sources */,
587602
26A40E912707C7A3007966F6 /* BLEDiscoveredCharacteristics.swift in Sources */,
588603
264BFE7426BC526C0050A223 /* BLEManager.swift in Sources */,
@@ -598,7 +613,6 @@
598613
26A40E8B2704EB22007966F6 /* DebugViewDFU.swift in Sources */,
599614
263F56E026F13E760001BA4F /* DebugManager.swift in Sources */,
600615
26318B1626CB27E70036051E /* Infini_iOS.xcdatamodeld in Sources */,
601-
266F53EC26FAABE7007481A6 /* TimeRangeTabs.swift in Sources */,
602616
26C5FAD826FC129400921207 /* ArbitraryNotificationView.swift in Sources */,
603617
2617EF3D27036DC600FE6F48 /* WhatsNewBody.swift in Sources */,
604618
26A40E952708C7F8007966F6 /* ScanningPopover.swift in Sources */,
@@ -611,6 +625,7 @@
611625
263B20BC26CDF20400676BF0 /* BatteryChart.swift in Sources */,
612626
2644261226DC093D009BD54A /* SetTime.swift in Sources */,
613627
266F53E626FA7676007481A6 /* HomeScreen.swift in Sources */,
628+
268E774127175830000DF90D /* ChartSettingsSheetDatePicker.swift in Sources */,
614629
263B20B526CD673900676BF0 /* ChartTabs.swift in Sources */,
615630
26D7816E26CA003B00BBF555 /* SettingsFunctions.swift in Sources */,
616631
26A6316326C4C6D6005AE404 /* BLEConnectView.swift in Sources */,
@@ -620,6 +635,7 @@
620635
26C5FAD526FBB76100921207 /* DeviceNameManager.swift in Sources */,
621636
26A6315B26C49841005AE404 /* DFU.swift in Sources */,
622637
26D7817A26CAD19F00BBF555 /* ColorPalette.swift in Sources */,
638+
268E773F27174B8B000DF90D /* ChartSettingsSheetSliders.swift in Sources */,
623639
26A40EEA270A5F39007966F6 /* DFUStartButtonColorSelector.swift in Sources */,
624640
26A40EE8270A1F97007966F6 /* RenameDeviceHeader.swift in Sources */,
625641
266F53EA26FA91F3007481A6 /* DeviceInfo.swift in Sources */,

Infini-iOS/View Components/Chart View Components/ChartManager.swift

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ struct DataPoint {
2424

2525
class ChartManager: ObservableObject {
2626

27-
@Published var dateRange: DateRange = .day
2827
@Published var currentChart: chartSelection = .battery
2928
var lastChartWasHeart = UserDefaults.standard.value(forKey: "lastStatusViewWasHeart") as? Bool ?? false
29+
@Published var heartRangeSelectionState = DateSelectionState()
30+
@Published var batteryRangeSelectionState = DateSelectionState()
3031

3132
let viewContext = PersistenceController.shared.container.viewContext
3233

@@ -40,6 +41,19 @@ class ChartManager: ObservableObject {
4041
}
4142
}
4243

44+
struct DateSelectionState {
45+
var dateRangeSelection: Int = 0
46+
47+
// state variables for slider
48+
var hours: Float = 1
49+
var days: Float = 0
50+
var weeks: Float = 0
51+
52+
// state variables for date picker
53+
var endDate = Date()
54+
var startDate = Calendar.current.date(byAdding: .hour, value: -1, to: Date()) ?? (Date() - 2419200)
55+
}
56+
4357
@Published var trueIfHeart = true
4458
@Published var trueIfBat = false
4559

@@ -100,30 +114,31 @@ class ChartManager: ObservableObject {
100114
}
101115
}
102116

103-
func setTimeRange() -> Double {
104-
var dateValue: Double = 0
105-
switch dateRange {
106-
case .hour:
107-
dateValue = -3600
108-
case .day:
109-
dateValue = -86400
110-
case .week:
111-
dateValue = -604800
112-
}
113-
return dateValue
114-
}
115-
116117
func convert(results: FetchedResults<ChartDataPoint>) -> [LineChartDataPoint] {
118+
var dateRangeSelection: DateSelectionState
119+
if currentChart == .heart {
120+
dateRangeSelection = heartRangeSelectionState
121+
} else {
122+
dateRangeSelection = batteryRangeSelectionState
123+
}
117124
var dataPoints: [LineChartDataPoint] = []
118125
let dateFormat = DateFormatter()
119-
let timeRange = setTimeRange()
120126
dateFormat.dateFormat = "MMM d\nH:mm:ss"
121127
for data in results {
122-
if timeRange == 0 {
123-
dataPoints.append(LineChartDataPoint(value: data.value, xAxisLabel: "Time", description: dateFormat.string(from: data.timestamp!), date: data.timestamp!))
124-
} else if data.timestamp!.timeIntervalSinceNow >= setTimeRange() {
128+
switch dateRangeSelection.dateRangeSelection {
129+
case 1:
130+
let dateSum = (dateRangeSelection.hours * -3600) + (dateRangeSelection.days * -86400) + (dateRangeSelection.weeks * -604800)
131+
if data.timestamp!.timeIntervalSinceNow >= Double(dateSum) {
132+
dataPoints.append(LineChartDataPoint(value: data.value, xAxisLabel: "Time", description: dateFormat.string(from: data.timestamp!), date: data.timestamp!))
133+
}
134+
case 2:
135+
if data.timestamp! >= dateRangeSelection.startDate && data.timestamp! <= dateRangeSelection.endDate {
136+
dataPoints.append(LineChartDataPoint(value: data.value, xAxisLabel: "Time", description: dateFormat.string(from: data.timestamp!), date: data.timestamp!))
137+
}
138+
default:
125139
dataPoints.append(LineChartDataPoint(value: data.value, xAxisLabel: "Time", description: dateFormat.string(from: data.timestamp!), date: data.timestamp!))
126140
}
141+
127142
}
128143
return dataPoints
129144
}

Infini-iOS/View Components/Chart View Components/ChartTabs.swift

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,42 +18,18 @@ struct StatusTabs: View {
1818
@ObservedObject var chartManager = ChartManager.shared
1919

2020
var body: some View{
21-
VStack {
22-
HStack {
23-
Button (action: {
24-
chartManager.currentChart = .heart
25-
lastStatusViewWasHeart = true
26-
}) {
27-
(Text(Image(systemName: "heart"))
28-
.foregroundColor(Color.pink) +
29-
Text(": " + String(format: "%.0f", bleManager.heartBPM))
30-
.foregroundColor(Color.white) +
31-
Text(" BPM")
32-
.foregroundColor(Color.white)
33-
.font(.body))
34-
.frame(maxWidth:.infinity, alignment: .center)
35-
.padding()
36-
.background(colorScheme == .dark ? (chartManager.currentChart == .heart ? Color.darkGray : Color.darkestGray) : Color.blue)
37-
.opacity(colorScheme == .dark ? 1.0 : (chartManager.currentChart == .heart ? 1.0 : 0.3))
38-
.cornerRadius(5)
39-
.font(.title)
40-
}.padding(.leading, 10)
41-
Button (action: {
42-
chartManager.currentChart = .battery
43-
lastStatusViewWasHeart = false
44-
}) {
45-
(Text(Image(systemName: "battery.100"))
46-
.foregroundColor(Color.green) +
47-
Text(": " + String(format: "%.0f", bleManager.batteryLevel) + "%")
48-
.foregroundColor(Color.white))
49-
.frame(maxWidth: .infinity, alignment: .center)
50-
.padding()
51-
.background(colorScheme == .dark ? (chartManager.currentChart == .battery ? Color.darkGray : Color.darkestGray) : Color.blue)
52-
.opacity(colorScheme == .dark ? 1.0 : (chartManager.currentChart == .battery ? 1.0 : 0.3))
53-
.cornerRadius(5)
54-
.font(.title)
55-
}
56-
.padding(.trailing, 10)
21+
Picker("Chart", selection: $chartManager.currentChart) {
22+
Text("Heart: " + String(format: "%.0f", bleManager.heartBPM) + " BPM")
23+
.tag(ChartManager.chartSelection.heart)
24+
Text("Battery: " + String(format: "%.0f", bleManager.batteryLevel) + "%")
25+
.tag(ChartManager.chartSelection.battery)
26+
}
27+
.pickerStyle(.segmented)
28+
.onChange(of: chartManager.currentChart) { _ in
29+
if chartManager.currentChart == .heart {
30+
lastStatusViewWasHeart = true
31+
} else {
32+
lastStatusViewWasHeart = false
5733
}
5834
}
5935
}

Infini-iOS/View Components/Chart View Components/TimeRangeTabs.swift

Lines changed: 0 additions & 77 deletions
This file was deleted.

Infini-iOS/View Components/ChartView.swift

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,23 @@ struct ChartView: View {
1515

1616
var body: some View {
1717
VStack {
18-
Text("Charts")
19-
.font(.largeTitle)
20-
.padding()
21-
.frame(maxWidth: .infinity, alignment: .leading)
22-
TimeRangeTabs()
18+
HStack {
19+
Text("Charts")
20+
.font(.largeTitle)
21+
.padding(.leading)
22+
.padding(.vertical)
23+
.frame(alignment: .leading)
24+
Button {
25+
SheetManager.shared.sheetSelection = .chartSettings
26+
SheetManager.shared.showSheet = true
27+
} label: {
28+
Image(systemName: "gear")
29+
.imageScale(.large)
30+
.padding(.vertical)
31+
}
32+
Spacer()
33+
}
34+
// TimeRangeTabs()
2335
StatusTabs()
2436
CurrentChart()
2537
}

Infini-iOS/View Components/SettingsView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ struct Settings_Page: View {
8888
}
8989
Section(header: Text("Graph Data")) {
9090
Button (action: {
91-
ChartManager.shared.deleteAll(dataSet: chartPoints, chart: ChartsAsInts.battery.rawValue)
91+
ChartManager.shared.deleteAll(dataSet: chartPoints, chart: ChartsAsInts.heart.rawValue)
9292
}) {
9393
(Text("Clear All HRM Chart Data"))
9494
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//
2+
// ChartSettingsSheetDatePicker.swift
3+
// Infini-iOS
4+
//
5+
// Created by Alex Emry on 10/13/21.
6+
//
7+
//
8+
9+
10+
import SwiftUI
11+
12+
struct ChartSettingsSheetDatePicker: View {
13+
let today = Date()
14+
let oneMonthAgo = Calendar.current.date(byAdding: .month, value: -1, to: Date()) ?? (Date() - 2419200)
15+
16+
// @Binding var endDate: Date// = Date()
17+
// @Binding var startDate: Date// = Calendar.current.date(byAdding: .month, value: -1, to: Date())!
18+
19+
@Binding var chartRangeState: ChartManager.DateSelectionState
20+
21+
var body: some View {
22+
List {
23+
DatePicker(
24+
"Start Date",
25+
selection: $chartRangeState.startDate,
26+
in: oneMonthAgo...today,
27+
displayedComponents: [.date, .hourAndMinute]
28+
)
29+
DatePicker(
30+
"End Date",
31+
selection: $chartRangeState.endDate,
32+
in: oneMonthAgo...today,
33+
displayedComponents: [.date, .hourAndMinute]
34+
)
35+
}.listStyle(.insetGrouped)
36+
}
37+
}

0 commit comments

Comments
 (0)