BPReportCell.swift 7.56 KB
//
//  BPReportCell.swift
//  Twear
//
//  Created by yangbin on 2022/1/1.
//

import UIKit
import Charts
import SwiftDate

class BPReportCell: UICollectionViewCell {
    
    @IBOutlet weak var lineChartView: LineChartView!
    @IBOutlet weak var dbpLabel: UILabel!
    @IBOutlet weak var sbpLabel: UILabel!
    @IBOutlet weak var dateLabel: UILabel!
    
    var dateType: DateType = .day {
        didSet {
            updateChartView()
        }
    }
    lazy private var monthDays = DateInRegion().monthDays
    var bpArray: [BloodPressureModel] = []
    
    
    private func updateChartView() {
        setupChartView()
        let nowDate = DateInRegion().date

        switch dateType {
        case .day:
            bpArray = BloodPressureModel.getBloodPressureByDay(nowDate)
            dateLabel.text = nowDate.dateAt(.startOfDay).toString(.custom("yyyy.MM.dd"))
        case .week:
            bpArray = BloodPressureModel.getBloodPressureByWeek(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:
            bpArray = BloodPressureModel.getBloodPressureByMonth(nowDate)
            dateLabel.text = nowDate.toString(.custom("yyyy.MM"))
        case .year:
            bpArray = BloodPressureModel.getBloodPressureByYear(nowDate)
            dateLabel.text = "\(nowDate.year).01-\(nowDate.year).12"
        }
        
        if bpArray.count == 0 {
            resetLabel()
        } else {
            updateLabel(sbp: bpArray.average(\.sbp), dbp: bpArray.average(\.dbp))
        }
        if let maxSbp = bpArray.max(\.sbp)?.sbp {
            lineChartView.leftAxis.axisMaximum = Double(max(140, maxSbp))
        }
        

        var sbpDataEntries = [ChartDataEntry]()
        var dbpDataEntries = [ChartDataEntry]()
        for bp in bpArray {
            if bp.sbp > 0 {
                var pointX: Double = 0
                switch dateType {
                case .day:
                    pointX = Double(bp.date!.hour)+Double(bp.date!.minute)/60.0
                case .week:
                    pointX = Double(bp.date!.weekIndex)
                case .month:
                    pointX = Double(bp.date!.day-1)
                case .year:
                    pointX = Double(bp.date!.month-1)
                }
                sbpDataEntries.append(ChartDataEntry(x: pointX, y: Double(bp.sbp)))
                dbpDataEntries.append(ChartDataEntry(x: pointX, y: Double(bp.dbp)))
            }
        }

        
        let sbpDataSet = LineChartDataSet(entries: sbpDataEntries)
        sbpDataSet.drawValuesEnabled = false
        sbpDataSet.highlightEnabled = false//选中拐点,是否开启高亮效果(显示十字线)
        sbpDataSet.highlightLineWidth = 1
        sbpDataSet.highlightColor = UIColor.rgbColorFromHex(0xFFD200)// 十字线颜色
        sbpDataSet.drawHorizontalHighlightIndicatorEnabled = false
        sbpDataSet.mode = .horizontalBezier
        sbpDataSet.setColor(UIColor.rgbColorFromHex(0xFFD200))
        sbpDataSet.lineWidth = 1
        
        let dbpDataSet = LineChartDataSet(entries: dbpDataEntries)
        dbpDataSet.drawValuesEnabled = false
        dbpDataSet.highlightEnabled = false//选中拐点,是否开启高亮效果(显示十字线)
        dbpDataSet.mode = .horizontalBezier
        dbpDataSet.setColor(UIColor.rgbColorFromHex(0x00CDDF))
        dbpDataSet.lineWidth = 1
        
        var circleRadius: CGFloat = 0
        switch dateType {
        case .day:
            circleRadius = 3
        case .week:
            circleRadius = 5
        case .month:
            circleRadius = 3
        case .year:
            circleRadius = 4
        }
        
        if bpArray.count == 1 {
            sbpDataSet.circleColors = [UIColor.rgbColorFromHex(0xFFD200)]
            sbpDataSet.drawCircleHoleEnabled = false
            sbpDataSet.circleRadius = circleRadius
            dbpDataSet.circleColors = [UIColor.rgbColorFromHex(0x00CDDF)]
            dbpDataSet.drawCircleHoleEnabled = false
            dbpDataSet.circleRadius = circleRadius
        } else {
            sbpDataSet.drawCirclesEnabled = false
            dbpDataSet.drawCirclesEnabled = false
        }
   
        lineChartView.data = LineChartData(dataSets: [sbpDataSet, dbpDataSet])
    }
    
    
    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 = 60 //设置左侧Y轴最小值
        leftAxis.axisMaximum = 140
        leftAxis.granularity = 10
        
        let litmitLine = ChartLimitLine(limit: 60, 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 resetLabel() {
        sbpLabel.toUnitMode(text: "--", unit: " mmHg", font: BoldFont(23), unitFont: RegularFont(13))
        dbpLabel.toUnitMode(text: "--", unit: " mmHg", font: BoldFont(23), unitFont: RegularFont(13))
    }
    
    private func updateLabel(sbp: Int, dbp: Int) {
        sbpLabel.toUnitMode(text: "\(sbp)", unit: " mmHg", font: BoldFont(23), unitFont: RegularFont(13))
        dbpLabel.toUnitMode(text: "\(dbp)", unit: " mmHg", font: BoldFont(23), unitFont: RegularFont(13))
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

}