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.

225 lines
13 KiB

2 years ago
//
// SleepViewModels.swift
2 years ago
// HPlusFit
//
// Created by lemo. on 2019/10/6.
// Copyright © 2019 lemo. All rights reserved.
//
import UIKit
fileprivate struct Metric {
static let legends = [
LegendData(docColor: kHexColor(0xF6BF47), name: MultiLanguageKey_FB.awakeFB.localized),
LegendData(docColor: kHexColor(0xA4A3FF), name: MultiLanguageKey_FB.shallowSleepFB.localized),
LegendData(docColor: kHexColor(0x6E63FF), name: MultiLanguageKey_FB.deepSleepFB.localized)
2 years ago
]
}
class SleepViewModels: 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: [], source: [], chartType: .horizontalSegment, maxAxis: 12, xAxis: [], lineColor: kHexColor(0x6161ED), isShowMeasureLine: false, center: nil, centerColor: kHexColor(0xEEA82C), centerUnit: nil)
return chartViewModel
}()
/// ()
private var currenTimeStr = DateClass.getCurrentTimeStr(formatStr: "yyyy-MM-dd")
private var queryType: DataQueryType = .day
override init() {
super.init()
//
fbloadSleepData(timeStr: currenTimeStr, queryType: queryType)
2 years ago
}
///
func fbloadSleepData(timeStr: String?, queryType: DataQueryType?) {
2 years ago
//
let tempQueryType = queryType == nil ? self.queryType : queryType!
self.queryType = tempQueryType
//
let tempTimeStr = timeStr == nil ? currenTimeStr : timeStr!
currenTimeStr = tempTimeStr
DataBaseManagerFireBoltt.shared.fbquerySleepModel(dataDate: tempTimeStr, queryType: tempQueryType) { [weak self] (results) in
2 years ago
guard let `self` = self else { return }
guard let sleepModelArr = results as? [SleepModel], sleepModelArr.count > 0 else {
self.relay.accept(self.defaultVM)
self.formRealy.accept(nil)
return
}
//
var chartViewModel: ChartViewModel!
var formModel: HealthFormModel?
switch tempQueryType {
case .day:
let sleepModel = sleepModelArr.first!
if sleepModel.totalSleepDuration == 0 {
self.relay.accept(self.defaultVM)
self.formRealy.accept(nil)
return
}
let source: [ChartViewData] = self.processSleepDetails(model: sleepModel)
chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: Metric.legends, source: source, chartType: .horizontalSegment, maxAxis: 12, xAxis: ["21:00", "00:00", "03:00", "06:00", "09:00"], lineColor: kHexColor(0x6161ED), isShowMeasureLine: false, center: String(format: "%02d:%02d", sleepModel.totalSleepDuration / 60, sleepModel.totalSleepDuration % 60), centerColor: kHexColor(0x5447F6), centerUnit: MultiLanguageKey_FB.hourFB.localized)
2 years ago
//
// formModel = HealthFormModel(oneValue: String(format: "%02d:%02d", sleepModel.deepSleepDuration / 60, sleepModel.deepSleepDuration % 60), twoValue: String(format: "%02d:%02d", sleepModel.lightSleepDuration / 60, sleepModel.lightSleepDuration % 60), threeValue: String(format: "%02d:%02d", sleepModel.totalSleepDuration / 60, sleepModel.totalSleepDuration % 60), fourValue: String(sleepModel.awakeNumber))
formModel = HealthFormModel(oneValue: String(format: "%02d:%02d", sleepModel.deepSleepDuration / 60, sleepModel.deepSleepDuration % 60), twoValue: String(format: "%02d:%02d", sleepModel.lightSleepDuration / 60, sleepModel.lightSleepDuration % 60), threeValue: String(format: "%02d:%02d", sleepModel.totalSleepDuration / 60, sleepModel.totalSleepDuration % 60), fourValue: String(sleepModel.awakeDuration%60))
case .week:
//
let weeks = (0...6).map { DateClass.dateStringOffset(from: tempTimeStr, offset: $0) }
var sources: [ChartViewData] = []
var maxAxis = 0
var totalDeepSleep = 0
var totalShallowSleep = 0
var totalAwakeSleep = 0
var totalSleep = 0
var totalAwakeNumber = 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 sleepModel in sleepModelArr {
if dataDate == sleepModel.dataDate && sleepModel.totalSleepDuration > 0 {
isMatch = true
if sleepModel.totalSleepDuration > maxAxis {
maxAxis = sleepModel.totalSleepDuration
}
totalDeepSleep += sleepModel.deepSleepDuration
totalShallowSleep += sleepModel.lightSleepDuration
totalAwakeSleep += sleepModel.awakeDuration
totalSleep += sleepModel.totalSleepDuration
totalAwakeNumber += sleepModel.awakeNumber
sources.append(ChartViewData(date: "", number: 0, sum: Float(sleepModel.totalSleepDuration) / 60.0, sleeps: [
sleepData(type: 2, value: Float(sleepModel.deepSleepDuration) / 60.0),
sleepData(type: 0, value: Float(sleepModel.awakeDuration) / 60.0),
sleepData(type: 1, value: Float(sleepModel.lightSleepDuration) / 60.0)
], fallingsleepTimes: "", awakeTimes: ""))
}
//
if !isMatch {
sources.append(ChartViewData(date: "", number: 0, sum: 0.0, sleeps: [
sleepData(type: 2, value: 0.0),
sleepData(type: 0, value: 0.0),
sleepData(type: 1, value: 0.0)
], fallingsleepTimes: "", awakeTimes: ""))
}
}
}
chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: Metric.legends, source:sources, chartType: .segmentBar, maxAxis: maxAxis / 60 + 2, xAxis: xAxis, lineColor: kHexColor(0xEEA82C), center: String(format: "%02d:%02d", totalSleep / 60, totalSleep % 60), centerColor: kHexColor(0x5447F6), centerUnit: "")
chartViewModel.points = sources.count
//
formModel = HealthFormModel(oneValue: String(format: "%02d:%02d", totalDeepSleep / 60, totalDeepSleep % 60), twoValue: String(format: "%02d:%02d", totalShallowSleep / 60, totalShallowSleep % 60), threeValue: String(format: "%02d:%02d", totalSleep / 60, totalSleep % 60), fourValue: String(format: "%02d:%02d", totalAwakeSleep / 60, totalAwakeSleep % 60))
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 totalDeepSleep = 0
var totalShallowSleep = 0
var totalAwakeSleep = 0
var totalSleep = 0
var totalAwakeNumber = 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 sleepModel in sleepModelArr {
let totalSleepTime = sleepModel.totalSleepDuration
if dataDate == sleepModel.dataDate && totalSleepTime > 0 {
isMatch = true
if totalSleepTime > maxAxis {
maxAxis = totalSleepTime
}
totalDeepSleep += sleepModel.deepSleepDuration
totalShallowSleep += sleepModel.lightSleepDuration
totalAwakeSleep += sleepModel.awakeDuration
totalSleep += sleepModel.totalSleepDuration
totalAwakeNumber += sleepModel.awakeNumber
sources.append(ChartViewData(date: "", number: 0, sum: Float(sleepModel.totalSleepDuration) / 60.0, sleeps: [
sleepData(type: 2, value: Float(sleepModel.deepSleepDuration) / 60.0),
sleepData(type: 0, value: Float(sleepModel.awakeDuration) / 60.0),
sleepData(type: 1, value: Float(sleepModel.lightSleepDuration) / 60.0)
], fallingsleepTimes: "", awakeTimes: ""))
}
//
if !isMatch {
sources.append(ChartViewData(date: nil, number: 0, sum: 0.0, sleeps: [
sleepData(type: 2, value: 0.0),
sleepData(type: 0, value: 0.0),
sleepData(type: 1, value: 0.0)
], fallingsleepTimes: "", awakeTimes: ""))
}
}
}
chartViewModel = ChartViewModel(leftIcon: nil, title: nil, legends: Metric.legends, source:sources, chartType: .rectangleSegBar, maxAxis: maxAxis / 60 + 2, xAxis: xAxis, lineColor: kHexColor(0xEEA82C), center: String(format: "%02d:%02d", totalSleep / 60, totalSleep % 60), centerColor: kHexColor(0x5447F6), centerUnit: "")
chartViewModel.points = sources.count
//
formModel = HealthFormModel(oneValue: String(format: "%02d:%02d", totalDeepSleep / 60, totalDeepSleep % 60), twoValue: String(format: "%02d:%02d", totalShallowSleep / 60, totalShallowSleep % 60), threeValue: String(format: "%02d:%02d", totalSleep / 60, totalSleep % 60), fourValue: String(format: "%02d:%02d", totalAwakeSleep / 60, totalAwakeSleep % 60))
default:
self.relay.accept(self.defaultVM)
self.formRealy.accept(nil)
return
}
//
self.relay.accept(chartViewModel)
self.formRealy.accept(formModel)
}
}
}
extension SleepViewModels {
2 years ago
///
///
/// - Parameter sleepDetails:
/// - Returns:
private func processSleepDetails(model: SleepModel) -> [ChartViewData] {
var chartViewArray: [ChartViewData] = []
let detailsArr: [String] = model.sleepDetails.components(separatedBy: ",")
for detail in detailsArr {
let comps = detail.components(separatedBy: "|")
// (|||,..)
if comps.count == 4 {
// ()
let type = (comps.first! as NSString).integerValue
//
let startTime = DateClass.timestampToStr(comps[1].integerValue, formatStr: "HH:mm")
//
let duration = comps[2].integerValue
//
let endTime = DateClass.timestampToStr(comps[3].integerValue, formatStr: "HH:mm")
//
let chartData = ChartViewData(sleep: sleepData(type: type, value: Float(duration) / 60.0, begin: startTime, end: endTime))
chartViewArray.append(chartData)
}
}
return chartViewArray
}
private func minToStr(min: Int) -> String {
return String(format: "%02d:%02d", min / 60, min % 60)
}
}