// // SleepReportCell.swift // Twear // // Created by yangbin on 2022/1/1. // import UIKit import Charts import SwiftDate class SleepReportCell: UICollectionViewCell { @IBOutlet weak var barChartView: BarChartView! @IBOutlet weak var deepLabel: UILabel! @IBOutlet weak var lightLabel: UILabel! @IBOutlet weak var awakeLabel: UILabel! @IBOutlet weak var lengthLabel: UILabel! @IBOutlet weak var dateLabel: UILabel! lazy private var monthDays = DateInRegion().monthDays private var sleepArray: [SleepModel] = [] private var sleepSummaryArray: [SleepSummary] = [] private var barWidth: Double = 1.0/60.0 var dateType: DateType = .day { didSet { updateChartView() } } private func updateChartView() { setupChartView() let nowDate = DateInRegion().date switch dateType { case .day: sleepArray = SleepModel.getSleepByDay(nowDate) dateLabel.text = nowDate.dateAt(.startOfDay).toString(.custom("yyyy.MM.dd")) case .week: sleepSummaryArray = SleepModel.getSleepByWeek(nowDate) dateLabel.text = ((nowDate-1.days).dateAt(.startOfWeek)+1.days).toString(.custom("MM.dd")) + "-" + ((nowDate-1.days).dateAt(.endOfWeek)+1.days).toString(.custom("MM.dd")) case .month: sleepSummaryArray = SleepModel.getSleepByMonth(nowDate) dateLabel.text = nowDate.toString(.custom("yyyy.MM")) case .year: sleepSummaryArray = SleepModel.getSleepByYear(nowDate) dateLabel.text = "\(nowDate.year).01-\(nowDate.year).12" } // let startDate = nowDate.dateAtStartOf(.day) // sleepArray = [SleepModel(type: .light, startDate: startDate+10.minutes, endDate: startDate+30.minutes), SleepModel(type: .awake, startDate: startDate+30.minutes, endDate: startDate+100.minutes), SleepModel(type: .light, startDate: startDate+100.minutes, endDate: startDate+160.minutes), SleepModel(type: .deep, startDate: startDate+160.minutes, endDate: startDate+500.minutes), SleepModel(type: .awake, startDate: startDate+500.minutes, endDate: startDate+540.minutes)] if dateType == .day { if sleepArray.count == 0 { resetLabel() } else { let sleep = SleepModel.querySleepPercentage(sleepArray) updateLable(length: sleep.length, awake: sleep.awake_pct, deep: sleep.deep_pct, light: sleep.light_pct) } } else { if sleepSummaryArray.count == 0 { resetLabel() } else { updateLable(length: sleepSummaryArray.average(\.sleepLength), awake: sleepSummaryArray.average(\.awake_pct), deep: sleepSummaryArray.average(\.deep_pct), light: sleepSummaryArray.average(\.light_pct)) } } if dateType == .day { barChartView.leftAxis.valueFormatter = IndexAxisValueFormatter(values: [LocString("清醒"), LocString("浅睡"), LocString("深睡")]) barChartView.leftAxis.yOffset = -30 barChartView.leftAxis.axisMaximum = 3 var awakeEntries = [BarChartDataEntry]() var deepEntries = [BarChartDataEntry]() var lightEntries = [BarChartDataEntry]() // var emptyEntries = [BarChartDataEntry]() let xAxis = barChartView.xAxis var startPoint: Double = 0 // var sleepXValues: [String] = [] if let startDate = sleepArray.first?.startDate, let endDate = sleepArray.last?.endDate { startPoint = Double(startDate.hour) + Double(startDate.minute)/60.0 if startPoint > 20 { startPoint = startPoint - 24 } var endPoint = Double(endDate.hour) + Double(endDate.minute)/60.0 if endPoint > 20 { endPoint = endPoint - 24 } xAxis.labelCount = 2 xAxis.axisMinimum = -0.8012345 xAxis.axisMaximum = (endPoint - startPoint) + 0.5 xAxis.valueFormatter = CDTimeAxisValueFormatter(min: -0.8012345, max: (endPoint - startPoint) + 0.5, labelCount: 2, values: [startDate.toString(.custom("HH:mm")), endDate.toString(.custom("HH:mm"))]) } else { xAxis.labelCount = 2 xAxis.axisMinimum = -0.8012345 xAxis.axisMaximum = 11.5 xAxis.valueFormatter = CDTimeAxisValueFormatter(min: -0.8012345, max: 11.5, labelCount: 2, values: ["22:00", "09:00"]) } for sleep in sleepArray { var startX = Double(sleep.startDate!.hour) + Double(sleep.startDate!.minute)/60.0 if startX > 20 { startX = startX - 24 } startX = startX - startPoint // let startX = Double(sleep.startDate!.hour) + Double(sleep.startDate!.minute)/60.0 for n in 0.. 0 { var pointX: Double = 0 switch dateType { case .day: break case .week: barWidth = 0.25 pointX = Double(sleep.endDate!.weekIndex) case .month: pointX = Double(sleep.endDate!.day-1) case .year: barWidth = 0.4 pointX = Double(sleep.endDate!.month-1) } dataEntries.append(BarChartDataEntry(x: pointX, y: Double(sleep.light+sleep.deep)/60)) } } let dataSet = BarChartDataSet(entries: dataEntries) dataSet.colors = [UIColor.rgbColorFromHex(0x9733ED)] dataSet.highlightEnabled = false dataSet.highlightColor = UIColor.rgbColorFromHex(0x9B0AFB) dataSet.drawValuesEnabled = false let chartData = BarChartData(dataSets: [dataSet]) chartData.barWidth = barWidth barChartView.data = chartData } } private func setupChartView() { barChartView.chartDescription?.enabled = false //图描述 barChartView.legend.enabled = false //左下角图例 barChartView.setScaleEnabled(false) //可滑动 barChartView.rightAxis.enabled = false //不绘制右边轴的信息 let leftAxis = barChartView.leftAxis leftAxis.labelTextColor = ChartsTextColor leftAxis.labelFont = ChartsTextFont(11) leftAxis.xOffset = -3 leftAxis.gridLineDashLengths = [2.0, 2.0] //设置虚线样式的网格线 leftAxis.gridColor = LineColor leftAxis.gridLineWidth = 1 leftAxis.axisLineWidth = 0 leftAxis.drawGridLinesBehindDataEnabled = false leftAxis.labelPosition = .insideChart leftAxis.axisMinimum = 0 //设置左侧Y轴最小值 leftAxis.granularity = 1 let litmitLine = ChartLimitLine(limit: 0, label: "") litmitLine.lineWidth = 1 litmitLine.lineColor = LineColor leftAxis.addLimitLine(litmitLine) leftAxis.drawLimitLinesBehindDataEnabled = false //设置限制线绘制在折线图的后面 let xAxis = barChartView.xAxis xAxis.granularity = 1 //间隔 xAxis.labelPosition = .bottom xAxis.labelFont = ChartsTextFont(11) xAxis.labelTextColor = ChartsTextColor xAxis.drawGridLinesBehindDataEnabled = false xAxis.axisLineColor = LineColor xAxis.axisLineWidth = 1 xAxis.gridLineDashLengths = [6, 666] xAxis.gridColor = LineColor xAxis.drawAxisLineEnabled = false switch dateType { case .day: xAxis.valueFormatter = IndexAxisValueFormatter(values: DayXValues) xAxis.labelCount = 9 // if sleepArray.count > 0 { xAxis.axisMinimum = -0.8 xAxis.axisMaximum = 9.5 // } else { // xAxis.axisMinimum = -2.9 // xAxis.axisMaximum = 24 + 2 // } case .week: xAxis.valueFormatter = IndexAxisValueFormatter(values: WeekXValues) xAxis.labelCount = 7 xAxis.axisMinimum = -0.8 xAxis.axisMaximum = 6 + 0.8 case .month: xAxis.valueFormatter = IndexAxisValueFormatter(values: MonthXValues(monthDays)) xAxis.labelCount = 8 xAxis.axisMinimum = -3.5 xAxis.axisMinLabels = 8 xAxis.axisMaximum = Double(monthDays-1) + 2.1 case .year: xAxis.valueFormatter = IndexAxisValueFormatter(values: MonthValues) xAxis.labelCount = 12 xAxis.axisMinimum = -1.3 xAxis.axisMaximum = 11 + 0.8 } } private func resetLabel() { lengthLabel.toTimeType2(length: -1, 25, 15) deepLabel.toUnitMode(text: "--", unit: "%", font: BoldFont(25), unitFont: RegularFont(15)) awakeLabel.toUnitMode(text: "--", unit: "%", font: BoldFont(25), unitFont: RegularFont(15)) lightLabel.toUnitMode(text: "--", unit: "%", font: BoldFont(25), unitFont: RegularFont(15)) } private func updateLable(length: Int, awake: Int, deep: Int, light: Int) { lengthLabel.toTimeType2(length: length, 25, 15) deepLabel.toUnitMode(text: "\(deep)", unit: "%", font: BoldFont(25), unitFont: RegularFont(15)) awakeLabel.toUnitMode(text: "\(awake)", unit: "%", font: BoldFont(25), unitFont: RegularFont(15)) lightLabel.toUnitMode(text: "\(light)", unit: "%", font: BoldFont(25), unitFont: RegularFont(15)) } override func awakeFromNib() { super.awakeFromNib() // Initialization code } }