// // BloodPressureViewModels.swift // FireBoltt // // Created by Sheldon on 2021/9/22. // Copyright © 2021 Sheldon. All rights reserved. // import UIKit class BloodPressureViewModels: ViewModel { // 图表数据 lazy var relay: BehaviorRelay = { return BehaviorRelay(value: defaultVM) }() // 底部数据 let formRealy = BehaviorRelay(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 DataBaseManagerFireBoltt.shared.fbqueryBloodPressureData(dataDate: tempTimeStr, queryType: tempQueryType) { [weak self] (results) in guard let `self` = self else { return } guard let bpModelArr = results as? [BloodPressureModel], bpModelArr.count > 0 else { self.relay.accept(self.defaultVM) self.formRealy.accept(nil) return } // 拼接数据模型 var chartViewModel: ChartViewModel! var formModel: HealthFormModel? switch tempQueryType { case .day: let bpModel = bpModelArr.first! if bpModel.dbpMin == 0 { self.relay.accept(self.defaultVM) self.formRealy.accept(nil) return } // 测试数据 // bpModel.details = "118|69|1685158772,125|75|1685159372,115|67|1685169372" let sources = self.getFilterDatas(bpModel:bpModel) let maxAxis = sources.map{ $0.value }.max() chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: nil, source: sources, chartType: .polyline, maxAxis: maxAxis, xAxis: ["00:00", "06:00", "12:00", "18:00", "24:00"], lineColor: kHexColor(0xED6565), isContinuous: false, isShowMeasureLine: false) chartViewModel.points = sources.count // 底部数据总和 formModel = HealthFormModel(oneValue: String(bpModel.sbpAvg), twoValue: String(bpModel.dbpAvg), threeValue: String(bpModel.sbpMax), fourValue: String(bpModel.dbpMax)) break case .week: // 获取一周时间戳数组 let weeks = (0...6).map { DateClass.dateStringOffset(from: tempTimeStr, offset: $0) } var sources: [ChartViewData] = [] var maxAxis = 0 var maxSBP = 0 var maxDBP = 0 var totalAvgDBP = 0 var totalAvgSBP = 0 var xAxis: [String] = [] // 过滤无效数据 let sortBpModelArr = bpModelArr.filter { $0.dbpMin != 0 } // 边里匹配对应日期数据数组 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 bpModel in bpModelArr { if dataDate == bpModel.dataDate { isMatch = true if bpModel.sbpAvg > maxAxis { maxAxis = bpModel.sbpAvg } if bpModel.sbpMax > maxSBP { maxSBP = bpModel.sbpMax } if bpModel.dbpMax > maxDBP { maxDBP = bpModel.dbpMax } totalAvgDBP += bpModel.dbpAvg totalAvgSBP += bpModel.sbpAvg sources.append(ChartViewData(date: nil, value: bpModel.sbpAvg, value2: bpModel.dbpAvg)) break } } // 添加空数据 if !isMatch { sources.append(ChartViewData(date: nil, value: 0, value2: 0)) } } totalAvgDBP = totalAvgDBP / sortBpModelArr.count totalAvgSBP = totalAvgSBP / sortBpModelArr.count chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: nil, source: sources, chartType: .polyline, maxAxis: maxAxis, xAxis: xAxis, lineColor: kHexColor(0xED6565), isContinuous: false, isShowMeasureLine: false) chartViewModel.points = sources.count // 底部数据总和 formModel = HealthFormModel(oneValue: String(totalAvgSBP), twoValue: String(totalAvgDBP), threeValue: String(maxSBP), fourValue: String(maxDBP)) break 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 maxSBP = 0 var maxDBP = 0 var totalAvgDBP = 0 var totalAvgSBP = 0 var xAxis: [String] = [] // 过滤无效数据 let sortBpModelArr = bpModelArr.filter { $0.dbpMin != 0 } // 边里匹配对应日期数据数组 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 bpModel in bpModelArr { if dataDate == bpModel.dataDate { isMatch = true if bpModel.sbpAvg > maxAxis { maxAxis = bpModel.sbpAvg } if bpModel.sbpMax > maxSBP { maxSBP = bpModel.sbpMax } if bpModel.dbpMax > maxDBP { maxDBP = bpModel.dbpMax } totalAvgDBP += bpModel.dbpAvg totalAvgSBP += bpModel.sbpAvg sources.append(ChartViewData(date: nil, value: bpModel.sbpAvg, value2: bpModel.dbpAvg)) break } } // 添加空数据 if !isMatch { sources.append(ChartViewData(date: nil, value: 0, value2: 0)) } } totalAvgDBP = totalAvgDBP / sortBpModelArr.count totalAvgSBP = totalAvgSBP / sortBpModelArr.count chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: nil, source: sources, chartType: .polyline, maxAxis: maxAxis, xAxis: xAxis, lineColor: kHexColor(0xED6565), isContinuous: false, isShowMeasureLine: false) chartViewModel.points = sources.count // 底部数据总和 formModel = HealthFormModel(oneValue: String(totalAvgSBP), twoValue: String(totalAvgDBP), threeValue: String(maxSBP), fourValue: String(maxDBP)) break default: self.relay.accept(self.defaultVM) self.formRealy.accept(nil) return } // 更新数据 self.relay.accept(chartViewModel) self.formRealy.accept(formModel) } } // 解析日数据详情 func getFilterDatas(bpModel:BloodPressureModel) -> [ChartViewData] { var bpsArr: [String] = [] for _ in 0..<144 { bpsArr.append("0|0") } // 血压详情 144条 (SBP|DBP,...) let bps: [String] = bpModel.details.components(separatedBy: ",").map { $0 } let startTimeStamp = DateClass.timeStrToTimestamp(bpModel.dataDate, formatStr: "yyyy-MM-dd") for detail in bps { let comps = detail.components(separatedBy: "|") if comps.count == 3 { let timeStamp = (comps[2] as NSString).integerValue let index = (timeStamp - startTimeStamp)/600 // 添加下标非0判断,避免崩溃 if index >= 0 { bpsArr[index] = comps[0] + "|" + comps[1] } } } let chartDatas = bpsArr.map{ data -> ChartViewData in let comps = data.components(separatedBy: "|") return ChartViewData(date: nil, value: comps[0].integerValue, value2: comps[1].integerValue) } return chartDatas } }