// // StepReportCell.swift // Twear // // Created by yangbin on 2022/1/1. // import UIKit import Charts import SwiftDate class StepReportCell: UICollectionViewCell { @IBOutlet weak var lineChartView: LineChartView! @IBOutlet weak var stepLabel: UILabel! @IBOutlet weak var stepsGoalLabel: UILabel! @IBOutlet weak var dateLabel: UILabel! @IBOutlet weak var detailLabel: UILabel! var dateType: DateType = .day { didSet { updateChartView() } } private let goal: Int = UserInfo.stepsGoal lazy private var monthDays = DateInRegion().monthDays var stepArray: [StepModel] = [] private func updateChartView() { setupChartView() let nowDate = DateInRegion().date switch dateType { case .day: stepArray = StepModel.getStepsByDay(nowDate) dateLabel.text = nowDate.dateAt(.startOfDay).toString(.custom("yyyy.MM.dd")) case .week: stepArray = StepModel.getStepsByWeek(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: stepArray = StepModel.getStepsByMonth(nowDate) dateLabel.text = nowDate.toString(.custom("yyyy.MM")) case .year: stepArray = StepModel.getStepsByYear(nowDate) dateLabel.text = "\(nowDate.year).01-\(nowDate.year).12" } var maxStep = stepArray.max(\.number)?.number ?? goal if maxStep <= goal { maxStep = goal } if dateType == .day { detailLabel.text = LocString("目标步数") } else { detailLabel.text = LocString("日均步数") } if stepArray.count == 0 { setSteps(nil) } else { if dateType == .day { if let step = stepArray.last { setSteps(step.number) } setStepsGoal(goal) } else { lineChartView.leftAxis.axisMaximum = maxStep == goal ? Double(goal) : Double(maxStep) * 1.2 setSteps(stepArray.sum(\.number)) setStepsGoal(stepArray.average(\.number)) } } var dataEntries = [ChartDataEntry]() for step in stepArray { var pointX: Double = 0 switch dateType { case .day: if step.date!.hour == 23 { pointX = 24 } else { pointX = Double((step.date!+1.hours).hour)+Double(step.date!.minute)/60.0 } case .week: pointX = Double(step.date!.weekIndex) case .month: pointX = Double(step.date!.day-1) case .year: pointX = Double(step.date!.month-1) } dataEntries.append(ChartDataEntry(x: pointX, y: Double(step.number))) } if stepArray.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(0x1DDCC5)// 十字线颜色 dataSet.drawHorizontalHighlightIndicatorEnabled = false dataSet.mode = .horizontalBezier dataSet.setColor(UIColor.rgbColorFromHex(0x1DDCC5)) dataSet.lineWidth = 1 dataSet.drawFilledEnabled = true //填充绘制 let gradientColors = [UIColor.rgbColorFromHex(0x1DDCC5).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]) // lineChartView.highlightValues([Highlight(x: 0, y: 0, dataSetIndex: 0)]) } private func setSteps(_ steps: Int?) { if steps == nil { stepLabel.toUnitMode(text: "--", unit: " \(LocString("步"))", font: BoldFont(23), unitFont: RegularFont(13)) } else { stepLabel.toUnitMode(text: "\(steps!)", unit: " \(LocString("步"))", font: BoldFont(23), unitFont: RegularFont(13)) } } private func setStepsGoal(_ steps: Int) { stepsGoalLabel.toUnitMode(text: "\(steps)", unit: " \(LocString("步"))", font: BoldFont(23), unitFont: RegularFont(13)) } 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 = -4 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.axisMaximum = Double(goal) leftAxis.granularity = 500 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 } } override func awakeFromNib() { super.awakeFromNib() // Initialization code } }