BloodPressureVC.swift 12.1 KB
//
//  BloodPressureVC.swift
//  Twear
//
//  Created by yangbin on 2021/11/25.
//

import UIKit
import Charts
import SwiftDate

class BloodPressureVC: UIViewController, DateSegmentViewDelegate, RangeSliderDelegate, ChartViewDelegate, BluetoothSyncDelegate {

    @IBOutlet weak var dateSegmentView: DateSegmentView!
    @IBOutlet weak var lineChartView: LineChartView!
    @IBOutlet weak var sliderView: RangeSliderView!
    @IBOutlet weak var dateLabel: UILabel!
    @IBOutlet weak var bpLabel: UILabel!
    @IBOutlet weak var dbpLabel: UILabel!
    @IBOutlet weak var sbpLabel: UILabel!
    
    private var dateType: DateType = .day
    private var selectedDate = Date()
    private lazy var monthDays = DateInRegion().monthDays
    private var points: [Double] = []
    
    
    private var bpArray: [BloodPressureModel] = [] {
        didSet {
            if bpArray.count == 0 {
                resetLabel()
            }
            points = []
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.navigationController?.setNavigationBarHidden(true, animated: true)
    }
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        BluetoothManager.shared.unRegisterSyncDelegate(self)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        dateSegmentView.selectedColor = UIColor.rgbColorFromHex(0xFFD200)
        dateSegmentView.delegate = self
        sliderView.delegate = self
        BluetoothManager.shared.registerSyncDelegate(self)
        
        view.layoutIfNeeded()
        setupChartView()
        didSelectedDate(date: DateInRegion(), dateType: .day)
        // Do any additional setup after loading the view.
    }
    func didReceiveBloodPressure() {
        didSelectedDate(date: DateInRegion(selectedDate), dateType: dateType)
    }
    @IBAction func share(_ sender: Any) {
        let shareView = ShareView(view.captureImage)
        shareView.show()
    }
    
    //MARK: DateSegmentViewDelegate
    func didSelectedDate(date: DateInRegion, dateType: DateType) {
        self.dateType = dateType
        monthDays = date.monthDays
        selectedDate = date.date

        switch dateType {
        case .day:
            bpArray = BloodPressureModel.getBloodPressureByDay(selectedDate)
            dateLabel.text = date.dateAt(.startOfDay).toString(.custom("HH:mm"))
        case .week:
            bpArray = BloodPressureModel.getBloodPressureByWeek(selectedDate)
            dateLabel.text = (date.dateAt(.startOfWeek)+1.days).toString(.custom("yyyy.MM.dd")) + " " + LocString("周一") + " " + LocString("平均收缩压/舒张压")
        case .month:
            bpArray = BloodPressureModel.getBloodPressureByMonth(selectedDate)
            dateLabel.text = date.dateAt(.startOfMonth).toString(.custom("yyyy.MM.dd")) + " " + LocString("平均收缩压/舒张压")
        case .year:
            bpArray = BloodPressureModel.getBloodPressureByYear(selectedDate)
            dateLabel.text = date.dateAtStartOf(.year).toString(.custom("yyyy.MM")) + " " + LocString("平均收缩压/舒张压")
        }
        
//        let bp3 = BloodPressureModel(dbp: 90, sbp: 110, date: DateInRegion().date-5.minutes)
//        let bp2 = BloodPressureModel(dbp: 68, sbp: 120, date: DateInRegion().date-45.minutes)
//        let bp1 = BloodPressureModel(dbp: 70, sbp: 100, date: DateInRegion().date-65.minutes)
//        bpArray = [bp3]
        updateChartView()
    }
    
    //MARK: RangeSliderDelegate
    func sliderDidChanged(index: Int) {
        lineChartView.highlightValues([Highlight(x: points[index], y: 0, dataSetIndex: 0)])
        updateLable(index)
    }
    
    //MARK: ChartViewDelegate
    func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
        if bpArray.count == 1 {
            lineChartView.highlightValues([Highlight(x: points[0], y: 0, dataSetIndex: 0)])
        } else {
            sliderView.didSelectedValue(entry.x)
        }
    }
    
    private func resetLabel() {
        bpLabel.text = "--/--"
        sbpLabel.text = "--"
        dbpLabel.text = "--"
    }
    
    private func updateLable(_ index: Int) {
        if bpArray.count == 0 {
            resetLabel()
            return
        }

        bpLabel.text = "\(bpArray[index].sbp)/\(bpArray[index].dbp)"
//
//        print(bpArray)
        
        if dateType == .day {
            let bp = BloodPressureModel.getAverageByDay(selectedDate)
            sbpLabel.text = "\(bp.sbp)"
            dbpLabel.text = "\(bp.dbp)"
        } else {
            sbpLabel.text = "\(bpArray[index].sbp)"
            dbpLabel.text = "\(bpArray[index].dbp)"
        }
        
        let sDate = bpArray[index].date!
        switch dateType {
        case .day:
            dateLabel.text = sDate.toString(.custom("HH:mm"))
        case .week:
            dateLabel.text = sDate.toString(.custom("yyyy.MM.dd")) + " " + sDate.weekText + " " + LocString("平均收缩压/舒张压")
        case .month:
            dateLabel.text = sDate.toString(.custom("yyyy.MM.dd")) + " " + LocString("平均收缩压/舒张压")
        case .year:
            dateLabel.text = sDate.toString(.custom("yyyy.MM")) + " " + LocString("平均收缩压/舒张压")
        }
    }
    
    
    private func updateChartView() {
        let xAxis = lineChartView.xAxis
        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
        }
        
        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)
                }
                points.append(pointX)
                sbpDataEntries.append(ChartDataEntry(x: pointX, y: Double(bp.sbp)))
                dbpDataEntries.append(ChartDataEntry(x: pointX, y: Double(bp.dbp)))
            }
        }
//        if sbpDataEntries.count == 1 {
//            sbpDataEntries.append(ChartDataEntry(x: sbpDataEntries[0].x+0.2, y: sbpDataEntries[0].y))
//            dbpDataEntries.append(ChartDataEntry(x: dbpDataEntries[0].x+0.2, y: dbpDataEntries[0].y))
//        }
        
        let sbpDataSet = LineChartDataSet(entries: sbpDataEntries)
        sbpDataSet.drawValuesEnabled = false
        sbpDataSet.highlightEnabled = true//选中拐点,是否开启高亮效果(显示十字线)
        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
        }
//        if
        
        
        lineChartView.data = LineChartData(dataSets: [sbpDataSet, dbpDataSet])
        lineChartView.highlightValues([Highlight(x: 0, y: 0, dataSetIndex: 0)])
        
        
        setupSliderViewScale()
    }
    
    
    
    private func setupSliderViewScale() {
        var endPointX: Int = 0
        switch dateType {
        case .day:
            endPointX = 24
        case .week:
            endPointX = 6
        case .month:
            endPointX = monthDays-1
        case .year:
            endPointX = 11
        }
        sliderView.setDrawSpace(startPointX: getChartViewX(0), endPointX: getChartViewX(endPointX), range: 0...endPointX, points: points, imageName: "slider_bp", isLast: true)
    }
    
    private func getChartViewX(_ x: Int) -> CGFloat {
        return lineChartView.pixelForValues(x: Double(x), y: 0, axis: .left).x
    }
    
    private func setupChartView() {
        lineChartView.delegate = self
        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
    }
    
    @IBAction func gotoReferenceVC(_ sender: Any) {
        let vc = UIStoryboard.loadViewControllerIdentifier(storyboardName: "Home", identifier: "BPReferenceVC")
        navigationController?.pushViewController(vc, animated: true)
    }
    
    @IBAction func back(_ sender: Any) {
        navigationController?.popViewController(animated: true)
    }
    

}