You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
10 KiB
208 lines
10 KiB
// |
|
// BloodOxygenViewModels.swift |
|
// Lookfit |
|
// |
|
// Created by Sheldon on 2021/9/22. |
|
// Copyright © 2021 Sheldon. All rights reserved. |
|
// |
|
|
|
import UIKit |
|
|
|
class BloodOxygenViewModels: ViewModel { |
|
|
|
// 图表数据 |
|
lazy var relay: BehaviorRelay<ChartViewModel> = { |
|
return BehaviorRelay<ChartViewModel>(value: defaultVM) |
|
}() |
|
// 底部数据 |
|
let formRealy = BehaviorRelay<HealthFormModel?>(value: nil) |
|
// 默认数据 |
|
private lazy var defaultVM: ChartViewModel = { |
|
let chartViewModel: ChartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: nil, source: [], chartType: .gradentFill, maxAxis: 0, xAxis: [], lineColor: kHexColor(0xED6565), isContinuous: false, isShowMeasureLine: false) |
|
return chartViewModel |
|
}() |
|
/// 当前时间(默认当前) |
|
private var currenTimeStr = DateClass.getCurrentTimeStr(formatStr: "yyyy-MM-dd") |
|
private var queryType: DataQueryType = .day |
|
|
|
override init() { |
|
super.init() |
|
// 默认加载当天 |
|
loadData(timeStr: currenTimeStr, queryType: queryType) |
|
} |
|
|
|
// 数据 |
|
func loadData(timeStr: String?, queryType: DataQueryType?) { |
|
// 无查询类型默认为上一次查询类型 |
|
let tempQueryType = queryType == nil ? self.queryType : queryType! |
|
self.queryType = tempQueryType |
|
// 查询时间戳 |
|
let tempTimeStr = timeStr == nil ? currenTimeStr : timeStr! |
|
currenTimeStr = tempTimeStr |
|
DataBaseManager.shared.queryBloodOxygenData(dataDate: tempTimeStr, queryType: tempQueryType) { [weak self] (results) in |
|
guard let `self` = self else { return } |
|
guard let modelArr = results as? [BloodOxygenModel], modelArr.count > 0 else { |
|
self.relay.accept(self.defaultVM) |
|
self.formRealy.accept(nil) |
|
return |
|
} |
|
// 拼接数据模型 |
|
var chartViewModel: ChartViewModel! |
|
var formModel: HealthFormModel? |
|
switch tempQueryType { |
|
case .day: |
|
let model = modelArr.first! |
|
if model.bloodOxygenAvg == 0 { |
|
self.relay.accept(self.defaultVM) |
|
self.formRealy.accept(nil) |
|
return |
|
} |
|
let sources = self.getFilterDatas(dateStr: model.dataDate, details: model.details) |
|
let maxAxis = sources.map{ $0.value }.max() |
|
chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: nil, source: sources, chartType: .gradentFill, maxAxis: maxAxis, xAxis: ["00:00", "06:00", "12:00", "18:00", "24:00"], lineColor: kHexColor(0xD81E20), isContinuous: false, isShowMeasureLine: false, center: String(model.bloodOxygenAvg), centerColor: kHexColor(0xD81E20), centerUnit: MultiLanguageKey.bloodOxygenUnit.localized) |
|
// 底部数据总和 |
|
formModel = HealthFormModel(oneValue: String(model.bloodOxygenAvg), twoValue: String(model.bloodOxygenMax), threeValue: String(model.bloodOxygenMin), fourValue: "") |
|
break |
|
case .week: |
|
// 获取一周时间戳数组 |
|
let weeks = (0...6).map { DateClass.dateStringOffset(from: tempTimeStr, offset: $0) } |
|
var sources: [ChartViewData] = [] |
|
var maxAxis = 0 |
|
var totalAvg = 0 |
|
var minValue = 0 |
|
var xAxis: [String] = [] |
|
// 边里匹配对应日期数据数组 |
|
for dataDate in weeks { |
|
let showDate = DateClass.getTimeStrToDate(formatStr: "yyyy-MM-dd", timeStr: dataDate).tranFormDateStr(format: "MM/dd") |
|
xAxis.append(showDate) |
|
var isMatch = false |
|
for model in modelArr { |
|
if dataDate == model.dataDate { |
|
isMatch = true |
|
if model.bloodOxygenAvg > maxAxis { |
|
maxAxis = model.bloodOxygenAvg |
|
} |
|
if model.bloodOxygenAvg < minValue || minValue == 0 { |
|
minValue = model.bloodOxygenAvg |
|
} |
|
totalAvg += model.bloodOxygenAvg |
|
sources.append(ChartViewData(date: nil, value: model.bloodOxygenAvg)) |
|
break |
|
} |
|
} |
|
// 添加空数据 |
|
if !isMatch { |
|
sources.append(ChartViewData(date: nil, value: 0)) |
|
} |
|
} |
|
totalAvg = totalAvg / modelArr.count |
|
chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: nil, source: sources, chartType: .gradentFill, maxAxis: maxAxis, xAxis: xAxis, lineColor: kHexColor(0xD81E20), isContinuous: false, isShowMeasureLine: false, center: String(totalAvg), centerColor: kHexColor(0xD81E20), centerUnit: MultiLanguageKey.bloodOxygenUnit.localized) |
|
chartViewModel.points = sources.count |
|
// 底部数据总和 |
|
formModel = HealthFormModel(oneValue: String(totalAvg), twoValue: String(maxAxis), threeValue: String(minValue), fourValue: "") |
|
case .month: |
|
// 获取一个月时间戳数组 |
|
let selectDate = DateClass.getTimeStrToDate(formatStr: "yyyy-MM-dd", timeStr: tempTimeStr) |
|
let monthSatrtDate = selectDate.startOfCurrentMonth().tranFormDateStr(format: "yyyy-MM-dd") |
|
let monthRange = selectDate.getMonthHowManyDay() |
|
let months = monthRange.map { DateClass.dateStringOffset(from: monthSatrtDate, offset: $0 - 1) } |
|
var sources: [ChartViewData] = [] |
|
var maxAxis = 0 |
|
var totalAvg = 0 |
|
var minValue = 0 |
|
var xAxis: [String] = [] |
|
// 边里匹配对应日期数据数组 |
|
for (offset, dataDate) in months.enumerated() { |
|
// 只展示每周的 |
|
if offset == 0 || offset == months.count - 1 || offset == (months.count / 2) { |
|
let showDate = DateClass.getTimeStrToDate(formatStr: "yyyy-MM-dd", timeStr: dataDate).tranFormDateStr(format: "dd") |
|
xAxis.append(showDate) |
|
} |
|
var isMatch = false |
|
for model in modelArr { |
|
if dataDate == model.dataDate { |
|
isMatch = true |
|
if model.bloodOxygenAvg > maxAxis { |
|
maxAxis = model.bloodOxygenAvg |
|
} |
|
if model.bloodOxygenAvg < minValue || minValue == 0 { |
|
minValue = model.bloodOxygenAvg |
|
} |
|
totalAvg += model.bloodOxygenAvg |
|
sources.append(ChartViewData(date: nil, value: model.bloodOxygenAvg)) |
|
break |
|
} |
|
} |
|
// 添加空数据 |
|
if !isMatch { |
|
sources.append(ChartViewData(date: nil, value: 0)) |
|
} |
|
} |
|
totalAvg = totalAvg / modelArr.count |
|
chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: nil, source: sources, chartType: .gradentFill, maxAxis: maxAxis, xAxis: xAxis, lineColor: kHexColor(0xD81E20), isContinuous: false, isShowMeasureLine: false, center: String(totalAvg), centerColor: kHexColor(0xD81E20), centerUnit: MultiLanguageKey.bloodOxygenUnit.localized) |
|
chartViewModel.points = sources.count |
|
// 底部数据总和 |
|
formModel = HealthFormModel(oneValue: String(totalAvg), twoValue: String(maxAxis), threeValue: String(minValue), fourValue: "") |
|
default: |
|
self.relay.accept(self.defaultVM) |
|
self.formRealy.accept(nil) |
|
return |
|
} |
|
// 更新数据 |
|
self.relay.accept(chartViewModel) |
|
self.formRealy.accept(formModel) |
|
} |
|
} |
|
|
|
// 解析日数据详情 |
|
func getFilterDatas(dateStr: String, details: String) -> [ChartViewData] { |
|
var heartDatas: [Int] = [] |
|
for _ in 0..<144 { |
|
heartDatas.append(0) |
|
} |
|
let startTimeStamp = DateClass.timeStrToTimestamp(dateStr, formatStr: "yyyy-MM-dd") |
|
let detailsArray: [String] = details.components(separatedBy: ",") |
|
var heartRateValues: [Int] = [] |
|
for detail in detailsArray { |
|
let comps = detail.components(separatedBy: "|") |
|
if comps.count == 2 { |
|
let heartRate = (comps[0] as NSString).integerValue |
|
if heartRate > 0 { |
|
heartRateValues.append(heartRate) |
|
} |
|
} |
|
} |
|
// 心率最大值 |
|
let heartRateMax: Int = heartRateValues.max() ?? 0 |
|
var heartMaxIdx: Int = 0 |
|
for detail in detailsArray { |
|
let comps = detail.components(separatedBy: "|") |
|
if comps.count == 2 { |
|
let timeStamp = (comps[1] as NSString).integerValue |
|
let index = (timeStamp - startTimeStamp)/600 |
|
// 记录最大心率的索引 |
|
let heartRateValue = (comps[0] as NSString).integerValue |
|
if heartRateValue == heartRateMax { |
|
heartMaxIdx = index |
|
} |
|
|
|
// 添加下标非0判断,避免崩溃 |
|
if index >= 0 { |
|
if index == heartMaxIdx { |
|
heartDatas[index] = heartRateMax |
|
}else { |
|
heartDatas[index] = (comps[0] as NSString).integerValue |
|
} |
|
} |
|
|
|
} |
|
|
|
} |
|
let chartDatas = heartDatas.map{ data -> ChartViewData in |
|
return ChartViewData(date: "", value: data) |
|
} |
|
return chartDatas |
|
} |
|
|
|
} |
|
|
|
|