TIRGraphView.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // LoopFollow
  2. // TIRGraphView.swift
  3. import Charts
  4. import SwiftUI
  5. import UIKit
  6. struct TIRGraphView: UIViewRepresentable {
  7. let tirData: [TIRDataPoint]
  8. func makeCoordinator() -> Coordinator {
  9. Coordinator()
  10. }
  11. func makeUIView(context _: Context) -> UIView {
  12. let containerView = NonInteractiveContainerView()
  13. containerView.backgroundColor = .systemBackground
  14. let chartView = BarChartView()
  15. chartView.backgroundColor = .systemBackground
  16. chartView.rightAxis.enabled = false
  17. chartView.leftAxis.enabled = true
  18. chartView.xAxis.labelPosition = .bottom
  19. chartView.xAxis.granularity = 1.0
  20. chartView.leftAxis.axisMinimum = 0.0
  21. chartView.leftAxis.axisMaximum = 100.0
  22. chartView.leftAxis.valueFormatter = PercentageAxisValueFormatter()
  23. chartView.leftAxis.labelCount = 5
  24. chartView.rightAxis.drawGridLinesEnabled = false
  25. chartView.leftAxis.drawGridLinesEnabled = true
  26. chartView.leftAxis.gridLineDashLengths = [5, 5]
  27. chartView.xAxis.drawGridLinesEnabled = false
  28. chartView.legend.enabled = false
  29. chartView.chartDescription.enabled = false
  30. chartView.isUserInteractionEnabled = false
  31. containerView.addSubview(chartView)
  32. chartView.translatesAutoresizingMaskIntoConstraints = false
  33. NSLayoutConstraint.activate([
  34. chartView.topAnchor.constraint(equalTo: containerView.topAnchor),
  35. chartView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
  36. chartView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
  37. chartView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
  38. ])
  39. return containerView
  40. }
  41. class Coordinator {}
  42. func updateUIView(_ containerView: UIView, context _: Context) {
  43. guard let chartView = containerView.subviews.first as? BarChartView else { return }
  44. guard !tirData.isEmpty else { return }
  45. var dataEntries: [BarChartDataEntry] = []
  46. var xAxisLabels: [String] = []
  47. for (index, point) in tirData.enumerated() {
  48. let entry = BarChartDataEntry(
  49. x: Double(index),
  50. yValues: [
  51. point.veryLow,
  52. point.low,
  53. point.inRange,
  54. point.high,
  55. point.veryHigh,
  56. ]
  57. )
  58. dataEntries.append(entry)
  59. xAxisLabels.append(point.period.rawValue)
  60. }
  61. let dataSet = BarChartDataSet(entries: dataEntries, label: "Time in Range")
  62. dataSet.colors = [
  63. UIColor.systemRed.withAlphaComponent(0.8),
  64. UIColor.systemRed.withAlphaComponent(0.5),
  65. UIColor.systemGreen.withAlphaComponent(0.7),
  66. UIColor.systemYellow.withAlphaComponent(0.7),
  67. UIColor.systemOrange.withAlphaComponent(0.7),
  68. ]
  69. dataSet.stackLabels = ["Very Low", "Low", "In Range", "High", "Very High"]
  70. dataSet.drawValuesEnabled = false
  71. let data = BarChartData(dataSet: dataSet)
  72. data.barWidth = 0.6
  73. chartView.data = data
  74. chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: xAxisLabels)
  75. chartView.xAxis.labelRotationAngle = 0
  76. chartView.xAxis.labelCount = xAxisLabels.count
  77. chartView.notifyDataSetChanged()
  78. }
  79. }
  80. class PercentageAxisValueFormatter: AxisValueFormatter {
  81. func stringForValue(_ value: Double, axis _: AxisBase?) -> String {
  82. return String(format: "%.0f%%", value)
  83. }
  84. }