BOReportCell.swift 7.1 KB
//
//  BOReportCell.swift
//  Twear
//
//  Created by yangbin on 2022/1/1.
//

import UIKit
import Charts
import SwiftDate

class BOReportCell: UICollectionViewCell {
    
    @IBOutlet weak var lineChartView: LineChartView!
    @IBOutlet weak var minBOLabel: UILabel!
    @IBOutlet weak var maxBOLabel: UILabel!
    @IBOutlet weak var avgBOLabel: UILabel!
    @IBOutlet weak var dateLabel: UILabel!
    
    var dateType: DateType = .day {
        didSet {
            updateChartView()
        }
    }
    
    lazy private var monthDays = DateInRegion().monthDays
    var boArray: [BloodOxygenModel] = []
    
    private func updateChartView() {
        setupChartView()
        let nowDate = DateInRegion().date
        var boResult: (boArray: [BloodOxygenModel], minBo: [Int], maxBo: [Int]) = ([], [], [])
        switch dateType {
        case .day:
            boResult = BloodOxygenModel.getBloodOxygenByDay(nowDate)
            dateLabel.text = nowDate.dateAt(.startOfDay).toString(.custom("yyyy.MM.dd"))
        case .week:
            boResult = BloodOxygenModel.getBloodOxygenByWeek(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:
            boResult = BloodOxygenModel.getBloodOxygenByMonth(nowDate)
            dateLabel.text = nowDate.toString(.custom("yyyy.MM"))
        case .year:
            boResult = BloodOxygenModel.getBloodOxygenByYear(nowDate)
            dateLabel.text = "\(nowDate.year).01-\(nowDate.year).12"
        }
        boArray = boResult.boArray
        if boArray.count == 0 {
            resetLabel()
        } else {
            updateLabel(max: boResult.maxBo.max() ?? 0, min:  boResult.minBo.min() ?? 0, avg: boArray.average(\.value))
        }

        var dataEntries = [ChartDataEntry]()
        for bo in boArray {
            if bo.value > 0 {
                var pointX: Double = 0
                switch dateType {
                case .day:
                    pointX = Double(bo.date!.hour)+Double(bo.date!.minute)/60.0
                case .week:
                    pointX = Double(bo.date!.weekIndex)
                case .month:
                    pointX = Double(bo.date!.day-1)
                case .year:
                    pointX = Double(bo.date!.month-1)
                }
                dataEntries.append(ChartDataEntry(x: pointX, y: Double(bo.value)))
            }
        }
        
        
        if dataEntries.count == 1 {
            dataEntries.append(ChartDataEntry(x: dataEntries[0].x+0.2, y: dataEntries[0].y))
        }
        
        let dataSet = LineChartDataSet(entries: dataEntries)
        dataSet.drawCirclesEnabled = false
        dataSet.drawValuesEnabled = false
        dataSet.highlightEnabled = false//选中拐点,是否开启高亮效果(显示十字线)
        dataSet.highlightLineWidth = 1
        dataSet.highlightColor = UIColor.rgbColorFromHex(0xFF3600)// 十字线颜色
        dataSet.drawHorizontalHighlightIndicatorEnabled = false
        dataSet.mode = .horizontalBezier
        dataSet.setColor(UIColor.rgbColorFromHex(0xFF3600))
        dataSet.lineWidth = 1
        
        
        dataSet.drawFilledEnabled = true //填充绘制
        let gradientColors = [UIColor.rgbColorFromHex(0xD82D00).cgColor, UIColor.rgbColorFromHex(0xFFFFFF).cgColor]
        let gradient = CGGradient(colorsSpace: nil, colors: gradientColors as CFArray, locations: [1.0, 0.0])
        dataSet.fillAlpha = 1
        dataSet.fill = Fill(linearGradient: gradient!, angle: 90)
        lineChartView.data = LineChartData(dataSets: [dataSet])

    }
    
    
    private func setupChartView() {
        
        lineChartView.chartDescription?.enabled = false //图描述
        lineChartView.legend.enabled = false //左下角图例
        lineChartView.setScaleEnabled(false) //可滑动
        lineChartView.rightAxis.enabled = false //不绘制右边轴的信息
        
        let leftAxis = lineChartView.leftAxis
        leftAxis.labelTextColor = ChartsTextColor
        leftAxis.labelFont = ChartsTextFont(11)
        leftAxis.yOffset = -5
        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 = 90 //设置左侧Y轴最小值
        leftAxis.axisMaximum = 100
        leftAxis.granularity = 2
        
        let litmitLine = ChartLimitLine(limit: 0, label: "")
        litmitLine.lineWidth = 1
        litmitLine.lineColor = LineColor
        leftAxis.addLimitLine(litmitLine)
        leftAxis.drawLimitLinesBehindDataEnabled = false  //设置限制线绘制在折线图的后面
        
        
        let xAxis = lineChartView.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
            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 updateLabel(max: Int, min: Int, avg: Int) {
        maxBOLabel.toUnitMode(text: "\(max)", unit: " %", font: BoldFont(25), unitFont: RegularFont(15))
        avgBOLabel.toUnitMode(text: "\(avg)", unit: " %", font: BoldFont(25), unitFont: RegularFont(15))
        minBOLabel.toUnitMode(text: "\(min)", unit: " %", font: BoldFont(25), unitFont: RegularFont(15))
    }
    
    private func resetLabel() {
        maxBOLabel.toUnitMode(text: "--", unit: " %", font: BoldFont(25), unitFont: RegularFont(15))
        minBOLabel.toUnitMode(text: "--", unit: " %", font: BoldFont(25), unitFont: RegularFont(15))
        avgBOLabel.toUnitMode(text: "--", unit: " %", font: BoldFont(25), unitFont: RegularFont(15))
    }
    

    

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

}