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
![]()
2 years ago
|
//
|
||
![]()
2 years ago
|
// HRViewModels.swift
|
||
![]()
2 years ago
|
// HPlusFit
|
||
|
//
|
||
|
// Created by lemo. on 2019/10/5.
|
||
|
// Copyright © 2019 lemo. All rights reserved.
|
||
|
//
|
||
|
|
||
|
import UIKit
|
||
|
|
||
![]()
2 years ago
|
class HRViewModels: ViewModel {
|
||
![]()
2 years ago
|
|
||
|
// 图表数据
|
||
|
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()
|
||
|
// 默认加载当天
|
||
|
loadHrData(timeStr: currenTimeStr, queryType: queryType)
|
||
|
}
|
||
|
|
||
|
// 加载心率数据
|
||
|
func loadHrData(timeStr: String?, queryType: DataQueryType?) {
|
||
|
// 无查询类型默认为上一次查询类型
|
||
|
let tempQueryType = queryType == nil ? self.queryType : queryType!
|
||
|
self.queryType = tempQueryType
|
||
|
// 查询时间戳
|
||
|
let tempTimeStr = timeStr == nil ? currenTimeStr : timeStr!
|
||
|
currenTimeStr = tempTimeStr
|
||
![]()
1 year ago
|
DataBaseManagerFireBoltt.shared.fbqueryHeartRateData(dataDate: tempTimeStr, queryType: tempQueryType) { [weak self] (results) in
|
||
![]()
2 years ago
|
guard let `self` = self else { return }
|
||
|
guard let hrModelArr = results as? [HeartRateModel], hrModelArr.count > 0 else {
|
||
|
self.relay.accept(self.defaultVM)
|
||
|
self.formRealy.accept(nil)
|
||
|
return
|
||
|
}
|
||
|
// 拼接数据模型
|
||
|
var chartViewModel: ChartViewModel!
|
||
|
var formModel: HealthFormModel?
|
||
|
switch tempQueryType {
|
||
|
case .day:
|
||
|
let hrModel = hrModelArr.first!
|
||
|
if hrModel.heartAvg == 0 {
|
||
|
self.relay.accept(self.defaultVM)
|
||
|
self.formRealy.accept(nil)
|
||
|
return
|
||
|
}
|
||
|
let sources = self.getFilterDatas(dateStr: hrModel.dataDate, details: hrModel.heartDetails)
|
||
|
let maxAxis = sources.map{ $0.value }.max()
|
||
![]()
1 year ago
|
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(0xED8A65), isContinuous: false, isShowMeasureLine: false, center: String(hrModel.heartAvg), centerColor: kHexColor(0xED8A65), centerUnit: MultiLanguageKey_FB.hrUnitFB.localized)
|
||
![]()
2 years ago
|
// 底部数据总和
|
||
|
formModel = HealthFormModel(oneValue: String(hrModel.heartAvg), twoValue: String(hrModel.heartMax), threeValue: String(hrModel.heartMin), fourValue: "")
|
||
|
break
|
||
|
case .week:
|
||
|
// 获取一周时间戳数组
|
||
|
let weeks = (0...6).map { DateClass.dateStringOffset(from: tempTimeStr, offset: $0) }
|
||
|
var sources: [ChartViewData] = []
|
||
|
var maxAxis = 0
|
||
|
var totalAvgHr = 0
|
||
|
var minHr = 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 hrModel in hrModelArr {
|
||
|
if dataDate == hrModel.dataDate {
|
||
|
isMatch = true
|
||
|
if hrModel.heartAvg > maxAxis {
|
||
|
maxAxis = hrModel.heartAvg
|
||
|
}
|
||
|
if hrModel.heartAvg < minHr || minHr == 0 {
|
||
|
minHr = hrModel.heartAvg
|
||
|
}
|
||
|
totalAvgHr += hrModel.heartAvg
|
||
|
sources.append(ChartViewData(date: nil, value: hrModel.heartAvg))
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
// 添加空数据
|
||
|
if !isMatch {
|
||
|
sources.append(ChartViewData(date: nil, value: 0))
|
||
|
}
|
||
|
}
|
||
|
totalAvgHr = totalAvgHr / hrModelArr.count
|
||
![]()
1 year ago
|
chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: nil, source: sources, chartType: .gradentFill, maxAxis: maxAxis, xAxis: xAxis, lineColor: kHexColor(0xED8A65), isContinuous: false, isShowMeasureLine: false, center: String(totalAvgHr), centerColor: kHexColor(0xED8A65), centerUnit: MultiLanguageKey_FB.hrUnitFB.localized)
|
||
![]()
2 years ago
|
chartViewModel.points = sources.count
|
||
|
// 底部数据总和
|
||
|
formModel = HealthFormModel(oneValue: String(totalAvgHr), twoValue: String(maxAxis), threeValue: String(minHr), 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 totalAvgHr = 0
|
||
|
var minHr = 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 hrModel in hrModelArr {
|
||
|
if dataDate == hrModel.dataDate {
|
||
|
isMatch = true
|
||
|
if hrModel.heartAvg > maxAxis {
|
||
|
maxAxis = hrModel.heartAvg
|
||
|
}
|
||
|
if hrModel.heartAvg < minHr || minHr == 0 {
|
||
|
minHr = hrModel.heartAvg
|
||
|
}
|
||
|
totalAvgHr += hrModel.heartAvg
|
||
|
sources.append(ChartViewData(date: nil, value: hrModel.heartAvg))
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
// 添加空数据
|
||
|
if !isMatch {
|
||
|
sources.append(ChartViewData(date: nil, value: 0))
|
||
|
}
|
||
|
}
|
||
|
totalAvgHr = totalAvgHr / hrModelArr.count
|
||
![]()
1 year ago
|
chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: nil, source: sources, chartType: .gradentFill, maxAxis: maxAxis, xAxis: xAxis, lineColor: kHexColor(0xED8A65), isContinuous: false, isShowMeasureLine: false, center: String(totalAvgHr), centerColor: kHexColor(0xED8A65), centerUnit: MultiLanguageKey_FB.hrUnitFB.localized)
|
||
![]()
2 years ago
|
chartViewModel.points = sources.count
|
||
|
// 底部数据总和
|
||
|
formModel = HealthFormModel(oneValue: String(totalAvgHr), twoValue: String(maxAxis), threeValue: String(minHr), 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
|
||
|
}
|
||
|
|
||
|
}
|