Просмотр исходного кода

Migrate charts to Swift Charts (#704)

* Migrate charts to Swift Charts

Replaces the danielgindi Charts and SwiftAlgorithms CocoaPods with native
Swift Charts.

- Rebuilds the BG graph, treatments, and prediction cone on Swift Charts
  with a custom pan/zoom/inspect interaction layer.
- Ports the stats views (AGP, TIR, GRI) off the old Charts dependency.
- Drops the Charts and SwiftAlgorithms pods and their generated support files.

Chart appearance and behaviour are kept at parity with the previous
implementation.

* Raise app and Live Activity extension deployment target to iOS 18.0

* Show every reading and treatment under the chart scrubber

When the detail selector is dragged across the chart, the pill now lists
every item near the finger — the nearest glucose reading plus any treatments
whose symbols fall within a screen-space capture band — instead of a single
winner chosen by time. Every glucose reading stays inspectable, including
where a bolus, carb entry, or an on-trace treatment (BG check, note, suspend,
resume, sensor start) shares its time.

* Enhance AGP, GRI, and TIR graph views with threshold indicators and improved padding

* Refactor threshold label handling in AGPGraphView to use Localizer for unit display

* Add label support to BandRect, enhance band label rendering in BGChartView and fix upper domain for Y label

* Show Trio override names on the graph

Trio uploads overrides as Exercise events with the name in the notes
field and no reason field, so the graph band label fell back to the
generic "Override". Resolve the name notes-first (falling back to
reason for Loop) when building the override graph data, matching the
info table and treatments list.

---------

Co-authored-by: codebymini <daniel@codebymini.se>
Co-authored-by: Daniel Mini Johansson <42831533+codebymini@users.noreply.github.com>
Jonas Björkert 1 неделя назад
Родитель
Сommit
b6c81a88de
100 измененных файлов с 2727 добавлено и 16249 удалено
  1. 33 21
      LoopFollow.xcodeproj/project.pbxproj
  2. 594 0
      LoopFollow/Charts/BGChartModel.swift
  3. 190 0
      LoopFollow/Charts/BGChartStubs.swift
  4. 1598 0
      LoopFollow/Charts/BGChartView.swift
  5. 0 2206
      LoopFollow/Controllers/Graphs.swift
  6. 0 2
      LoopFollow/Controllers/NightScout.swift
  7. 6 1
      LoopFollow/Controllers/Nightscout/Treatments/Overrides.swift
  8. 0 1
      LoopFollow/Controllers/Nightscout/Treatments/SMB.swift
  9. 0 1
      LoopFollow/Controllers/Nightscout/Treatments/TemporaryTarget.swift
  10. 20 25
      LoopFollow/Controllers/StatsDisplayView.swift
  11. 2 1
      LoopFollow/Controllers/Timers.swift
  12. 0 216
      LoopFollow/Helpers/Chart.swift
  13. 0 28
      LoopFollow/Helpers/carbBolusArrays.swift
  14. 121 124
      LoopFollow/Stats/AGP/AGPGraphView.swift
  15. 3 1
      LoopFollow/Stats/AGP/AGPView.swift
  16. 0 25
      LoopFollow/Stats/ChartContainerView.swift
  17. 77 107
      LoopFollow/Stats/GRI/GRIRiskGridView.swift
  18. 3 1
      LoopFollow/Stats/GRI/GRIView.swift
  19. 61 84
      LoopFollow/Stats/TIR/TIRGraphView.swift
  20. 3 1
      LoopFollow/Stats/TIR/TIRView.swift
  21. 0 20
      LoopFollow/ViewControllers/LineChartWrapper.swift
  22. 6 5
      LoopFollow/ViewControllers/MainHomeView.swift
  23. 8 28
      LoopFollow/ViewControllers/MainViewController.swift
  24. 0 51
      Podfile
  25. 2 15
      Podfile.lock
  26. 0 202
      Pods/Charts/LICENSE
  27. 0 14
      Pods/Charts/PrivacyInfo.xcprivacy
  28. 0 239
      Pods/Charts/README.md
  29. 0 281
      Pods/Charts/Source/Charts/Animation/Animator.swift
  30. 0 394
      Pods/Charts/Source/Charts/Animation/ChartAnimationEasing.swift
  31. 0 186
      Pods/Charts/Source/Charts/Charts/BarChartView.swift
  32. 0 1958
      Pods/Charts/Source/Charts/Charts/BarLineChartViewBase.swift
  33. 0 27
      Pods/Charts/Source/Charts/Charts/BubbleChartView.swift
  34. 0 34
      Pods/Charts/Source/Charts/Charts/CandleStickChartView.swift
  35. 0 890
      Pods/Charts/Source/Charts/Charts/ChartViewBase.swift
  36. 0 246
      Pods/Charts/Source/Charts/Charts/CombinedChartView.swift
  37. 0 269
      Pods/Charts/Source/Charts/Charts/HorizontalBarChartView.swift
  38. 0 28
      Pods/Charts/Source/Charts/Charts/LineChartView.swift
  39. 0 675
      Pods/Charts/Source/Charts/Charts/PieChartView.swift
  40. 0 854
      Pods/Charts/Source/Charts/Charts/PieRadarChartViewBase.swift
  41. 0 220
      Pods/Charts/Source/Charts/Charts/RadarChartView.swift
  42. 0 31
      Pods/Charts/Source/Charts/Charts/ScatterChartView.swift
  43. 0 358
      Pods/Charts/Source/Charts/Components/AxisBase.swift
  44. 0 74
      Pods/Charts/Source/Charts/Components/ChartLimitLine.swift
  45. 0 37
      Pods/Charts/Source/Charts/Components/ComponentBase.swift
  46. 0 54
      Pods/Charts/Source/Charts/Components/Description.swift
  47. 0 418
      Pods/Charts/Source/Charts/Components/Legend.swift
  48. 0 73
      Pods/Charts/Source/Charts/Components/LegendEntry.swift
  49. 0 39
      Pods/Charts/Source/Charts/Components/Marker.swift
  50. 0 106
      Pods/Charts/Source/Charts/Components/MarkerImage.swift
  51. 0 99
      Pods/Charts/Source/Charts/Components/MarkerView.swift
  52. 0 75
      Pods/Charts/Source/Charts/Components/XAxis.swift
  53. 0 206
      Pods/Charts/Source/Charts/Components/YAxis.swift
  54. 0 413
      Pods/Charts/Source/Charts/Data/Implementations/ChartBaseDataSet.swift
  55. 0 108
      Pods/Charts/Source/Charts/Data/Implementations/Standard/BarChartData.swift
  56. 0 214
      Pods/Charts/Source/Charts/Data/Implementations/Standard/BarChartDataEntry.swift
  57. 0 134
      Pods/Charts/Source/Charts/Data/Implementations/Standard/BarChartDataSet.swift
  58. 0 30
      Pods/Charts/Source/Charts/Data/Implementations/Standard/BarLineScatterCandleBubbleChartData.swift
  59. 0 38
      Pods/Charts/Source/Charts/Data/Implementations/Standard/BarLineScatterCandleBubbleChartDataSet.swift
  60. 0 37
      Pods/Charts/Source/Charts/Data/Implementations/Standard/BubbleChartData.swift
  61. 0 79
      Pods/Charts/Source/Charts/Data/Implementations/Standard/BubbleChartDataEntry.swift
  62. 0 53
      Pods/Charts/Source/Charts/Data/Implementations/Standard/BubbleChartDataSet.swift
  63. 0 30
      Pods/Charts/Source/Charts/Data/Implementations/Standard/CandleChartData.swift
  64. 0 98
      Pods/Charts/Source/Charts/Data/Implementations/Standard/CandleChartDataEntry.swift
  65. 0 117
      Pods/Charts/Source/Charts/Data/Implementations/Standard/CandleChartDataSet.swift
  66. 0 574
      Pods/Charts/Source/Charts/Data/Implementations/Standard/ChartData.swift
  67. 0 110
      Pods/Charts/Source/Charts/Data/Implementations/Standard/ChartDataEntry.swift
  68. 0 96
      Pods/Charts/Source/Charts/Data/Implementations/Standard/ChartDataEntryBase.swift
  69. 0 489
      Pods/Charts/Source/Charts/Data/Implementations/Standard/ChartDataSet.swift
  70. 0 292
      Pods/Charts/Source/Charts/Data/Implementations/Standard/CombinedChartData.swift
  71. 0 31
      Pods/Charts/Source/Charts/Data/Implementations/Standard/LineChartData.swift
  72. 0 177
      Pods/Charts/Source/Charts/Data/Implementations/Standard/LineChartDataSet.swift
  73. 0 85
      Pods/Charts/Source/Charts/Data/Implementations/Standard/LineRadarChartDataSet.swift
  74. 0 51
      Pods/Charts/Source/Charts/Data/Implementations/Standard/LineScatterCandleRadarChartDataSet.swift
  75. 0 107
      Pods/Charts/Source/Charts/Data/Implementations/Standard/PieChartData.swift
  76. 0 119
      Pods/Charts/Source/Charts/Data/Implementations/Standard/PieChartDataEntry.swift
  77. 0 130
      Pods/Charts/Source/Charts/Data/Implementations/Standard/PieChartDataSet.swift
  78. 0 51
      Pods/Charts/Source/Charts/Data/Implementations/Standard/RadarChartData.swift
  79. 0 54
      Pods/Charts/Source/Charts/Data/Implementations/Standard/RadarChartDataEntry.swift
  80. 0 59
      Pods/Charts/Source/Charts/Data/Implementations/Standard/RadarChartDataSet.swift
  81. 0 39
      Pods/Charts/Source/Charts/Data/Implementations/Standard/ScatterChartData.swift
  82. 0 78
      Pods/Charts/Source/Charts/Data/Implementations/Standard/ScatterChartDataSet.swift
  83. 0 42
      Pods/Charts/Source/Charts/Data/Interfaces/BarChartDataSetProtocol.swift
  84. 0 26
      Pods/Charts/Source/Charts/Data/Interfaces/BarLineScatterCandleBubbleChartDataSetProtocol.swift
  85. 0 27
      Pods/Charts/Source/Charts/Data/Interfaces/BubbleChartDataSetProtocol.swift
  86. 0 66
      Pods/Charts/Source/Charts/Data/Interfaces/CandleChartDataSetProtocol.swift
  87. 0 270
      Pods/Charts/Source/Charts/Data/Interfaces/ChartDataSetProtocol.swift
  88. 0 86
      Pods/Charts/Source/Charts/Data/Interfaces/LineChartDataSetProtocol.swift
  89. 0 45
      Pods/Charts/Source/Charts/Data/Interfaces/LineRadarChartDataSetProtocol.swift
  90. 0 36
      Pods/Charts/Source/Charts/Data/Interfaces/LineScatterCandleRadarChartDataSetProtocol.swift
  91. 0 64
      Pods/Charts/Source/Charts/Data/Interfaces/PieChartDataSetProtocol.swift
  92. 0 40
      Pods/Charts/Source/Charts/Data/Interfaces/RadarChartDataSetProtocol.swift
  93. 0 36
      Pods/Charts/Source/Charts/Data/Interfaces/ScatterChartDataSetProtocol.swift
  94. 0 153
      Pods/Charts/Source/Charts/Filters/DataApproximator+N.swift
  95. 0 115
      Pods/Charts/Source/Charts/Filters/DataApproximator.swift
  96. 0 30
      Pods/Charts/Source/Charts/Formatters/AxisValueFormatter.swift
  97. 0 100
      Pods/Charts/Source/Charts/Formatters/DefaultAxisValueFormatter.swift
  98. 0 58
      Pods/Charts/Source/Charts/Formatters/DefaultFillFormatter.swift
  99. 0 111
      Pods/Charts/Source/Charts/Formatters/DefaultValueFormatter.swift
  100. 0 0
      Pods/Charts/Source/Charts/Formatters/FillFormatter.swift

+ 33 - 21
LoopFollow.xcodeproj/project.pbxproj

@@ -9,6 +9,7 @@
 /* Begin PBXBuildFile section */
 		18BA6357F867577712A116EB /* DBSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B81E18A2489A364AFC0A9E4 /* DBSize.swift */; };
 		2D8068C66833EEAED7B4BEB8 /* FutureCarbsCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBAB9EECE7095238A558060 /* FutureCarbsCondition.swift */; };
+		2F99F2B5C902F3018383C086 /* BGChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F575C47A06818042D6CB8C /* BGChartView.swift */; };
 		374A77992F5BD8B200E96858 /* APNSClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374A77982F5BD8AB00E96858 /* APNSClient.swift */; };
 		374A77A52F5BE17000E96858 /* AppGroupID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374A779F2F5BE17000E96858 /* AppGroupID.swift */; };
 		374A77A62F5BE17000E96858 /* GlucoseSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374A77A12F5BE17000E96858 /* GlucoseSnapshot.swift */; };
@@ -66,8 +67,10 @@
 		65E153C32E4BB69100693A4F /* URLTokenValidationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E153C22E4BB69100693A4F /* URLTokenValidationView.swift */; };
 		65E8A2862E44B0300065037B /* VolumeButtonHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E8A2852E44B0300065037B /* VolumeButtonHandler.swift */; };
 		66E3D12E66AA4534A144A54B /* BackgroundRefreshManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8CA8BE0B3D247408FE088B4 /* BackgroundRefreshManager.swift */; };
+		92664FA270DA9905E1F08676 /* BGChartStubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C508E0E86BEC0B13280F34B /* BGChartStubs.swift */; };
 		9727B75402723679BD39CDE5 /* DBSizeTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBE9ECA96BEA20DBD21B570D /* DBSizeTask.swift */; };
 		9C7FB98C98BE4FF98F4815EE /* Telemetry.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDFBE69CEF18416D84959974 /* Telemetry.swift */; };
+		9F24B79D2722BB040AE3311F /* BGChartModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C8CB992D98689FC7D019CEC /* BGChartModel.swift */; };
 		A1A1A10001000000A0CFEED1 /* APNsCredentialValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1A1A10001000000A0CFEED2 /* APNsCredentialValidator.swift */; };
 		A1A1A10002000000A0CFEED1 /* LogRedactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1A1A10002000000A0CFEED2 /* LogRedactor.swift */; };
 		A1B2C3D4E5F6A7B8C9D0E1F3 /* StatsDisplayModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B2C3D4E5F6A7B8C9D0E1F2 /* StatsDisplayModel.swift */; };
@@ -169,7 +172,6 @@
 		DD608A0C2C27415C00F91132 /* BackgroundAlertManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD608A0B2C27415C00F91132 /* BackgroundAlertManager.swift */; };
 		DD6A935E2BFA6FA2003FFB8E /* DeviceStatusOpenAPS.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6A935D2BFA6FA2003FFB8E /* DeviceStatusOpenAPS.swift */; };
 		DD7A3B5D2F1E8D9A00B4C6E1 /* BGDisplayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7A3B5C2F1E8D9A00B4C6E1 /* BGDisplayView.swift */; };
-		DD7A3B5F2F1E8DA000B4C6E1 /* LineChartWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7A3B5E2F1E8DA000B4C6E1 /* LineChartWrapper.swift */; };
 		DD7A3B612F1E8DA600B4C6E1 /* MainHomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7A3B602F1E8DA600B4C6E1 /* MainHomeView.swift */; };
 		DD7B0D442D730A3B0063DCB6 /* CycleHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7B0D432D730A320063DCB6 /* CycleHelper.swift */; };
 		DD7E19842ACDA50C00DBD158 /* Overrides.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7E19832ACDA50C00DBD158 /* Overrides.swift */; };
@@ -301,7 +303,6 @@
 		FC16A97A24996673003D6245 /* NightScout.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC16A97924996673003D6245 /* NightScout.swift */; };
 		FC16A97B249966A3003D6245 /* AlarmSound.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC7CE589248ABEA3001F83B8 /* AlarmSound.swift */; };
 		FC16A97D24996747003D6245 /* SpeakBG.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC16A97C24996747003D6245 /* SpeakBG.swift */; };
-		FC16A97F249969E2003D6245 /* Graphs.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC16A97E249969E2003D6245 /* Graphs.swift */; };
 		FC16A98124996C07003D6245 /* DateTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC16A98024996C07003D6245 /* DateTime.swift */; };
 		FC1BDD2B24A22650001B652C /* Stats.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC1BDD2A24A22650001B652C /* Stats.swift */; };
 		FC1BDD2D24A23204001B652C /* MainViewController+updateStats.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC1BDD2C24A23204001B652C /* MainViewController+updateStats.swift */; };
@@ -438,7 +439,6 @@
 		FCE537BC249A4D7D00F80BF8 /* carbBolusArrays.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE537BB249A4D7D00F80BF8 /* carbBolusArrays.swift */; };
 		FCEF87AC24A141A700AE6FA0 /* Localizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEF87AA24A1417900AE6FA0 /* Localizer.swift */; };
 		FCFEEC9E2486E68E00402A7F /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FCFEEC9D2486E68E00402A7F /* WebKit.framework */; };
-		FCFEECA02488157B00402A7F /* Chart.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCFEEC9F2488157B00402A7F /* Chart.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -528,6 +528,8 @@
 		65A100022F5AA00000AA1002 /* UnitsConfigurationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitsConfigurationView.swift; sourceTree = "<group>"; };
 		65E153C22E4BB69100693A4F /* URLTokenValidationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLTokenValidationView.swift; sourceTree = "<group>"; };
 		65E8A2852E44B0300065037B /* VolumeButtonHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumeButtonHandler.swift; sourceTree = "<group>"; };
+		6C508E0E86BEC0B13280F34B /* BGChartStubs.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BGChartStubs.swift; sourceTree = "<group>"; };
+		7C8CB992D98689FC7D019CEC /* BGChartModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BGChartModel.swift; sourceTree = "<group>"; };
 		8B81E18A2489A364AFC0A9E4 /* DBSize.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DBSize.swift; sourceTree = "<group>"; };
 		A1A1A10001000000A0CFEED2 /* APNsCredentialValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APNsCredentialValidator.swift; sourceTree = "<group>"; };
 		A1A1A10002000000A0CFEED2 /* LogRedactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogRedactor.swift; sourceTree = "<group>"; };
@@ -542,6 +544,7 @@
 		B500000000000000000000B1 /* RemoteMealHistoryEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteMealHistoryEntry.swift; sourceTree = "<group>"; };
 		B500000000000000000000B3 /* QuickPickMealsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickPickMealsManager.swift; sourceTree = "<group>"; };
 		B500000000000000000000C1 /* QuickPickSectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickPickSectionHeader.swift; sourceTree = "<group>"; };
+		B5F575C47A06818042D6CB8C /* BGChartView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BGChartView.swift; sourceTree = "<group>"; };
 		B7D2A4EFD18B7B7748B6669E /* FutureCarbsAlarmEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FutureCarbsAlarmEditor.swift; sourceTree = "<group>"; };
 		BB2C3D4E5F6A7B8C9D0E1F2A /* MainTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabView.swift; sourceTree = "<group>"; };
 		BDFBE69CEF18416D84959974 /* Telemetry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Telemetry.swift; sourceTree = "<group>"; };
@@ -631,7 +634,6 @@
 		DD608A0B2C27415C00F91132 /* BackgroundAlertManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundAlertManager.swift; sourceTree = "<group>"; };
 		DD6A935D2BFA6FA2003FFB8E /* DeviceStatusOpenAPS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceStatusOpenAPS.swift; sourceTree = "<group>"; };
 		DD7A3B5C2F1E8D9A00B4C6E1 /* BGDisplayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGDisplayView.swift; sourceTree = "<group>"; };
-		DD7A3B5E2F1E8DA000B4C6E1 /* LineChartWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineChartWrapper.swift; sourceTree = "<group>"; };
 		DD7A3B602F1E8DA600B4C6E1 /* MainHomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeView.swift; sourceTree = "<group>"; };
 		DD7B0D432D730A320063DCB6 /* CycleHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CycleHelper.swift; sourceTree = "<group>"; };
 		DD7E19832ACDA50C00DBD158 /* Overrides.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Overrides.swift; sourceTree = "<group>"; };
@@ -765,7 +767,6 @@
 		EE5F6A7B8C9D0E1F2A3B4C5D /* NightscoutContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutContentView.swift; sourceTree = "<group>"; };
 		FC16A97924996673003D6245 /* NightScout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightScout.swift; sourceTree = "<group>"; };
 		FC16A97C24996747003D6245 /* SpeakBG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpeakBG.swift; sourceTree = "<group>"; };
-		FC16A97E249969E2003D6245 /* Graphs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Graphs.swift; sourceTree = "<group>"; };
 		FC16A98024996C07003D6245 /* DateTime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTime.swift; sourceTree = "<group>"; };
 		FC1BDD2A24A22650001B652C /* Stats.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stats.swift; sourceTree = "<group>"; };
 		FC1BDD2C24A23204001B652C /* MainViewController+updateStats.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainViewController+updateStats.swift"; sourceTree = "<group>"; };
@@ -907,7 +908,6 @@
 		FCE537C2249AAB2600F80BF8 /* NotificationCenter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NotificationCenter.framework; path = System/Library/Frameworks/NotificationCenter.framework; sourceTree = SDKROOT; };
 		FCEF87AA24A1417900AE6FA0 /* Localizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Localizer.swift; sourceTree = "<group>"; };
 		FCFEEC9D2486E68E00402A7F /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
-		FCFEEC9F2488157B00402A7F /* Chart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Chart.swift; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFileSystemSynchronizedRootGroup section */
@@ -1051,6 +1051,7 @@
 				FCE537C2249AAB2600F80BF8 /* NotificationCenter.framework */,
 				37A4BDDA2F5B6B4A00EEB289 /* WidgetKit.framework */,
 				37A4BDDC2F5B6B4A00EEB289 /* SwiftUI.framework */,
+				CC91308AF89D63D758EAF1C3 /* iOS */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
@@ -1082,6 +1083,23 @@
 			path = QuickPickMeals;
 			sourceTree = "<group>";
 		};
+		CC1E389FE3B6E6EA3184474B /* Charts */ = {
+			isa = PBXGroup;
+			children = (
+				7C8CB992D98689FC7D019CEC /* BGChartModel.swift */,
+				B5F575C47A06818042D6CB8C /* BGChartView.swift */,
+				6C508E0E86BEC0B13280F34B /* BGChartStubs.swift */,
+			);
+			path = Charts;
+			sourceTree = "<group>";
+		};
+		CC91308AF89D63D758EAF1C3 /* iOS */ = {
+			isa = PBXGroup;
+			children = (
+			);
+			name = iOS;
+			sourceTree = "<group>";
+		};
 		DD02475A2DB2E8CE00FCADF6 /* AlarmCondition */ = {
 			isa = PBXGroup;
 			children = (
@@ -1528,7 +1546,6 @@
 				FC7CE589248ABEA3001F83B8 /* AlarmSound.swift */,
 				FC16A97924996673003D6245 /* NightScout.swift */,
 				FC16A97C24996747003D6245 /* SpeakBG.swift */,
-				FC16A97E249969E2003D6245 /* Graphs.swift */,
 				FC1BDD2A24A22650001B652C /* Stats.swift */,
 				FC1BDD2C24A23204001B652C /* MainViewController+updateStats.swift */,
 				A1B2C3D4E5F6A7B8C9D0E1F2 /* StatsDisplayModel.swift */,
@@ -1700,6 +1717,7 @@
 				DDC7E5CD2DC6637800EB1127 /* Storage */,
 				DDEF503D2D32753A00999A5D /* Task */,
 				FCC68871248A736700A0279D /* ViewControllers */,
+				CC1E389FE3B6E6EA3184474B /* Charts */,
 			);
 			path = LoopFollow;
 			sourceTree = "<group>";
@@ -1763,7 +1781,6 @@
 				FCC688592489554800A0279D /* BackgroundTaskAudio.swift */,
 				A1A1A10001000000A0CFEED2 /* APNsCredentialValidator.swift */,
 				A8CA8BE0B3D247408FE088B4 /* BackgroundRefreshManager.swift */,
-				FCFEEC9F2488157B00402A7F /* Chart.swift */,
 				FCC0FAC124922A22003E610E /* DictionaryKeyPath.swift */,
 				FC16A98024996C07003D6245 /* DateTime.swift */,
 				654132E92E19F24800BDBE08 /* TOTPGenerator.swift */,
@@ -1790,7 +1807,6 @@
 			isa = PBXGroup;
 			children = (
 				DD7A3B5C2F1E8D9A00B4C6E1 /* BGDisplayView.swift */,
-				DD7A3B5E2F1E8DA000B4C6E1 /* LineChartWrapper.swift */,
 				DD7A3B602F1E8DA600B4C6E1 /* MainHomeView.swift */,
 				CC3D4E5F6A7B8C9D0E1F2A3B /* MoreMenuView.swift */,
 				EE5F6A7B8C9D0E1F2A3B4C5D /* NightscoutContentView.swift */,
@@ -1906,7 +1922,7 @@
 			);
 			mainGroup = FC97880B2485969B00A7906C;
 			packageReferences = (
-				DD50C10A2F60A00000000002 /* XCRemoteSwiftPackageReference "socket.io-client-swift" */,
+				DD50C10A2F60A00000000002 /* XCRemoteSwiftPackageReference "socket" */,
 			);
 			productRefGroup = FC9788152485969B00A7906C /* Products */;
 			projectDirPath = "";
@@ -2295,7 +2311,6 @@
 				DD4E5F6A7B8C9D0E2F2A3B4C /* RemoteContentView.swift in Sources */,
 				DD48780A2C7B30D40048F05C /* RemoteSettingsViewModel.swift in Sources */,
 				AB1CD0012C7B30D40048F05C /* RemoteDiagnostics.swift in Sources */,
-				FCFEECA02488157B00402A7F /* Chart.swift in Sources */,
 				DDDC31CE2E13A811009EA0F3 /* AlarmTile.swift in Sources */,
 				DD0C0C6D2C48606200DBADDF /* CarbMetric.swift in Sources */,
 				DDC7E5422DBD8A1600EB1127 /* AlarmGeneralSection.swift in Sources */,
@@ -2314,12 +2329,10 @@
 				DDF6999E2C5AAA640058A8D9 /* ErrorMessageView.swift in Sources */,
 				CC3D4E5F6A7B8C9D0E2F2A3B /* MoreMenuView.swift in Sources */,
 				DD7A3B5D2F1E8D9A00B4C6E1 /* BGDisplayView.swift in Sources */,
-				DD7A3B5F2F1E8DA000B4C6E1 /* LineChartWrapper.swift in Sources */,
 				DD7A3B612F1E8DA600B4C6E1 /* MainHomeView.swift in Sources */,
 				EE5F6A7B8C9D0E2F2A3B4C5D /* NightscoutContentView.swift in Sources */,
 				654132E72E19EA7E00BDBE08 /* SimpleQRCodeScannerView.swift in Sources */,
 				DD4878152C7B75230048F05C /* MealView.swift in Sources */,
-				FC16A97F249969E2003D6245 /* Graphs.swift in Sources */,
 				FC8589BF252B54F500C8FC73 /* Mobileprovision.swift in Sources */,
 				DD4878052C7B2C970048F05C /* Storage.swift in Sources */,
 				DD493AE12ACF22FE009A6922 /* Profile.swift in Sources */,
@@ -2467,6 +2480,9 @@
 				DDEF50422D479BAA00884336 /* LoopAPNSCarbsView.swift in Sources */,
 				DDEF50432D479BBA00884336 /* LoopAPNSBolusView.swift in Sources */,
 				DDEF50452D479BDA00884336 /* LoopAPNSRemoteView.swift in Sources */,
+				9F24B79D2722BB040AE3311F /* BGChartModel.swift in Sources */,
+				2F99F2B5C902F3018383C086 /* BGChartView.swift in Sources */,
+				92664FA270DA9905E1F08676 /* BGChartStubs.swift in Sources */,
 				18BA6357F867577712A116EB /* DBSize.swift in Sources */,
 				9727B75402723679BD39CDE5 /* DBSizeTask.swift in Sources */,
 				E2BE9B6A33AE4F0FD750767E /* DBSizeCondition.swift in Sources */,
@@ -2522,7 +2538,7 @@
 				INFOPLIST_FILE = LoopFollowLAExtension/ExtensionInfo.plist;
 				INFOPLIST_KEY_CFBundleDisplayName = LoopFollowLAExtension;
 				INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2026 Jon Fawcett. All rights reserved.";
-				IPHONEOS_DEPLOYMENT_TARGET = 16.6;
+				IPHONEOS_DEPLOYMENT_TARGET = 18.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
@@ -2574,7 +2590,7 @@
 				INFOPLIST_FILE = LoopFollowLAExtension/ExtensionInfo.plist;
 				INFOPLIST_KEY_CFBundleDisplayName = LoopFollowLAExtension;
 				INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2026 Jon Fawcett. All rights reserved.";
-				IPHONEOS_DEPLOYMENT_TARGET = 16.6;
+				IPHONEOS_DEPLOYMENT_TARGET = 18.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
@@ -2618,9 +2634,7 @@
 				ENABLE_USER_SCRIPT_SANDBOXING = YES;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(inherited)",
-					"$(BUILT_PRODUCTS_DIR)/Charts",
 					"$(BUILT_PRODUCTS_DIR)/ShareClient",
-					"$(BUILT_PRODUCTS_DIR)/SwiftAlgorithms",
 				);
 				GCC_C_LANGUAGE_STANDARD = gnu17;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -2651,9 +2665,7 @@
 				ENABLE_USER_SCRIPT_SANDBOXING = YES;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(inherited)",
-					"$(BUILT_PRODUCTS_DIR)/Charts",
 					"$(BUILT_PRODUCTS_DIR)/ShareClient",
-					"$(BUILT_PRODUCTS_DIR)/SwiftAlgorithms",
 				);
 				GCC_C_LANGUAGE_STANDARD = gnu17;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -2801,7 +2813,7 @@
 				DEFINES_MODULE = YES;
 				DEVELOPMENT_TEAM = "$(LF_DEVELOPMENT_TEAM)";
 				INFOPLIST_FILE = LoopFollow/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 16.6;
+				IPHONEOS_DEPLOYMENT_TARGET = 18.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
@@ -2826,7 +2838,7 @@
 				DEFINES_MODULE = YES;
 				DEVELOPMENT_TEAM = "$(LF_DEVELOPMENT_TEAM)";
 				INFOPLIST_FILE = LoopFollow/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 16.6;
+				IPHONEOS_DEPLOYMENT_TARGET = 18.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",

+ 594 - 0
LoopFollow/Charts/BGChartModel.swift

@@ -0,0 +1,594 @@
+// LoopFollow
+// BGChartModel.swift
+
+import Foundation
+import SwiftUI
+
+/// Interaction state shared between the main chart (which owns the gestures)
+/// and the small overview chart (which shows a viewport box and navigates on
+/// tap). Kept separate from BGChartModel so high-frequency pan/zoom writes
+/// don't invalidate views that only observe the data.
+final class BGChartInteraction: ObservableObject {
+    /// Date at the leading (left) edge of the main chart's visible window.
+    @Published var scrollPosition: Date
+    /// Length of the visible x-axis window in seconds.
+    @Published var visibleSeconds: TimeInterval
+    /// True while the main chart should keep auto-scrolling to "now"; cleared
+    /// when the user pans back into history, re-armed when they return to the edge.
+    @Published var followLatest: Bool = true
+
+    init() {
+        let seconds = Self.visibleSeconds(forScale: Storage.shared.chartScaleX.value)
+        visibleSeconds = seconds
+        scrollPosition = Date().addingTimeInterval(-seconds * 0.7)
+    }
+
+    /// Maps the persisted zoom scale (24 h divided by the scale factor) to a
+    /// visible-window length.
+    static func visibleSeconds(forScale scale: Double) -> TimeInterval {
+        guard scale > 0 else { return 6 * 3600 }
+        return min(max(24 * 3600 / scale, 15 * 60), 24 * 3600)
+    }
+
+    /// Persists the current zoom back into the stored scale representation.
+    func persistZoom() {
+        Storage.shared.chartScaleX.value = 24 * 3600 / visibleSeconds
+    }
+}
+
+final class BGChartModel: ObservableObject {
+    struct BGPoint: Identifiable {
+        let date: Date
+        let value: Double
+        let color: Color
+        var id: Double { date.timeIntervalSince1970 }
+    }
+
+    struct TreatmentPoint: Identifiable {
+        let date: Date
+        let value: Double
+        let sgv: Double
+        let label: String
+        let pillText: String
+        /// Where the symbol is drawn. Equals `date` unless `spread` nudged it
+        /// left to keep a crowded run of treatments from stacking up.
+        var drawnDate: Date
+        var id: Double { date.timeIntervalSince1970 }
+
+        init(date: Date, value: Double, sgv: Double, label: String, pillText: String) {
+            self.date = date
+            self.value = value
+            self.sgv = sgv
+            self.label = label
+            self.pillText = pillText
+            drawnDate = date
+        }
+    }
+
+    struct BasalStep: Identifiable {
+        let start: Date
+        let end: Date
+        let rate: Double
+        var id: TimeInterval { start.timeIntervalSince1970 }
+    }
+
+    struct ScheduledBasalPoint: Identifiable {
+        let date: Date
+        let rate: Double
+        var id: TimeInterval { date.timeIntervalSince1970 }
+    }
+
+    struct BandRect: Identifiable {
+        let start: Date
+        let end: Date
+        let yBottom: Double
+        let yTop: Double
+        let label: String
+        let pillText: String
+        var id: String { "\(start.timeIntervalSince1970)-\(end.timeIntervalSince1970)" }
+    }
+
+    struct ConePoint: Identifiable {
+        let date: Date
+        let yMin: Double
+        let yMax: Double
+        var id: Double { date.timeIntervalSince1970 }
+    }
+
+    /// A maximal stretch of consecutive BG readings sharing one range color.
+    /// Each run renders as a single LineMark series; runs share their boundary
+    /// point so the line stays visually continuous across color changes.
+    /// (One series per run — tens per day — instead of one per segment, which
+    /// was a Swift Charts layout hotspot at hundreds of series.)
+    struct BGRun: Identifiable {
+        let id: Int
+        let color: Color
+        let points: [BGPoint]
+    }
+
+    @Published var bg: [BGPoint] = []
+    @Published var bgRuns: [BGRun] = []
+    @Published var yesterday: [BGPoint] = []
+    @Published var prediction: [BGPoint] = []
+    @Published var ztPrediction: [BGPoint] = []
+    @Published var iobPrediction: [BGPoint] = []
+    @Published var cobPrediction: [BGPoint] = []
+    @Published var uamPrediction: [BGPoint] = []
+
+    /// Prediction cone band (min/max envelope). Set by updateOpenAPSPredictionDisplay;
+    /// preserved across rebuild() since it has no source array on the view controller.
+    /// The didSet keeps the canvas generation in sync for call sites that assign the
+    /// cone directly without triggering a rebuild.
+    @Published var cone: [ConePoint] = [] {
+        didSet { generation &+= 1 }
+    }
+
+    @Published var basal: [BasalStep] = []
+    @Published var basalScheduled: [ScheduledBasalPoint] = []
+
+    @Published var boluses: [TreatmentPoint] = []
+    @Published var carbs: [TreatmentPoint] = []
+    @Published var smbs: [TreatmentPoint] = []
+    @Published var bgChecks: [TreatmentPoint] = []
+    @Published var suspends: [TreatmentPoint] = []
+    @Published var resumes: [TreatmentPoint] = []
+    @Published var sensorStarts: [TreatmentPoint] = []
+    @Published var notes: [TreatmentPoint] = []
+
+    @Published var overrides: [BandRect] = []
+    @Published var tempTargets: [BandRect] = []
+
+    // Backend-aware band colors: Loop draws overrides green / temp targets purple,
+    // Trio (and other OpenAPS backends) use the inverse. Mirrors TreatmentGraphColors.
+    @Published var overrideColor: Color = .green
+    @Published var tempTargetColor: Color = .purple
+
+    @Published var maxBG: Double = 250
+    @Published var maxBasal: Double = 5
+    @Published var lowLine: Double = 70
+    @Published var highLine: Double = 180
+    @Published var domainStart: Date = .init(timeIntervalSince1970: 0)
+    @Published var domainEnd: Date = .init(timeIntervalSince1970: 0)
+
+    @Published var now: Date = .init()
+    @Published var diaMarkers: [Date] = []
+    @Published var midnightMarkers: [Date] = []
+    @Published var thirtyMinMark: Date? = nil
+    @Published var ninetyMinMark: Date? = nil
+
+    /// Shared pan/zoom/follow state (see BGChartInteraction). A separate object so
+    /// per-frame gesture writes don't invalidate views that only observe the data.
+    let interaction = BGChartInteraction()
+
+    /// Monotonic data version. Bumped whenever chart data changes; the chart
+    /// canvases use it (instead of comparing arrays) to decide whether a
+    /// re-layout is needed, so panning — which changes none of the data — can
+    /// provably skip their bodies.
+    private(set) var generation: Int = 0
+
+    private var rebuildScheduled = false
+
+    @Published var showLines: Bool = true
+    @Published var showDots: Bool = true
+    @Published var showDIA: Bool = true
+    @Published var show30Min: Bool = false
+    @Published var show90Min: Bool = false
+    @Published var showMidnight: Bool = false
+
+    private static let doseFormatter: NumberFormatter = {
+        let nf = NumberFormatter()
+        nf.locale = .current
+        nf.numberStyle = .decimal
+        nf.usesGroupingSeparator = false
+        nf.minimumIntegerDigits = 0
+        nf.minimumFractionDigits = 0
+        nf.maximumFractionDigits = 2
+        return nf
+    }()
+
+    private func formatDose(_ value: Double) -> String {
+        Self.doseFormatter.string(from: NSNumber(value: value)) ?? String(value)
+    }
+
+    /// Formatter for the time line at the bottom of every selection pill.
+    /// Recreated on each rebuild so 12/24-hour and graph-time-zone settings apply.
+    private var pillTimeFormatter = BGChartModel.makePillTimeFormatter()
+
+    private static func makePillTimeFormatter() -> DateFormatter {
+        let df = DateFormatter()
+        df.setLocalizedDateFormatFromTemplate(dateTimeUtils.is24Hour() ? "HH:mm" : "hh:mm")
+        if Storage.shared.graphTimeZoneEnabled.value,
+           let tz = TimeZone(identifier: Storage.shared.graphTimeZoneIdentifier.value)
+        {
+            df.timeZone = tz
+        }
+        return df
+    }
+
+    /// The pill's time line for a given point in time.
+    func pillTimeString(for date: Date) -> String {
+        pillTimeFormatter.string(from: date)
+    }
+
+    /// Nightscout remote-command error notes embed a JSON payload after
+    /// the human-readable message ("Error text {\"bolus-entry\": 1.5, ...}").
+    /// Returns the message plus a compact summary of the payload, or nil when
+    /// the note contains no JSON.
+    private static func extractMessage(from note: String) -> String? {
+        guard let jsonStartIndex = note.range(of: "{\"")?.lowerBound else {
+            return nil
+        }
+
+        let errorMessage = String(note[..<jsonStartIndex])
+            .trimmingCharacters(in: .whitespacesAndNewlines)
+
+        var actionContext = ""
+        if let jsonData = String(note[jsonStartIndex...]).data(using: .utf8),
+           let json = try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any]
+        {
+            var actionParts: [String] = []
+            if let bolusAmount = json["bolus-entry"] as? Double {
+                actionParts.append("Bolus: \(bolusAmount) U")
+            }
+            if let carbsAmount = json["carbs-entry"] as? Double {
+                actionParts.append("Carbs: \(carbsAmount) g")
+            }
+            if let absorptionTime = json["absorption-time"] as? Double {
+                actionParts.append("Absorption: \(absorptionTime) hrs")
+            }
+            if let otp = json["otp"] as? String {
+                actionParts.append("OTP: \(otp)")
+            }
+            if let enteredBy = json["entered-by"] as? String {
+                actionParts.append("From: \(enteredBy)")
+            }
+            if !actionParts.isEmpty {
+                actionContext = " [" + actionParts.joined(separator: ", ") + "]"
+            }
+        }
+
+        let finalMessage = errorMessage + actionContext
+        return finalMessage.isEmpty ? nil : finalMessage
+    }
+
+    private func colorFor(_ sgv: Int, thresholds: (low: Double, high: Double)) -> Color {
+        if Double(sgv) >= thresholds.high {
+            return .yellow
+        } else if Double(sgv) <= thresholds.low {
+            return .red
+        } else {
+            return .green
+        }
+    }
+
+    /// Groups consecutive same-colored readings into line runs (see BGRun).
+    /// The segment between two points takes the color of the earlier point.
+    private static func makeRuns(_ points: [BGPoint]) -> [BGRun] {
+        guard let first = points.first else { return [] }
+        var runs: [BGRun] = []
+        var runColor = first.color
+        var runPoints: [BGPoint] = [first]
+        for pt in points.dropFirst() {
+            runPoints.append(pt)
+            if pt.color != runColor {
+                runs.append(BGRun(id: runs.count, color: runColor, points: runPoints))
+                runPoints = [pt]
+                runColor = pt.color
+            }
+        }
+        if runPoints.count > 1 {
+            runs.append(BGRun(id: runs.count, color: runColor, points: runPoints))
+        }
+        return runs
+    }
+
+    /// Minimum drawn spacing between two treatments of the same population, and
+    /// the furthest a treatment may be moved from its true time to reach it.
+    /// Boluses and SMBs share a y-anchor and symbol footprint, so they are
+    /// decluttered as one population; carbs carry a wider "30 3h" label, so
+    /// they need — and are allowed — more room.
+    private enum Spread {
+        static let bolusGap: TimeInterval = 240
+        static let bolusShift: TimeInterval = 240
+        static let carbGap: TimeInterval = 250
+        static let carbShift: TimeInterval = 250
+    }
+
+    /// Nudges crowded treatments left so their symbols don't stack. The newest
+    /// point in a run keeps its true time and earlier ones give way, never by
+    /// more than `maxShift` — so a treatment is at most `maxShift` from where it
+    /// really happened, and an isolated one never moves at all.
+    private static func spread(_ points: [TreatmentPoint], minGap: TimeInterval, maxShift: TimeInterval) -> [TreatmentPoint] {
+        var out = points.sorted { $0.date < $1.date }
+        spreadSorted(&out, minGap: minGap, maxShift: maxShift)
+        return out
+    }
+
+    /// Spreads two treatment kinds as a single population — a bolus dot and an
+    /// SMB triangle drawn at the same minute overlap just like two dots would —
+    /// then hands each kind back its own points.
+    private static func spreadTogether(_ first: [TreatmentPoint], _ second: [TreatmentPoint], minGap: TimeInterval, maxShift: TimeInterval) -> ([TreatmentPoint], [TreatmentPoint]) {
+        let tagged = (first.map { (isFirst: true, point: $0) } + second.map { (isFirst: false, point: $0) })
+            .sorted { $0.point.date < $1.point.date }
+        var points = tagged.map(\.point)
+        spreadSorted(&points, minGap: minGap, maxShift: maxShift)
+        var outFirst: [TreatmentPoint] = []
+        var outSecond: [TreatmentPoint] = []
+        for (tag, point) in zip(tagged, points) {
+            if tag.isFirst {
+                outFirst.append(point)
+            } else {
+                outSecond.append(point)
+            }
+        }
+        return (outFirst, outSecond)
+    }
+
+    /// `points` must be sorted ascending by `date`.
+    private static func spreadSorted(_ out: inout [TreatmentPoint], minGap: TimeInterval, maxShift: TimeInterval) {
+        guard out.count > 1 else { return }
+
+        // Walking left from the newest point, each point yields to its right
+        // neighbor until it hits its own left bound (`date - maxShift`).
+        var clamped = [Bool](repeating: false, count: out.count)
+        for i in stride(from: out.count - 2, through: 0, by: -1) {
+            let wanted = out[i + 1].drawnDate.addingTimeInterval(-minGap)
+            guard out[i].drawnDate > wanted else { continue }
+            let leftBound = out[i].date.addingTimeInterval(-maxShift)
+            if wanted <= leftBound {
+                out[i].drawnDate = leftBound
+                clamped[i] = true
+            } else {
+                out[i].drawnDate = wanted
+            }
+        }
+
+        // A chain of clamped points was squeezed against its left bound and may
+        // have piled up there (several same-time treatments all land at
+        // date - maxShift). Re-space each chain evenly between that bound and
+        // the first point to its right that still had room.
+        var i = 0
+        while i < out.count - 1 {
+            guard clamped[i] else {
+                i += 1
+                continue
+            }
+            var last = i
+            while clamped[last + 1] {
+                last += 1
+            }
+            let anchorIndex = last + 1
+            let anchor = out[anchorIndex].drawnDate
+            let leftBound = out[i].date.addingTimeInterval(-maxShift)
+            let spacing = anchor.timeIntervalSince(leftBound) / Double(anchorIndex - i)
+            for k in i ... last {
+                let ideal = anchor.addingTimeInterval(-spacing * Double(anchorIndex - k))
+                let boundK = out[k].date.addingTimeInterval(-maxShift)
+                out[k].drawnDate = min(max(ideal, boundK), out[k].date)
+            }
+            i = anchorIndex + 1
+        }
+    }
+
+    /// Schedules a rebuild, coalescing bursts: a refresh cycle calls a dozen
+    /// update*Graph() entry points back-to-back, and rebuilding once per
+    /// runloop turn is enough.
+    func rebuild() {
+        guard !rebuildScheduled else {
+            return
+        }
+        rebuildScheduled = true
+        DispatchQueue.main.async { [weak self] in
+            guard let self else { return }
+            self.rebuildScheduled = false
+            self.performRebuild()
+        }
+    }
+
+    private func performRebuild() {
+        guard let vc = MainViewController.shared else { return }
+
+        pillTimeFormatter = Self.makePillTimeFormatter()
+
+        let maxBGValue = Double(vc.calculateMaxBgGraphValue())
+        maxBG = max(maxBGValue, Storage.shared.minBGScale.value)
+
+        // Same thresholds the stats and main header use: fixed 70–180 / 70–140
+        // for the TIR/TITR range modes, the user's lines for custom mode.
+        let thresholds = UnitSettingsStore.shared.effectiveThresholds()
+        lowLine = thresholds.low
+        highLine = thresholds.high
+
+        showLines = Storage.shared.showLines.value
+        showDots = Storage.shared.showDots.value
+        showDIA = Storage.shared.showDIALines.value
+        show30Min = Storage.shared.show30MinLine.value
+        show90Min = Storage.shared.show90MinLine.value
+        showMidnight = Storage.shared.showMidnightLines.value
+
+        let isLoop = Storage.shared.device.value == "Loop"
+        overrideColor = isLoop ? .green : .purple
+        tempTargetColor = isLoop ? .purple : .green
+
+        // Clamp plotted BG to the display range (see #600); color is still
+        // keyed off the true reading.
+        let minDisplay = globalVariables.minDisplayGlucose
+        let maxDisplay = globalVariables.maxDisplayGlucose
+        func clampSgv(_ sgv: Int) -> Double { Double(min(max(sgv, minDisplay), maxDisplay)) }
+
+        bg = vc.bgData.map { BGPoint(date: Date(timeIntervalSince1970: $0.date), value: clampSgv($0.sgv), color: colorFor($0.sgv, thresholds: thresholds)) }
+        bgRuns = Self.makeRuns(bg)
+
+        // Yesterday comparison overlay (#665): already +24h shifted, dimmed gray, no dots.
+        if Storage.shared.showYesterdayLine.value {
+            yesterday = vc.yesterdayBGData.map {
+                BGPoint(date: Date(timeIntervalSince1970: $0.date), value: clampSgv($0.sgv), color: Color(.systemGray).opacity(0.4))
+            }
+        } else {
+            yesterday = []
+        }
+
+        prediction = vc.predictionData.map { BGPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), color: .purple) }
+        ztPrediction = vc.ztPredictionData.map { BGPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), color: .purple) }
+        iobPrediction = vc.iobPredictionData.map { BGPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), color: .purple) }
+        cobPrediction = vc.cobPredictionData.map { BGPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), color: .purple) }
+        uamPrediction = vc.uamPredictionData.map { BGPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), color: .purple) }
+
+        let bolusPoints = vc.bolusData.map {
+            let dose = self.formatDose($0.value)
+            return TreatmentPoint(
+                date: Date(timeIntervalSince1970: $0.date),
+                value: $0.value,
+                sgv: Double($0.sgv),
+                label: dose,
+                pillText: "Bolus\n\(dose)U\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))"
+            )
+        }
+        carbs = Self.spread(vc.carbData.map {
+            let grams = Int($0.value)
+            var label = "\(grams)"
+            if $0.absorptionTime > 0, Storage.shared.showAbsorption.value {
+                label += " \($0.absorptionTime / 60)h"
+            }
+            return TreatmentPoint(
+                date: Date(timeIntervalSince1970: $0.date),
+                value: $0.value,
+                sgv: Double($0.sgv),
+                label: label,
+                pillText: "Carbs\n\(grams)g\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))"
+            )
+        }, minGap: Spread.carbGap, maxShift: Spread.carbShift)
+        let smbPoints = vc.smbData.map {
+            let dose = self.formatDose($0.value)
+            return TreatmentPoint(
+                date: Date(timeIntervalSince1970: $0.date),
+                value: $0.value,
+                sgv: Double($0.sgv),
+                label: dose,
+                pillText: "SMB\n\(dose)U\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))"
+            )
+        }
+        (boluses, smbs) = Self.spreadTogether(bolusPoints, smbPoints, minGap: Spread.bolusGap, maxShift: Spread.bolusShift)
+        bgChecks = vc.bgCheckData.map {
+            TreatmentPoint(
+                date: Date(timeIntervalSince1970: $0.date),
+                value: Double($0.sgv),
+                sgv: Double($0.sgv),
+                label: "",
+                pillText: "BG Check\n\(Localizer.toDisplayUnits(String($0.sgv)))\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))"
+            )
+        }
+        suspends = vc.suspendGraphData.map {
+            TreatmentPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), sgv: Double($0.sgv), label: "", pillText: "Suspend\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))")
+        }
+        resumes = vc.resumeGraphData.map {
+            TreatmentPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), sgv: Double($0.sgv), label: "", pillText: "Resume\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))")
+        }
+        sensorStarts = vc.sensorStartGraphData.map {
+            TreatmentPoint(date: Date(timeIntervalSince1970: $0.date), value: Double($0.sgv), sgv: Double($0.sgv), label: "", pillText: "Sensor Start\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))")
+        }
+        notes = vc.noteGraphData.map {
+            TreatmentPoint(
+                date: Date(timeIntervalSince1970: $0.date),
+                value: Double($0.sgv),
+                sgv: Double($0.sgv),
+                label: $0.note,
+                pillText: "\(Self.extractMessage(from: $0.note) ?? $0.note)\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))"
+            )
+        }
+
+        basalScheduled = vc.basalScheduleData.map {
+            ScheduledBasalPoint(date: Date(timeIntervalSince1970: $0.date), rate: $0.basalRate)
+        }
+
+        var steps: [BasalStep] = []
+        let sortedBasal = vc.basalData.sorted { $0.date < $1.date }
+        for i in 0 ..< sortedBasal.count {
+            let start = sortedBasal[i].date
+            let end = i + 1 < sortedBasal.count
+                ? sortedBasal[i + 1].date
+                : dateTimeUtils.getNowTimeIntervalUTC()
+            guard end > start else { continue }
+            steps.append(BasalStep(
+                start: Date(timeIntervalSince1970: start),
+                end: Date(timeIntervalSince1970: end),
+                rate: sortedBasal[i].basalRate
+            ))
+        }
+        basal = steps
+        let computedMaxBasal = steps.map(\.rate).max() ?? 0
+        maxBasal = max(computedMaxBasal, Storage.shared.minBasalScale.value)
+
+        let yTop = maxBG - 5
+        let yBottom = maxBG - 25
+        overrides = vc.overrideGraphData.map {
+            let overrideName = $0.reason.trimmingCharacters(in: .whitespacesAndNewlines)
+            let displayName = overrideName.isEmpty ? "Override" : overrideName
+            return BandRect(
+                start: Date(timeIntervalSince1970: $0.date),
+                end: Date(timeIntervalSince1970: $0.endDate),
+                yBottom: yBottom,
+                yTop: yTop,
+                label: displayName,
+                pillText: "Override\n\(displayName)\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))"
+            )
+        }
+        tempTargets = vc.tempTargetGraphData.map {
+            let target = $0.correctionRange.first.map { String($0) } ?? ""
+            return BandRect(
+                start: Date(timeIntervalSince1970: $0.date),
+                end: Date(timeIntervalSince1970: $0.endDate),
+                yBottom: yBottom,
+                yTop: yTop,
+                label: "Temp Target",
+                pillText: "Temp Target\n\(Localizer.toDisplayUnits(target))\n\(pillTimeString(for: Date(timeIntervalSince1970: $0.date)))"
+            )
+        }
+
+        let currentNow = Date(timeIntervalSince1970: dateTimeUtils.getNowTimeIntervalUTC())
+        now = currentNow
+        let hoursBack = TimeInterval(Storage.shared.downloadDays.value * 24 * 3600)
+        domainStart = currentNow.addingTimeInterval(-hoursBack)
+        // Everything drawn in the future (predictions, cone, override/temp-target
+        // bands) is bounded by the "Hours of Prediction" setting, so the scale
+        // domain ends there too. The 15-minute floor keeps room for follow
+        // mode's right-side padding when predictions are set to 0 (and matches
+        // the floor Overrides.swift uses for future bands).
+        let hoursForward = max(Storage.shared.predictionToLoad.value, 0.25) * 3600
+        domainEnd = currentNow.addingTimeInterval(hoursForward)
+
+        // 30/90 min lookback markers
+        thirtyMinMark = currentNow.addingTimeInterval(-1800)
+        ninetyMinMark = currentNow.addingTimeInterval(-5400)
+
+        // DIA markers: every hour going back for 6 hours
+        var dia: [Date] = []
+        for i in 1 ... 6 {
+            dia.append(currentNow.addingTimeInterval(TimeInterval(-i * 3600)))
+        }
+        diaMarkers = dia
+
+        // Midnight markers: every local midnight within domain
+        var midnights: [Date] = []
+        let calendar: Calendar = {
+            var cal = Calendar(identifier: .gregorian)
+            if Storage.shared.graphTimeZoneEnabled.value,
+               let tz = TimeZone(identifier: Storage.shared.graphTimeZoneIdentifier.value)
+            {
+                cal.timeZone = tz
+            }
+            return cal
+        }()
+        var cursor = calendar.startOfDay(for: domainStart)
+        while cursor <= domainEnd {
+            if cursor >= domainStart {
+                midnights.append(cursor)
+            }
+            guard let next = calendar.date(byAdding: .day, value: 1, to: cursor) else { break }
+            cursor = next
+        }
+        midnightMarkers = midnights
+
+        generation &+= 1
+    }
+}

+ 190 - 0
LoopFollow/Charts/BGChartStubs.swift

@@ -0,0 +1,190 @@
+// LoopFollow
+// BGChartStubs.swift
+
+import Foundation
+import SwiftUI
+import UIKit
+
+/// The `update*Graph()` / `createGraph()` entry points the rest of the app
+/// calls to refresh the chart. Rendering happens in BGChartModel +
+/// BGChartView (Apple Swift Charts); these update lightweight state
+/// (topBG / topPredictionBG / prediction arrays) and trigger a (coalesced)
+/// model rebuild.
+extension MainViewController {
+    func createGraph() {
+        chartModel.rebuild()
+        // The chart's follow/auto-return logic runs off model.now, so arm the
+        // once-a-minute "now" tick.
+        startGraphNowTimer()
+    }
+
+    func createSmallBGGraph() {}
+
+    func updateBGGraphSettings() {
+        chartModel.rebuild()
+    }
+
+    private func recomputeTopBG() {
+        let maxBGOffset: Double = 50
+        topBG = Storage.shared.minBGScale.value
+        for entry in bgData {
+            if Double(entry.sgv) > topBG - maxBGOffset {
+                topBG = Double(entry.sgv) + maxBGOffset
+            }
+        }
+    }
+
+    private func recomputeTopPredictionBG() {
+        let maxBGOffset: Double = 20
+        topPredictionBG = Storage.shared.minBGScale.value
+        let allPredictions = predictionData + ztPredictionData + iobPredictionData + cobPredictionData + uamPredictionData
+        for entry in allPredictions {
+            let v = Double(entry.sgv)
+            if v > topPredictionBG - maxBGOffset {
+                topPredictionBG = v + maxBGOffset
+            }
+        }
+    }
+
+    func updateBGGraph() {
+        recomputeTopBG()
+        // Profile processing defers building the scheduled-basal segments until
+        // the first BG render has happened (Profile.swift checks firstGraphLoad).
+        // Clear the flag here or the scheduled basal line never gets data.
+        if !bgData.isEmpty {
+            firstGraphLoad = false
+        }
+        chartModel.rebuild()
+    }
+
+    func updatePredictionGraph(color _: UIColor? = nil) {
+        recomputeTopPredictionBG()
+        chartModel.rebuild()
+    }
+
+    func updatePredictionGraphGeneric(
+        dataIndex: Int,
+        predictionData: [ShareGlucoseData],
+        chartLabel _: String,
+        color _: UIColor
+    ) {
+        switch dataIndex {
+        case 12: ztPredictionData = predictionData
+        case 13: iobPredictionData = predictionData
+        case 14: cobPredictionData = predictionData
+        case 15: uamPredictionData = predictionData
+        default: break
+        }
+        recomputeTopPredictionBG()
+        chartModel.rebuild()
+    }
+
+    // Removes the Loop forecast line. Used when the active system switches away from Loop.
+    func clearLoopPredictionGraph() {
+        guard !predictionData.isEmpty else { return }
+        predictionData.removeAll()
+        updatePredictionGraph()
+    }
+
+    // Removes the Trio/OpenAPS forecast (ZT/IOB/COB/UAM lines and the cone). Used when the active system switches away from Trio/OpenAPS.
+    func clearOpenAPSPredictionGraph() {
+        let hasLineData = !ztPredictionData.isEmpty || !iobPredictionData.isEmpty || !cobPredictionData.isEmpty || !uamPredictionData.isEmpty
+        guard hasLineData || !chartModel.cone.isEmpty else { return }
+        ztPredictionData = []
+        iobPredictionData = []
+        cobPredictionData = []
+        uamPredictionData = []
+        chartModel.cone = []
+        recomputeTopPredictionBG()
+        chartModel.rebuild()
+    }
+
+    // Routes OpenAPS/Trio predictions either into a cone band or individual
+    // prediction lines. Cone is only for OpenAPS-based backends; Loop always
+    // uses lines.
+    func updateOpenAPSPredictionDisplay() {
+        guard let predBGs = openAPSPredBGs else {
+            chartModel.cone = []
+            return
+        }
+
+        let displayType: PredictionDisplayType = Storage.shared.device.value == "Loop"
+            ? .lines
+            : Storage.shared.predictionDisplayType.value
+        let toLoad = Int(Storage.shared.predictionToLoad.value * 12)
+        let predictionStart = openAPSPredUpdatedTime ?? Date().timeIntervalSince1970
+        let types = ["ZT", "IOB", "COB", "UAM"]
+        let minDisplay = globalVariables.minDisplayGlucose
+        let maxDisplay = globalVariables.maxDisplayGlucose
+
+        topPredictionBG = Storage.shared.minBGScale.value
+
+        if displayType == .cone {
+            // Clear individual prediction lines.
+            ztPredictionData = []
+            iobPredictionData = []
+            cobPredictionData = []
+            uamPredictionData = []
+
+            let allArrays = types.compactMap { predBGs[$0] }.filter { !$0.isEmpty }
+            var coneData: [BGChartModel.ConePoint] = []
+            if !allArrays.isEmpty {
+                // Cap at the shortest predBG array length so every cone point uses
+                // the same set of contributing arrays. Matches Trio's ForecastSetup.
+                let coneLength = min(allArrays.map { $0.count }.min()!, toLoad + 1)
+                var t = predictionStart
+                for i in 0 ..< coneLength {
+                    let valuesAtIndex = allArrays.compactMap { i < $0.count ? $0[i] : nil }
+                    if !valuesAtIndex.isEmpty {
+                        var yMin = max(valuesAtIndex.min()!, Double(minDisplay))
+                        var yMax = min(valuesAtIndex.max()!, Double(maxDisplay))
+                        // Keep a minimum ±1 mg/dL band so the cone stays visible when predictions agree.
+                        if yMin == yMax {
+                            yMin -= 1
+                            yMax += 1
+                        }
+                        coneData.append(BGChartModel.ConePoint(
+                            date: Date(timeIntervalSince1970: t),
+                            yMin: yMin,
+                            yMax: yMax
+                        ))
+                        if yMax > topPredictionBG - 20 { topPredictionBG = yMax + 20 }
+                    }
+                    t += 300
+                }
+            }
+            chartModel.cone = coneData
+        } else {
+            chartModel.cone = []
+
+            // dataIndex mapping matches updatePredictionGraphGeneric: 12=ZT 13=IOB 14=COB 15=UAM
+            for (offset, type) in types.enumerated() {
+                var predictionData: [ShareGlucoseData] = []
+                if let graphData = predBGs[type] {
+                    var t = predictionStart
+                    for i in 0 ... toLoad where i < graphData.count {
+                        let clamped = min(max(Int(round(graphData[i])), minDisplay), maxDisplay)
+                        predictionData.append(ShareGlucoseData(sgv: clamped, date: t, direction: "flat"))
+                        t += 300
+                    }
+                }
+                updatePredictionGraphGeneric(dataIndex: 12 + offset, predictionData: predictionData, chartLabel: type, color: .clear)
+            }
+        }
+
+        chartModel.rebuild()
+    }
+
+    func updateBasalGraph() { chartModel.rebuild() }
+    func updateBolusGraph() { chartModel.rebuild() }
+    func updateCarbGraph() { chartModel.rebuild() }
+    func updateBasalScheduledGraph() { chartModel.rebuild() }
+    func updateOverrideGraph() { chartModel.rebuild() }
+    func updateBGCheckGraph() { chartModel.rebuild() }
+    func updateSuspendGraph() { chartModel.rebuild() }
+    func updateResumeGraph() { chartModel.rebuild() }
+    func updateSensorStart() { chartModel.rebuild() }
+    func updateNotes() { chartModel.rebuild() }
+    func updateSmbGraph() { chartModel.rebuild() }
+    func updateTempTargetGraph() { chartModel.rebuild() }
+}

Разница между файлами не показана из-за своего большого размера
+ 1598 - 0
LoopFollow/Charts/BGChartView.swift


Разница между файлами не показана из-за своего большого размера
+ 0 - 2206
LoopFollow/Controllers/Graphs.swift


+ 0 - 2
LoopFollow/Controllers/NightScout.swift

@@ -59,7 +59,6 @@ extension MainViewController {
     func clearOldSmb() {
         smbData.removeAll()
         updateSmbGraph()
-        updateChartRenderers()
     }
 
     func clearOldCarb() {
@@ -80,7 +79,6 @@ extension MainViewController {
     func clearOldTempTarget() {
         tempTargetGraphData.removeAll()
         updateTempTargetGraph()
-        updateChartRenderers()
     }
 
     func clearOldSuspend() {

+ 6 - 1
LoopFollow/Controllers/Nightscout/Treatments/Overrides.swift

@@ -69,7 +69,12 @@ extension MainViewController {
                     return [lo, hi]
                 }(),
                 enteredBy: e["enteredBy"] as? String ?? "unknown",
-                reason: e["reason"] as? String ?? "",
+                // Loop stores the override name in "reason"; Trio stores it in
+                // "notes". Prefer notes so Trio override names surface on the
+                // graph, matching the info table and treatments list.
+                reason: (e["notes"] as? String)?.trimmingCharacters(in: .whitespacesAndNewlines)
+                    ?? (e["reason"] as? String)?.trimmingCharacters(in: .whitespacesAndNewlines)
+                    ?? "",
                 sgv: -20
             )
             overrideGraphData.append(dot)

+ 0 - 1
LoopFollow/Controllers/Nightscout/Treatments/SMB.swift

@@ -35,7 +35,6 @@ extension MainViewController {
 
         if Storage.shared.graphBolus.value {
             updateSmbGraph()
-            updateChartRenderers()
         }
     }
 }

+ 0 - 1
LoopFollow/Controllers/Nightscout/Treatments/TemporaryTarget.swift

@@ -64,7 +64,6 @@ extension MainViewController {
 
         if Storage.shared.graphOtherTreatments.value {
             updateTempTargetGraph()
-            updateChartRenderers()
         }
 
         if let target = activeTempTarget {

+ 20 - 25
LoopFollow/Controllers/StatsDisplayView.swift

@@ -15,7 +15,8 @@ struct StatsDisplayView: View {
                 pieRange: model.pieRange,
                 pieHigh: model.pieHigh
             )
-            .frame(width: 100, height: 100)
+            .frame(width: 80, height: 80)
+            .padding(.leading, 8)
 
             VStack(spacing: 10) {
                 HStack {
@@ -48,37 +49,31 @@ struct StatsDisplayView: View {
     }
 }
 
-struct StatsPieChartView: UIViewRepresentable {
+struct StatsPieChartView: View {
     var pieLow: Double
     var pieRange: Double
     var pieHigh: Double
 
-    func makeUIView(context _: Context) -> PieChartView {
-        let chart = PieChartView()
-        chart.legend.enabled = false
-        chart.drawEntryLabelsEnabled = false
-        chart.drawHoleEnabled = false
-        chart.rotationEnabled = false
-        chart.isUserInteractionEnabled = false
-        chart.backgroundColor = .clear
-        return chart
+    private struct Slice: Identifiable {
+        let id: String
+        let value: Double
+        let color: Color
     }
 
-    func updateUIView(_ chart: PieChartView, context _: Context) {
-        let entries = [
-            PieChartDataEntry(value: max(pieLow, 0.1)),
-            PieChartDataEntry(value: max(pieRange, 0.1)),
-            PieChartDataEntry(value: max(pieHigh, 0.1)),
+    private var slices: [Slice] {
+        [
+            Slice(id: "low", value: max(pieLow, 0.1), color: .red),
+            Slice(id: "range", value: max(pieRange, 0.1), color: .green),
+            Slice(id: "high", value: max(pieHigh, 0.1), color: .yellow),
         ]
+    }
 
-        let dataSet = PieChartDataSet(entries: entries, label: "")
-        dataSet.drawIconsEnabled = false
-        dataSet.sliceSpace = 0
-        dataSet.drawValuesEnabled = false
-        dataSet.valueLineWidth = 0
-        dataSet.formLineWidth = 0
-        dataSet.colors = [.systemRed, .systemGreen, .systemYellow]
-
-        chart.data = PieChartData(dataSet: dataSet)
+    var body: some View {
+        Chart(slices) { slice in
+            SectorMark(angle: .value("share", slice.value))
+                .foregroundStyle(slice.color)
+        }
+        .chartLegend(.hidden)
+        .allowsHitTesting(false)
     }
 }

+ 2 - 1
LoopFollow/Controllers/Timers.swift

@@ -6,6 +6,7 @@ import UIKit
 
 extension MainViewController {
     func startGraphNowTimer(time: TimeInterval = 60) {
+        graphNowTimer.invalidate()
         graphNowTimer = Timer.scheduledTimer(timeInterval: time,
                                              target: self,
                                              selector: #selector(MainViewController.graphNowTimerDidEnd(_:)),
@@ -14,6 +15,6 @@ extension MainViewController {
     }
 
     @objc func graphNowTimerDidEnd(_: Timer) {
-        createVerticalLines()
+        chartModel.rebuild()
     }
 }

+ 0 - 216
LoopFollow/Helpers/Chart.swift

@@ -1,216 +0,0 @@
-// LoopFollow
-// Chart.swift
-
-import Charts
-import Foundation
-
-final class OverrideFillFormatter: FillFormatter {
-    func getFillLinePosition(dataSet: Charts.LineChartDataSetProtocol, dataProvider _: Charts.LineChartDataProvider) -> CGFloat {
-        return CGFloat(dataSet.entryForIndex(0)!.y)
-        // return 375
-    }
-}
-
-final class basalFillFormatter: FillFormatter {
-    func getFillLinePosition(dataSet _: Charts.LineChartDataSetProtocol, dataProvider _: Charts.LineChartDataProvider) -> CGFloat {
-        return 0
-    }
-}
-
-final class ChartXValueFormatter: AxisValueFormatter {
-    func stringForValue(_ value: Double, axis _: AxisBase?) -> String {
-        let dateFormatter = DateFormatter()
-        // let timezoneOffset = TimeZone.current.secondsFromGMT()
-        // let epochTimezoneOffset = value + Double(timezoneOffset)
-        if dateTimeUtils.is24Hour() {
-            dateFormatter.setLocalizedDateFormatFromTemplate("HH:mm")
-        } else {
-            dateFormatter.setLocalizedDateFormatFromTemplate("hh:mm")
-        }
-
-        if Storage.shared.graphTimeZoneEnabled.value,
-           let tz = TimeZone(identifier: Storage.shared.graphTimeZoneIdentifier.value)
-        {
-            dateFormatter.timeZone = tz
-        }
-
-        // let date = Date(timeIntervalSince1970: epochTimezoneOffset)
-        let date = Date(timeIntervalSince1970: value)
-        let formattedDate = dateFormatter.string(from: date)
-
-        return formattedDate
-    }
-}
-
-final class ChartYDataValueFormatter: ValueFormatter {
-    func stringForValue(_: Double, entry: ChartDataEntry, dataSetIndex _: Int, viewPortHandler _: ViewPortHandler?) -> String {
-        guard let text = entry.data as? String else { return "" }
-        // Treatment entries store "label\r\rpillText" — extract only the label portion.
-        if let range = text.range(of: "\r\r") {
-            return String(text[..<range.lowerBound])
-        }
-        return text
-    }
-}
-
-final class ChartYOverrideValueFormatter: ValueFormatter {
-    func stringForValue(_: Double, entry: ChartDataEntry, dataSetIndex _: Int, viewPortHandler _: ViewPortHandler?) -> String {
-        if entry.data != nil {
-            return entry.data as? String ?? ""
-        } else {
-            return ""
-        }
-    }
-}
-
-final class ChartYMMOLValueFormatter: AxisValueFormatter {
-    func stringForValue(_ value: Double, axis _: AxisBase?) -> String {
-        return Localizer.toDisplayUnits(String(value))
-    }
-}
-
-class PillMarker: MarkerImage {
-    private(set) var color: UIColor
-    private(set) var font: UIFont
-    private(set) var textColor: UIColor
-    private var labelText: String = ""
-    private var attrs: [NSAttributedString.Key: AnyObject]!
-
-    static let formatter: DateComponentsFormatter = {
-        let f = DateComponentsFormatter()
-        f.allowedUnits = [.minute, .second]
-        f.unitsStyle = .short
-        return f
-    }()
-
-    init(color: UIColor, font: UIFont, textColor: UIColor) {
-        self.color = color
-        self.font = font
-        self.textColor = textColor
-
-        let paragraphStyle = NSMutableParagraphStyle()
-        paragraphStyle.alignment = .center
-        attrs = [.font: font, .paragraphStyle: paragraphStyle, .foregroundColor: textColor, .baselineOffset: NSNumber(value: -4)]
-        super.init()
-    }
-
-    override func draw(context: CGContext, point: CGPoint) {
-        // custom padding around text
-        let labelWidth = labelText.size(withAttributes: attrs).width + 10
-        // if you modify labelHeigh you will have to tweak baselineOffset in attrs
-        let labelHeight = labelText.size(withAttributes: attrs).height + 4
-
-        // place pill above the marker, centered along x
-        var rectangle = CGRect(x: point.x, y: point.y, width: labelWidth, height: labelHeight)
-        rectangle.origin.x -= rectangle.width / 2.0
-        var spacing: CGFloat = 20
-        if point.y < 300 { spacing = -40 }
-
-        rectangle.origin.y -= rectangle.height + spacing
-
-        // rounded rect
-        let clipPath = UIBezierPath(roundedRect: rectangle, cornerRadius: 6.0).cgPath
-        context.addPath(clipPath)
-        context.setFillColor(UIColor.secondarySystemBackground.cgColor)
-        context.setStrokeColor(UIColor.label.cgColor)
-        context.closePath()
-        context.drawPath(using: .fillStroke)
-
-        // add the text
-        labelText.draw(with: rectangle, options: .usesLineFragmentOrigin, attributes: attrs, context: nil)
-    }
-
-    private static let pillSeparator = "\r\r"
-
-    override func refreshContent(entry: ChartDataEntry, highlight _: Highlight) {
-        if let text = entry.data as? String {
-            // Treatment entries use pillSeparator to separate the value label from the marker text.
-            if let range = text.range(of: Self.pillSeparator) {
-                labelText = String(text[range.upperBound...])
-            } else {
-                labelText = text
-            }
-        } else {
-            labelText = String(entry.y)
-        }
-    }
-
-    private func customString(_ value: Double) -> String {
-        let formattedString = PillMarker.formatter.string(from: TimeInterval(value))!
-        // using this to convert the left axis values formatting, ie 2 min
-        return "\(formattedString)"
-    }
-}
-
-// MARK: - Cone of Uncertainty
-
-class ConeChartDataEntry: ChartDataEntry {
-    var yMin: Double = 0.0
-    var yMax: Double = 0.0
-
-    required init() {
-        super.init()
-    }
-
-    init(x: Double, yMin: Double, yMax: Double) {
-        self.yMin = yMin
-        self.yMax = yMax
-        super.init(x: x, y: yMax)
-    }
-
-    override func copy(with _: NSZone? = nil) -> Any {
-        let copy = ConeChartDataEntry(x: x, yMin: yMin, yMax: yMax)
-        copy.data = data
-        return copy
-    }
-}
-
-class ConeOfUncertaintyRenderer: LineChartRenderer {
-    let coneDataSetIndex: Int
-
-    init(dataProvider: LineChartDataProvider?, animator: Animator?, viewPortHandler: ViewPortHandler?, coneDataSetIndex: Int) {
-        self.coneDataSetIndex = coneDataSetIndex
-        super.init(dataProvider: dataProvider!, animator: animator!, viewPortHandler: viewPortHandler!)
-    }
-
-    override func drawExtras(context: CGContext) {
-        super.drawExtras(context: context)
-
-        guard let dataProvider = dataProvider,
-              dataProvider.lineData?.dataSets.count ?? 0 > coneDataSetIndex,
-              let lineDataSet = dataProvider.lineData?.dataSets[coneDataSetIndex] as? LineChartDataSet,
-              lineDataSet.entryCount > 1 else { return }
-
-        let trans = dataProvider.getTransformer(forAxis: lineDataSet.axisDependency)
-        let phaseY = animator.phaseY
-
-        var upperPoints = [CGPoint]()
-        var lowerPoints = [CGPoint]()
-
-        for i in 0 ..< lineDataSet.entryCount {
-            guard let entry = lineDataSet.entryForIndex(i) as? ConeChartDataEntry else { continue }
-            upperPoints.append(trans.pixelForValues(x: entry.x, y: entry.yMax * phaseY))
-            lowerPoints.append(trans.pixelForValues(x: entry.x, y: entry.yMin * phaseY))
-        }
-
-        guard upperPoints.count > 1 else { return }
-
-        context.saveGState()
-
-        let path = CGMutablePath()
-        path.move(to: upperPoints[0])
-        for i in 1 ..< upperPoints.count {
-            path.addLine(to: upperPoints[i])
-        }
-        for i in stride(from: lowerPoints.count - 1, through: 0, by: -1) {
-            path.addLine(to: lowerPoints[i])
-        }
-        path.closeSubpath()
-
-        context.addPath(path)
-        context.setFillColor(UIColor.systemBlue.withAlphaComponent(0.4).cgColor)
-        context.fillPath()
-
-        context.restoreGState()
-    }
-}

+ 0 - 28
LoopFollow/Helpers/carbBolusArrays.swift

@@ -32,32 +32,4 @@ extension MainViewController {
 
         return (false, 0)
     }
-
-    func findNextCarbTime(timeWithin: Int, needle: TimeInterval, haystack: [carbGraphStruct], startingIndex: Int) -> Bool {
-        if startingIndex > haystack.count - 2 { return false }
-        if haystack[startingIndex + 1].date - needle < Double(timeWithin) {
-            return true
-        }
-
-        return false
-    }
-
-    func findNextBolusTime(timeWithin: Int, needle: TimeInterval, haystack: [bolusGraphStruct], startingIndex: Int) -> Bool {
-        var last = false
-        var next = true
-        if startingIndex > haystack.count - 2 { return false }
-        if startingIndex == 0 { return false }
-
-        // Nothing to right that requires shift
-        if haystack[startingIndex + 1].date - needle > Double(timeWithin) {
-            return false
-        } else {
-            // Nothing to left preventing shift
-            if needle - haystack[startingIndex - 1].date > Double(timeWithin) {
-                return true
-            }
-        }
-
-        return false
-    }
 }

+ 121 - 124
LoopFollow/Stats/AGP/AGPGraphView.swift

@@ -4,141 +4,138 @@
 import Charts
 import SwiftUI
 
-struct AGPGraphView: UIViewRepresentable {
+struct AGPGraphView: View {
     let agpData: [AGPDataPoint]
 
-    func makeCoordinator() -> Coordinator {
-        Coordinator()
+    private enum Percentile: String, CaseIterable, Plottable {
+        case p5 = "5th"
+        case p25 = "25th"
+        case median = "Median"
+        case p75 = "75th"
+        case p95 = "95th"
+
+        var color: Color {
+            switch self {
+            case .p5, .p95: return Color(.systemGray).opacity(0.6)
+            case .p25, .p75: return Color(.systemBlue).opacity(0.7)
+            case .median: return Color(.systemBlue)
+            }
+        }
+
+        var lineWidth: CGFloat {
+            self == .median ? 3 : 1.5
+        }
     }
 
-    func makeUIView(context _: Context) -> UIView {
-        let containerView = NonInteractiveContainerView()
-        containerView.backgroundColor = .systemBackground
-
-        let chartView = LineChartView()
-        chartView.rightAxis.enabled = true
-        chartView.leftAxis.enabled = false
-        chartView.xAxis.labelPosition = .bottom
-        chartView.rightAxis.drawGridLinesEnabled = false
-        chartView.leftAxis.drawGridLinesEnabled = false
-        chartView.xAxis.drawGridLinesEnabled = false
-        chartView.rightAxis.valueFormatter = ChartYMMOLValueFormatter()
-        chartView.legend.enabled = false
-        chartView.chartDescription.enabled = false
-        chartView.isUserInteractionEnabled = false
-
-        containerView.addSubview(chartView)
-        chartView.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([
-            chartView.topAnchor.constraint(equalTo: containerView.topAnchor),
-            chartView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
-            chartView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
-            chartView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
-        ])
-
-        return containerView
+    private struct Point: Identifiable {
+        let percentile: Percentile
+        let hour: Double
+        let value: Double
+        var id: String { "\(percentile.rawValue)-\(hour)" }
     }
 
-    class Coordinator {}
-
-    func updateUIView(_ containerView: UIView, context _: Context) {
-        guard let chartView = containerView.subviews.first as? LineChartView else { return }
-        guard !agpData.isEmpty else { return }
-        var p5Entries: [ChartDataEntry] = []
-        var p25Entries: [ChartDataEntry] = []
-        var p50Entries: [ChartDataEntry] = []
-        var p75Entries: [ChartDataEntry] = []
-        var p95Entries: [ChartDataEntry] = []
-
-        for point in agpData {
-            let x = Double(point.timeOfDay) / 60.0
-            p5Entries.append(ChartDataEntry(x: x, y: point.p5))
-            p25Entries.append(ChartDataEntry(x: x, y: point.p25))
-            p50Entries.append(ChartDataEntry(x: x, y: point.p50))
-            p75Entries.append(ChartDataEntry(x: x, y: point.p75))
-            p95Entries.append(ChartDataEntry(x: x, y: point.p95))
+    private var points: [Point] {
+        let sortedData = agpData.sorted { $0.timeOfDay < $1.timeOfDay }
+        return sortedData.flatMap { dp -> [Point] in
+            let hour = Double(dp.timeOfDay) / 60.0
+            return [
+                Point(percentile: .p5, hour: hour, value: dp.p5),
+                Point(percentile: .p25, hour: hour, value: dp.p25),
+                Point(percentile: .median, hour: hour, value: dp.p50),
+                Point(percentile: .p75, hour: hour, value: dp.p75),
+                Point(percentile: .p95, hour: hour, value: dp.p95),
+            ]
         }
+    }
+
+    private var activeThresholds: (low: Double, high: Double) {
+        UnitSettingsStore.shared.effectiveThresholds()
+    }
+
+    private var lowThresholdLabel: String {
+        Localizer.toDisplayUnits(String(activeThresholds.low))
+    }
 
-        let sortedP5 = p5Entries.sorted { $0.x < $1.x }
-        let sortedP25 = p25Entries.sorted { $0.x < $1.x }
-        let sortedP50 = p50Entries.sorted { $0.x < $1.x }
-        let sortedP75 = p75Entries.sorted { $0.x < $1.x }
-        let sortedP95 = p95Entries.sorted { $0.x < $1.x }
+    private var highThresholdLabel: String {
+        Localizer.toDisplayUnits(String(activeThresholds.high))
+    }
+
+    private var plottedMinValue: Double {
+        min(points.map(\.value).min() ?? activeThresholds.low, activeThresholds.low)
+    }
 
-        guard !sortedP5.isEmpty, !sortedP25.isEmpty, !sortedP50.isEmpty,
-              !sortedP75.isEmpty, !sortedP95.isEmpty
-        else {
-            return
+    private var plottedMaxValue: Double {
+        max(points.map(\.value).max() ?? activeThresholds.high, activeThresholds.high)
+    }
+
+    private var yDomain: ClosedRange<Double> {
+        let span = max(plottedMaxValue - plottedMinValue, 1)
+        let topPadding = max(span * 0.05, 1)
+        return plottedMinValue ... (plottedMaxValue + topPadding)
+    }
+
+    private var yAxisEndpoints: [Double] {
+        if abs(plottedMaxValue - plottedMinValue) < 0.0001 {
+            return [plottedMinValue]
         }
-        let p5DataSet = LineChartDataSet(entries: sortedP5, label: "5th")
-        p5DataSet.colors = [NSUIColor.systemGray.withAlphaComponent(0.6)]
-        p5DataSet.lineWidth = 1.5
-        p5DataSet.drawCirclesEnabled = false
-        p5DataSet.drawValuesEnabled = false
-        p5DataSet.drawFilledEnabled = false
-        p5DataSet.mode = .linear
-
-        let p25DataSet = LineChartDataSet(entries: sortedP25, label: "25th")
-        p25DataSet.colors = [NSUIColor.systemBlue.withAlphaComponent(0.7)]
-        p25DataSet.lineWidth = 1.5
-        p25DataSet.drawCirclesEnabled = false
-        p25DataSet.drawValuesEnabled = false
-        p25DataSet.drawFilledEnabled = false
-        p25DataSet.mode = .linear
-
-        let p50DataSet = LineChartDataSet(entries: sortedP50, label: "Median")
-        p50DataSet.colors = [NSUIColor.systemBlue]
-        p50DataSet.lineWidth = 3
-        p50DataSet.drawCirclesEnabled = false
-        p50DataSet.drawValuesEnabled = false
-        p50DataSet.drawFilledEnabled = false
-        p50DataSet.mode = .linear
-
-        let p75DataSet = LineChartDataSet(entries: sortedP75, label: "75th")
-        p75DataSet.colors = [NSUIColor.systemBlue.withAlphaComponent(0.7)]
-        p75DataSet.lineWidth = 1.5
-        p75DataSet.drawCirclesEnabled = false
-        p75DataSet.drawValuesEnabled = false
-        p75DataSet.drawFilledEnabled = false
-        p75DataSet.mode = .linear
-
-        let p95DataSet = LineChartDataSet(entries: sortedP95, label: "95th")
-        p95DataSet.colors = [NSUIColor.systemGray.withAlphaComponent(0.6)]
-        p95DataSet.lineWidth = 1.5
-        p95DataSet.drawCirclesEnabled = false
-        p95DataSet.drawValuesEnabled = false
-        p95DataSet.drawFilledEnabled = false
-        p95DataSet.mode = .linear
-        let maxY = max(sortedP95.map { $0.y }.max() ?? 300, 300) + 10
-        let hourMinY = min(sortedP5.map { $0.y }.min() ?? 0, 0) - 10
-
-        var hourLines: [ChartDataEntry] = []
-        for hour in 0 ... 24 {
-            let x = Double(hour)
-            hourLines.append(ChartDataEntry(x: x, y: hourMinY))
-            hourLines.append(ChartDataEntry(x: x, y: maxY))
-            if hour < 24 {
-                hourLines.append(ChartDataEntry(x: x + 0.0001, y: hourMinY))
+        return [plottedMinValue, plottedMaxValue]
+    }
+
+    var body: some View {
+        Chart {
+            RuleMark(y: .value("lowBoundary", activeThresholds.low))
+                .lineStyle(StrokeStyle(lineWidth: 1, dash: [4, 4]))
+                .annotation(position: .leading, alignment: .leading) {
+                    Text(lowThresholdLabel)
+                        .font(.caption2)
+                }
+
+            RuleMark(y: .value("highBoundary", activeThresholds.high))
+                .lineStyle(StrokeStyle(lineWidth: 1, dash: [4, 4]))
+                .annotation(position: .leading, alignment: .leading) {
+                    Text(highThresholdLabel)
+                        .font(.caption2)
+                }
+
+            ForEach(points) { point in
+                LineMark(
+                    x: .value("hour", point.hour),
+                    y: .value("bg", point.value)
+                )
+                .foregroundStyle(by: .value("percentile", point.percentile))
+                .lineStyle(StrokeStyle(lineWidth: point.percentile.lineWidth))
+                .interpolationMethod(.linear)
             }
         }
-
-        let hourLinesDataSet = LineChartDataSet(entries: hourLines, label: "Hours")
-        hourLinesDataSet.colors = [NSUIColor.label.withAlphaComponent(0.3)]
-        hourLinesDataSet.lineWidth = 1
-        hourLinesDataSet.drawCirclesEnabled = false
-        hourLinesDataSet.drawValuesEnabled = false
-        hourLinesDataSet.drawFilledEnabled = false
-
-        let data = LineChartData()
-        data.append(p5DataSet)
-        data.append(p25DataSet)
-        data.append(p50DataSet)
-        data.append(p75DataSet)
-        data.append(p95DataSet)
-        data.append(hourLinesDataSet)
-
-        chartView.data = data
-        chartView.notifyDataSetChanged()
-        chartView.setNeedsDisplay()
+        .chartForegroundStyleScale(
+            domain: Percentile.allCases,
+            range: Percentile.allCases.map(\.color)
+        )
+        .chartLegend(.hidden)
+        .chartXScale(domain: 0 ... 24)
+        .chartYScale(domain: yDomain)
+        .chartXAxis {
+            AxisMarks(position: .bottom, values: Array(stride(from: 0, through: 24, by: 3))) { value in
+                AxisGridLine(stroke: StrokeStyle(lineWidth: 0.5))
+                    .foregroundStyle(Color(.label).opacity(0.3))
+                AxisTick()
+                AxisValueLabel {
+                    if let hour = value.as(Int.self) {
+                        Text("\(hour)")
+                    }
+                }
+            }
+        }
+        .chartYAxis {
+            AxisMarks(position: .leading, values: yAxisEndpoints) { value in
+                AxisValueLabel {
+                    if let raw = value.as(Double.self) {
+                        Text(Localizer.toDisplayUnits(String(raw)))
+                    }
+                }
+            }
+        }
+        .allowsHitTesting(false)
+        .background(Color(.systemBackground))
     }
 }

+ 3 - 1
LoopFollow/Stats/AGP/AGPView.swift

@@ -15,8 +15,10 @@ struct AGPView: View {
 
                 AGPGraphView(agpData: viewModel.agpData)
                     .frame(height: 200)
+                    .padding(.top, 10)
+                    .padding(.horizontal, 8)
+                    .padding(.bottom, 4)
                     .allowsHitTesting(false)
-                    .clipped()
 
                 // Legend
                 HStack(spacing: 16) {

+ 0 - 25
LoopFollow/Stats/ChartContainerView.swift

@@ -1,25 +0,0 @@
-// LoopFollow
-// ChartContainerView.swift
-
-import Charts
-import UIKit
-
-class NonInteractiveContainerView: UIView {
-    override init(frame: CGRect) {
-        super.init(frame: frame)
-        setup()
-    }
-
-    required init?(coder: NSCoder) {
-        super.init(coder: coder)
-        setup()
-    }
-
-    private func setup() {
-        isUserInteractionEnabled = false
-    }
-
-    override func hitTest(_: CGPoint, with _: UIEvent?) -> UIView? {
-        return nil
-    }
-}

+ 77 - 107
LoopFollow/Stats/GRI/GRIRiskGridView.swift

@@ -4,138 +4,108 @@
 import Charts
 import SwiftUI
 
-struct GRIRiskGridView: UIViewRepresentable {
+struct GRIRiskGridView: View {
     let hypoComponent: Double
     let hyperComponent: Double
     let gri: Double
 
-    func makeCoordinator() -> Coordinator {
-        Coordinator()
+    private enum Zone: String, CaseIterable, Plottable {
+        case a = "A"
+        case b = "B"
+        case c = "C"
+        case d = "D"
+        case e = "E"
+
+        var color: Color {
+            switch self {
+            case .a: return .green.opacity(0.3)
+            case .b: return .yellow.opacity(0.3)
+            case .c: return .orange.opacity(0.3)
+            case .d: return .red.opacity(0.3)
+            case .e: return .red.opacity(0.5)
+            }
+        }
     }
 
-    func makeUIView(context _: Context) -> UIView {
-        let containerView = NonInteractiveContainerView()
-        containerView.backgroundColor = .systemBackground
-
-        let chartView = ScatterChartView()
-        chartView.backgroundColor = .systemBackground
-        chartView.rightAxis.enabled = false
-        chartView.leftAxis.enabled = true
-        chartView.legend.enabled = false
-        chartView.chartDescription.enabled = false
-        chartView.leftAxis.axisMinimum = 0
-        chartView.leftAxis.axisMaximum = 60
-        chartView.leftAxis.forceLabelsEnabled = true
-        chartView.leftAxis.labelPosition = .outsideChart
-        chartView.rightAxis.enabled = false
-        chartView.xAxis.labelPosition = .bottom
-        chartView.xAxis.axisMinimum = 0
-        chartView.xAxis.axisMaximum = 30
-        chartView.isUserInteractionEnabled = false
-
-        containerView.addSubview(chartView)
-        chartView.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([
-            chartView.topAnchor.constraint(equalTo: containerView.topAnchor),
-            chartView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
-            chartView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
-            chartView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
-        ])
-
-        return containerView
+    private struct GridPoint: Identifiable {
+        let hypo: Double
+        let hyper: Double
+        let zone: Zone
+        var id: String { "\(hypo)-\(hyper)" }
     }
 
-    class Coordinator {}
-
-    func updateUIView(_ containerView: UIView, context _: Context) {
-        guard let chartView = containerView.subviews.first as? ScatterChartView else { return }
-
-        chartView.data = nil
-
-        let xHypoValue = hypoComponent
-        let yHyperValue = hyperComponent
-
-        var zoneAEntries: [ChartDataEntry] = []
-        var zoneBEntries: [ChartDataEntry] = []
-        var zoneCEntries: [ChartDataEntry] = []
-        var zoneDEntries: [ChartDataEntry] = []
-        var zoneEEntries: [ChartDataEntry] = []
-
+    private var gridPoints: [GridPoint] {
+        var points: [GridPoint] = []
         let step = 0.5
         for hypo in stride(from: 0.0, through: 30.0, by: step) {
             for hyper in stride(from: 0.0, through: 60.0, by: step) {
                 let griValue = (3.0 * hypo) + (1.6 * hyper)
-
                 guard griValue <= 100 else { continue }
 
-                let entry = ChartDataEntry(x: hypo, y: hyper)
-
+                let zone: Zone
                 if griValue <= 20 {
-                    zoneAEntries.append(entry)
+                    zone = .a
                 } else if griValue <= 40 {
-                    zoneBEntries.append(entry)
+                    zone = .b
                 } else if griValue <= 60 {
-                    zoneCEntries.append(entry)
+                    zone = .c
                 } else if griValue <= 80 {
-                    zoneDEntries.append(entry)
+                    zone = .d
                 } else {
-                    zoneEEntries.append(entry)
+                    zone = .e
                 }
+                points.append(GridPoint(hypo: hypo, hyper: hyper, zone: zone))
             }
         }
+        return points
+    }
 
-        let zoneADataSet = ScatterChartDataSet(entries: zoneAEntries, label: "Zone A")
-        zoneADataSet.setColor(NSUIColor.systemGreen.withAlphaComponent(0.3))
-        zoneADataSet.scatterShapeSize = 4
-        zoneADataSet.drawValuesEnabled = false
-
-        let zoneBDataSet = ScatterChartDataSet(entries: zoneBEntries, label: "Zone B")
-        zoneBDataSet.setColor(NSUIColor.systemYellow.withAlphaComponent(0.3))
-        zoneBDataSet.scatterShapeSize = 4
-        zoneBDataSet.drawValuesEnabled = false
-
-        let zoneCDataSet = ScatterChartDataSet(entries: zoneCEntries, label: "Zone C")
-        zoneCDataSet.setColor(NSUIColor.systemOrange.withAlphaComponent(0.3))
-        zoneCDataSet.scatterShapeSize = 4
-        zoneCDataSet.drawValuesEnabled = false
-
-        let zoneDDataSet = ScatterChartDataSet(entries: zoneDEntries, label: "Zone D")
-        zoneDDataSet.setColor(NSUIColor.systemRed.withAlphaComponent(0.3))
-        zoneDDataSet.scatterShapeSize = 4
-        zoneDDataSet.drawValuesEnabled = false
-
-        let zoneEDataSet = ScatterChartDataSet(entries: zoneEEntries, label: "Zone E")
-        zoneEDataSet.setColor(NSUIColor.systemRed.withAlphaComponent(0.5))
-        zoneEDataSet.scatterShapeSize = 4
-        zoneEDataSet.drawValuesEnabled = false
-
-        let currentPoint = ChartDataEntry(x: xHypoValue, y: yHyperValue)
-        let currentDataSet = ScatterChartDataSet(entries: [currentPoint], label: "Current GRI")
-        currentDataSet.setColor(NSUIColor.label)
-        currentDataSet.scatterShapeSize = 12
-        currentDataSet.setScatterShape(.circle)
-        currentDataSet.drawValuesEnabled = false
-
-        let data = ScatterChartData()
-        data.append(zoneADataSet)
-        data.append(zoneBDataSet)
-        data.append(zoneCDataSet)
-        data.append(zoneDDataSet)
-        data.append(zoneEDataSet)
-        data.append(currentDataSet)
-
-        chartView.data = data
+    var body: some View {
+        Chart {
+            ForEach(gridPoints) { point in
+                PointMark(
+                    x: .value("hypo", point.hypo),
+                    y: .value("hyper", point.hyper)
+                )
+                .symbolSize(16)
+                .foregroundStyle(by: .value("zone", point.zone))
+            }
 
-        chartView.xAxis.valueFormatter = DefaultAxisValueFormatter { value, _ in
-            String(format: "%.0f", value)
+            PointMark(
+                x: .value("hypo", hypoComponent),
+                y: .value("hyper", hyperComponent)
+            )
+            .symbolSize(120)
+            .foregroundStyle(Color(.label))
         }
-        chartView.leftAxis.valueFormatter = DefaultAxisValueFormatter { value, _ in
-            String(format: "%.0f", value)
+        .chartForegroundStyleScale(
+            domain: Zone.allCases,
+            range: Zone.allCases.map(\.color)
+        )
+        .chartLegend(.hidden)
+        .chartXScale(domain: 0 ... 30)
+        .chartYScale(domain: 0 ... 61)
+        .chartXAxis {
+            AxisMarks(position: .bottom) { value in
+                AxisTick()
+                AxisValueLabel {
+                    if let v = value.as(Double.self) {
+                        Text(String(format: "%.0f", v))
+                    }
+                }
+            }
         }
-
-        chartView.xAxis.labelTextColor = .label
-        chartView.leftAxis.labelTextColor = .label
-
-        chartView.notifyDataSetChanged()
+        .chartYAxis {
+            AxisMarks(position: .leading) { value in
+                AxisTick()
+                AxisValueLabel {
+                    if let v = value.as(Double.self) {
+                        Text(String(format: "%.0f", v))
+                    }
+                }
+            }
+        }
+        .allowsHitTesting(false)
+        .background(Color(.systemBackground))
     }
 }

+ 3 - 1
LoopFollow/Stats/GRI/GRIView.swift

@@ -43,9 +43,11 @@ struct GRIView: View {
                             gri: viewModel.gri ?? 0
                         )
                         .frame(height: 250)
+                        .padding(.top, 10)
                         .padding(.leading, yAxisLabelInset)
+                        .padding(.trailing, 8)
+                        .padding(.bottom, 4)
                         .allowsHitTesting(false)
-                        .clipped()
 
                         Text("Hyperglycemia Component (%)")
                             .font(.caption2)

+ 61 - 84
LoopFollow/Stats/TIR/TIRGraphView.swift

@@ -3,99 +3,76 @@
 
 import Charts
 import SwiftUI
-import UIKit
 
-struct TIRGraphView: UIViewRepresentable {
+struct TIRGraphView: View {
     let tirData: [TIRDataPoint]
 
-    func makeCoordinator() -> Coordinator {
-        Coordinator()
+    private enum Band: String, CaseIterable, Plottable {
+        case veryLow = "Very Low"
+        case low = "Low"
+        case inRange = "In Range"
+        case high = "High"
+        case veryHigh = "Very High"
+
+        var color: Color {
+            switch self {
+            case .veryLow: return .red.opacity(0.8)
+            case .low: return .red.opacity(0.5)
+            case .inRange: return .green.opacity(0.7)
+            case .high: return .yellow.opacity(0.7)
+            case .veryHigh: return .orange.opacity(0.7)
+            }
+        }
     }
 
-    func makeUIView(context _: Context) -> UIView {
-        let containerView = NonInteractiveContainerView()
-        containerView.backgroundColor = .systemBackground
-
-        let chartView = BarChartView()
-        chartView.backgroundColor = .systemBackground
-        chartView.rightAxis.enabled = false
-        chartView.leftAxis.enabled = true
-        chartView.xAxis.labelPosition = .bottom
-        chartView.xAxis.granularity = 1.0
-        chartView.leftAxis.axisMinimum = 0.0
-        chartView.leftAxis.axisMaximum = 100.0
-        chartView.leftAxis.valueFormatter = PercentageAxisValueFormatter()
-        chartView.leftAxis.labelCount = 5
-        chartView.rightAxis.drawGridLinesEnabled = false
-        chartView.leftAxis.drawGridLinesEnabled = true
-        chartView.leftAxis.gridLineDashLengths = [5, 5]
-        chartView.xAxis.drawGridLinesEnabled = false
-        chartView.legend.enabled = false
-        chartView.chartDescription.enabled = false
-        chartView.isUserInteractionEnabled = false
-
-        containerView.addSubview(chartView)
-        chartView.translatesAutoresizingMaskIntoConstraints = false
-        NSLayoutConstraint.activate([
-            chartView.topAnchor.constraint(equalTo: containerView.topAnchor),
-            chartView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
-            chartView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
-            chartView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
-        ])
-
-        return containerView
+    private struct Slice: Identifiable {
+        let period: TIRPeriod
+        let band: Band
+        let value: Double
+        var id: String { "\(period.rawValue)-\(band.rawValue)" }
     }
 
-    class Coordinator {}
-
-    func updateUIView(_ containerView: UIView, context _: Context) {
-        guard let chartView = containerView.subviews.first as? BarChartView else { return }
-        guard !tirData.isEmpty else { return }
-
-        var dataEntries: [BarChartDataEntry] = []
-        var xAxisLabels: [String] = []
-
-        for (index, point) in tirData.enumerated() {
-            let entry = BarChartDataEntry(
-                x: Double(index),
-                yValues: [
-                    point.veryLow,
-                    point.low,
-                    point.inRange,
-                    point.high,
-                    point.veryHigh,
-                ]
-            )
-            dataEntries.append(entry)
-            xAxisLabels.append(point.period.rawValue)
+    private var slices: [Slice] {
+        tirData.flatMap { point in
+            [
+                Slice(period: point.period, band: .veryLow, value: point.veryLow),
+                Slice(period: point.period, band: .low, value: point.low),
+                Slice(period: point.period, band: .inRange, value: point.inRange),
+                Slice(period: point.period, band: .high, value: point.high),
+                Slice(period: point.period, band: .veryHigh, value: point.veryHigh),
+            ]
         }
-
-        let dataSet = BarChartDataSet(entries: dataEntries, label: "Time in Range")
-        dataSet.colors = [
-            UIColor.systemRed.withAlphaComponent(0.8),
-            UIColor.systemRed.withAlphaComponent(0.5),
-            UIColor.systemGreen.withAlphaComponent(0.7),
-            UIColor.systemYellow.withAlphaComponent(0.7),
-            UIColor.systemOrange.withAlphaComponent(0.7),
-        ]
-        dataSet.stackLabels = ["Very Low", "Low", "In Range", "High", "Very High"]
-        dataSet.drawValuesEnabled = false
-
-        let data = BarChartData(dataSet: dataSet)
-        data.barWidth = 0.6
-
-        chartView.data = data
-
-        chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: xAxisLabels)
-        chartView.xAxis.labelRotationAngle = 0
-        chartView.xAxis.labelCount = xAxisLabels.count
-
-        chartView.notifyDataSetChanged()
     }
-}
 
-class PercentageAxisValueFormatter: AxisValueFormatter {
-    func stringForValue(_ value: Double, axis _: AxisBase?) -> String {
-        return String(format: "%.0f%%", value)
+    var body: some View {
+        Chart(slices) { slice in
+            BarMark(
+                x: .value("period", slice.period.rawValue),
+                y: .value("pct", slice.value),
+                width: .ratio(0.6)
+            )
+            .foregroundStyle(by: .value("band", slice.band))
+        }
+        .chartForegroundStyleScale(domain: Band.allCases, range: Band.allCases.map(\.color))
+        .chartLegend(.hidden)
+        .chartYScale(domain: 0 ... 102)
+        .chartYAxis {
+            AxisMarks(position: .leading, values: [0, 25, 50, 75, 100]) { value in
+                AxisGridLine(stroke: StrokeStyle(lineWidth: 0.5, dash: [5, 5]))
+                AxisTick()
+                AxisValueLabel {
+                    if let pct = value.as(Int.self) {
+                        Text("\(pct)%")
+                    }
+                }
+            }
+        }
+        .chartXAxis {
+            AxisMarks(position: .bottom) { _ in
+                AxisValueLabel()
+            }
+        }
+        .allowsHitTesting(false)
+        .background(Color(.systemBackground))
     }
 }

+ 3 - 1
LoopFollow/Stats/TIR/TIRView.swift

@@ -27,8 +27,10 @@ struct TIRView: View {
                     if !viewModel.tirData.isEmpty {
                         TIRGraphView(tirData: viewModel.tirData)
                             .frame(height: 250)
+                            .padding(.top, 10)
+                            .padding(.horizontal, 8)
+                            .padding(.bottom, 4)
                             .allowsHitTesting(false)
-                            .clipped()
 
                         VStack(alignment: .leading, spacing: 8) {
                             if let average = viewModel.tirData.first(where: { $0.period == .average }) {

+ 0 - 20
LoopFollow/ViewControllers/LineChartWrapper.swift

@@ -1,20 +0,0 @@
-// LoopFollow
-// LineChartWrapper.swift
-
-import Charts
-import SwiftUI
-
-struct LineChartWrapper: UIViewRepresentable {
-    let chartView: LineChartView
-
-    func makeUIView(context _: Context) -> LineChartView {
-        chartView
-    }
-
-    func updateUIView(_: LineChartView, context _: Context) {
-        // Intentionally empty. MainViewController owns the chart and calls
-        // notifyDataSetChanged itself whenever it mutates the data; doing it
-        // here too would redo that work on every unrelated SwiftUI re-render
-        // of MainHomeView (e.g. the once-a-second minAgoText tick).
-    }
-}

+ 6 - 5
LoopFollow/ViewControllers/MainHomeView.swift

@@ -1,12 +1,13 @@
 // LoopFollow
 // MainHomeView.swift
 
-import Charts
 import SwiftUI
 
 struct MainHomeView: View {
-    let bgChart: LineChartView
-    let bgChartFull: LineChartView
+    // Deliberately not @ObservedObject: this view only passes the model on.
+    // The chart views observe what they each need, so data and (especially)
+    // per-frame pan/zoom updates don't re-evaluate this whole screen.
+    let chartModel: BGChartModel
     @ObservedObject var infoManager: InfoManager
     @ObservedObject var statsModel: StatsDisplayModel
 
@@ -53,11 +54,11 @@ struct MainHomeView: View {
             .fixedSize(horizontal: false, vertical: true)
 
             // Main chart (fills remaining space)
-            LineChartWrapper(chartView: bgChart)
+            BGChartView(model: chartModel, config: .main)
 
             // Small overview chart
             if showSmallGraph.value {
-                LineChartWrapper(chartView: bgChartFull)
+                BGChartView(model: chartModel, config: .small)
                     .frame(height: CGFloat(smallGraphHeight.value))
             }
 

+ 8 - 28
LoopFollow/ViewControllers/MainViewController.swift

@@ -2,7 +2,6 @@
 // MainViewController.swift
 
 import AVFAudio
-import Charts
 import Combine
 import CoreBluetooth
 import EventKit
@@ -23,7 +22,7 @@ private struct APNSCredentialSnapshot: Equatable {
     let lfKeyId: String
 }
 
-class MainViewController: UIViewController, ChartViewDelegate, UNUserNotificationCenterDelegate {
+class MainViewController: UIViewController, UNUserNotificationCenterDelegate {
     /// The single, long-lived MainViewController that owns the app's data
     /// pipeline (scheduleAllTasks). Held strongly so it stays alive — and the
     /// engine keeps running — regardless of which tabs are visible or whether
@@ -41,8 +40,6 @@ class MainViewController: UIViewController, ChartViewDelegate, UNUserNotificatio
         vc.loadViewIfNeeded()
     }
 
-    var BGChart: LineChartView!
-    var BGChartFull: LineChartView!
     var statsDisplayModel = StatsDisplayModel()
 
     /// The hosting controller's view — hidden during loading / first-time setup.
@@ -90,6 +87,10 @@ class MainViewController: UIViewController, ChartViewDelegate, UNUserNotificatio
     var overrideGraphData: [DataStructs.overrideStruct] = []
     var tempTargetGraphData: [DataStructs.tempTargetStruct] = []
     var predictionData: [ShareGlucoseData] = []
+    var ztPredictionData: [ShareGlucoseData] = []
+    var iobPredictionData: [ShareGlucoseData] = []
+    var cobPredictionData: [ShareGlucoseData] = []
+    var uamPredictionData: [ShareGlucoseData] = []
     var openAPSPredBGs: [String: [Double]]?
     var openAPSPredUpdatedTime: TimeInterval?
     var bgCheckData: [ShareGlucoseData] = []
@@ -97,7 +98,6 @@ class MainViewController: UIViewController, ChartViewDelegate, UNUserNotificatio
     var resumeGraphData: [DataStructs.timestampOnlyStruct] = []
     var sensorStartGraphData: [DataStructs.timestampOnlyStruct] = []
     var noteGraphData: [DataStructs.noteStruct] = []
-    var chartData = LineChartData()
     var deviceBatteryData: [DataStructs.batteryStruct] = []
     var lastCalDate: Double = 0
     var latestLoopStatusString = ""
@@ -127,12 +127,12 @@ class MainViewController: UIViewController, ChartViewDelegate, UNUserNotificatio
     // Stores the timestamp of the last BG value that was spoken.
     var lastSpokenBGDate: TimeInterval = 0
 
-    var autoScrollPauseUntil: Date?
-
     var IsNotLooping = false
 
     let contactImageUpdater = ContactImageUpdater()
 
+    let chartModel = BGChartModel()
+
     private var cancellables = Set<AnyCancellable>()
 
     // Loading state management
@@ -150,17 +150,10 @@ class MainViewController: UIViewController, ChartViewDelegate, UNUserNotificatio
     private func setupUI() {
         view.backgroundColor = .systemBackground
 
-        BGChart = LineChartView()
-        BGChart.backgroundColor = .systemBackground
-
-        BGChartFull = LineChartView()
-        BGChartFull.backgroundColor = .systemBackground
-
         infoManager = InfoManager()
 
         let mainView = MainHomeView(
-            bgChart: BGChart,
-            bgChartFull: BGChartFull,
+            chartModel: chartModel,
             infoManager: infoManager,
             statsModel: statsDisplayModel,
             onRefresh: { [weak self] in self?.refresh() },
@@ -214,9 +207,6 @@ class MainViewController: UIViewController, ChartViewDelegate, UNUserNotificatio
         // setup show/hide graphs (first-time setup check)
         updateGraphVisibility()
 
-        BGChart.delegate = self
-        BGChartFull.delegate = self
-
         // Apply initial appearance mode
         updateAppearance(Storage.shared.appearanceMode.value)
 
@@ -962,16 +952,6 @@ class MainViewController: UIViewController, ChartViewDelegate, UNUserNotificatio
 
     func userNotificationCenter(_: UNUserNotificationCenter, didReceive _: UNNotificationResponse, withCompletionHandler _: @escaping () -> Void) {}
 
-    // User has scrolled the chart
-    func chartTranslated(_: ChartViewBase, dX _: CGFloat, dY _: CGFloat) {
-        let isViewingLatestData = abs(BGChart.highestVisibleX - BGChart.chartXMax) < 0.001
-        if isViewingLatestData {
-            autoScrollPauseUntil = nil // User is back at the latest data, allow auto-scrolling
-        } else {
-            autoScrollPauseUntil = Date().addingTimeInterval(5 * 60) // User is viewing historical data, pause auto-scrolling
-        }
-    }
-
     func calculateMaxBgGraphValue() -> Float {
         return max(Float(topBG), Float(topPredictionBG))
     }

+ 0 - 51
Podfile

@@ -1,7 +1,6 @@
 target 'LoopFollow' do
   use_frameworks!
 
-  pod 'Charts'
   pod 'ShareClient', :git => 'https://github.com/loopandlearn/dexcom-share-client-swift.git', :branch => 'loopfollow'
 
 end
@@ -15,54 +14,4 @@ post_install do |installer|
       end
     end
   end
-
-  # Patch Charts Transformer to avoid "CGAffineTransformInvert: singular matrix"
-  # warnings when chart views have zero dimensions (before layout).
-  transformer = 'Pods/Charts/Source/Charts/Utils/Transformer.swift'
-  if File.exist?(transformer)
-    code = File.read(transformer)
-    original = 'return valueToPixelMatrix.inverted()'
-    patched = <<~SWIFT.chomp
-      let matrix = valueToPixelMatrix
-            guard matrix.a * matrix.d - matrix.b * matrix.c != 0 else {
-                return .identity
-            }
-            return matrix.inverted()
-    SWIFT
-    if code.include?(original)
-      File.write(transformer, code.sub(original, patched))
-    end
-  end
-
-  # Inject a privacy manifest into the Charts framework (ITMS-91061).
-  # Charts 4.1.0 ships no PrivacyInfo.xcprivacy; it collects no data, performs
-  # no tracking, and uses no required-reason APIs, so this is a negative
-  # declaration. Re-applied here because `pod install` regenerates the project.
-  charts_manifest = <<~XML
-    <?xml version="1.0" encoding="UTF-8"?>
-    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-    <plist version="1.0">
-    <dict>
-    \t<key>NSPrivacyTracking</key>
-    \t<false/>
-    \t<key>NSPrivacyTrackingDomains</key>
-    \t<array/>
-    \t<key>NSPrivacyCollectedDataTypes</key>
-    \t<array/>
-    \t<key>NSPrivacyAccessedAPITypes</key>
-    \t<array/>
-    </dict>
-    </plist>
-  XML
-
-  manifest_path = installer.sandbox.root + 'Charts/PrivacyInfo.xcprivacy'
-  File.write(manifest_path, charts_manifest)
-
-  charts_target = installer.pods_project.targets.find { |t| t.name == 'Charts' }
-  if charts_target
-    file_ref = installer.pods_project.new_file(manifest_path.to_s)
-    already_added = charts_target.resources_build_phase.files_references.include?(file_ref)
-    charts_target.resources_build_phase.add_file_reference(file_ref) unless already_added
-    installer.pods_project.save
-  end
 end

+ 2 - 15
Podfile.lock

@@ -1,20 +1,9 @@
 PODS:
-  - Charts (4.1.0):
-    - Charts/Core (= 4.1.0)
-  - Charts/Core (4.1.0):
-    - SwiftAlgorithms (~> 1.0)
   - ShareClient (1.2)
-  - SwiftAlgorithms (1.0.0)
 
 DEPENDENCIES:
-  - Charts
   - ShareClient (from `https://github.com/loopandlearn/dexcom-share-client-swift.git`, branch `loopfollow`)
 
-SPEC REPOS:
-  trunk:
-    - Charts
-    - SwiftAlgorithms
-
 EXTERNAL SOURCES:
   ShareClient:
     :branch: loopfollow
@@ -26,10 +15,8 @@ CHECKOUT OPTIONS:
     :git: https://github.com/loopandlearn/dexcom-share-client-swift.git
 
 SPEC CHECKSUMS:
-  Charts: ce0768268078eee0336f122c3c4ca248e4e204c5
   ShareClient: 60b911c95e73b0ea9c5aad6d194a9c6b5f34b741
-  SwiftAlgorithms: 38dda4731d19027fdeee1125f973111bf3386b53
 
-PODFILE CHECKSUM: d241dda366d5454279fe3ff8869458d19e1bbebb
+PODFILE CHECKSUM: 617b13cfc623f15ca31e14e19086cb729b408fd7
 
-COCOAPODS: 1.12.1
+COCOAPODS: 1.16.2

+ 0 - 202
Pods/Charts/LICENSE

@@ -1,202 +0,0 @@
-Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "{}"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright 2016-2019 Daniel Cohen Gindi & Philipp Jahoda
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-

+ 0 - 14
Pods/Charts/PrivacyInfo.xcprivacy

@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>NSPrivacyTracking</key>
-	<false/>
-	<key>NSPrivacyTrackingDomains</key>
-	<array/>
-	<key>NSPrivacyCollectedDataTypes</key>
-	<array/>
-	<key>NSPrivacyAccessedAPITypes</key>
-	<array/>
-</dict>
-</plist>

Разница между файлами не показана из-за своего большого размера
+ 0 - 239
Pods/Charts/README.md


+ 0 - 281
Pods/Charts/Source/Charts/Animation/Animator.swift

@@ -1,281 +0,0 @@
-//
-//  Animator.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-import QuartzCore
-
-@objc(ChartAnimatorDelegate)
-public protocol AnimatorDelegate
-{
-    /// Called when the Animator has stepped.
-    func animatorUpdated(_ animator: Animator)
-    
-    /// Called when the Animator has stopped.
-    func animatorStopped(_ animator: Animator)
-}
-
-@objc(ChartAnimator)
-open class Animator: NSObject
-{
-    @objc open weak var delegate: AnimatorDelegate?
-    @objc open var updateBlock: (() -> Void)?
-    @objc open var stopBlock: (() -> Void)?
-    
-    /// the phase that is animated and influences the drawn values on the x-axis
-    @objc open var phaseX: Double = 1.0
-    
-    /// the phase that is animated and influences the drawn values on the y-axis
-    @objc open var phaseY: Double = 1.0
-    
-    private var _startTimeX: TimeInterval = 0.0
-    private var _startTimeY: TimeInterval = 0.0
-    private var _displayLink: NSUIDisplayLink?
-    
-    private var _durationX: TimeInterval = 0.0
-    private var _durationY: TimeInterval = 0.0
-    
-    private var _endTimeX: TimeInterval = 0.0
-    private var _endTimeY: TimeInterval = 0.0
-    private var _endTime: TimeInterval = 0.0
-    
-    private var _enabledX: Bool = false
-    private var _enabledY: Bool = false
-    
-    private var _easingX: ChartEasingFunctionBlock?
-    private var _easingY: ChartEasingFunctionBlock?
-
-    public override init()
-    {
-        super.init()
-    }
-    
-    deinit
-    {
-        stop()
-    }
-    
-    @objc open func stop()
-    {
-        guard _displayLink != nil else { return }
-
-        _displayLink?.remove(from: .main, forMode: RunLoop.Mode.common)
-        _displayLink = nil
-
-        _enabledX = false
-        _enabledY = false
-
-        // If we stopped an animation in the middle, we do not want to leave it like this
-        if phaseX != 1.0 || phaseY != 1.0
-        {
-            phaseX = 1.0
-            phaseY = 1.0
-
-            delegate?.animatorUpdated(self)
-            updateBlock?()
-        }
-
-        delegate?.animatorStopped(self)
-        stopBlock?()
-    }
-    
-    private func updateAnimationPhases(_ currentTime: TimeInterval)
-    {
-        if _enabledX
-        {
-            let elapsedTime: TimeInterval = currentTime - _startTimeX
-            let duration: TimeInterval = _durationX
-            var elapsed: TimeInterval = elapsedTime
-            if elapsed > duration
-            {
-                elapsed = duration
-            }
-           
-            phaseX = _easingX?(elapsed, duration) ?? elapsed / duration
-        }
-        
-        if _enabledY
-        {
-            let elapsedTime: TimeInterval = currentTime - _startTimeY
-            let duration: TimeInterval = _durationY
-            var elapsed: TimeInterval = elapsedTime
-            if elapsed > duration
-            {
-                elapsed = duration
-            }
-
-            phaseY = _easingY?(elapsed, duration) ?? elapsed / duration
-        }
-    }
-    
-    @objc private func animationLoop()
-    {
-        let currentTime: TimeInterval = CACurrentMediaTime()
-        
-        updateAnimationPhases(currentTime)
-
-        delegate?.animatorUpdated(self)
-        updateBlock?()
-        
-        if currentTime >= _endTime
-        {
-            stop()
-        }
-    }
-    
-    /// Animates the drawing / rendering of the chart on both x- and y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easingX: an easing function for the animation on the x axis
-    ///   - easingY: an easing function for the animation on the y axis
-    @objc open func animate(xAxisDuration: TimeInterval, yAxisDuration: TimeInterval, easingX: ChartEasingFunctionBlock?, easingY: ChartEasingFunctionBlock?)
-    {
-        stop()
-        
-        _startTimeX = CACurrentMediaTime()
-        _startTimeY = _startTimeX
-        _durationX = xAxisDuration
-        _durationY = yAxisDuration
-        _endTimeX = _startTimeX + xAxisDuration
-        _endTimeY = _startTimeY + yAxisDuration
-        _endTime = _endTimeX > _endTimeY ? _endTimeX : _endTimeY
-        _enabledX = xAxisDuration > 0.0
-        _enabledY = yAxisDuration > 0.0
-        
-        _easingX = easingX
-        _easingY = easingY
-        
-        // Take care of the first frame if rendering is already scheduled...
-        updateAnimationPhases(_startTimeX)
-        
-        if _enabledX || _enabledY
-        {
-            _displayLink = NSUIDisplayLink(target: self, selector: #selector(animationLoop))
-            _displayLink?.add(to: RunLoop.main, forMode: RunLoop.Mode.common)
-        }
-    }
-    
-    /// Animates the drawing / rendering of the chart on both x- and y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easingOptionX: the easing function for the animation on the x axis
-    ///   - easingOptionY: the easing function for the animation on the y axis
-    @objc open func animate(xAxisDuration: TimeInterval, yAxisDuration: TimeInterval, easingOptionX: ChartEasingOption, easingOptionY: ChartEasingOption)
-    {
-        animate(xAxisDuration: xAxisDuration, yAxisDuration: yAxisDuration, easingX: easingFunctionFromOption(easingOptionX), easingY: easingFunctionFromOption(easingOptionY))
-    }
-    
-    /// Animates the drawing / rendering of the chart on both x- and y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easing: an easing function for the animation
-    @objc open func animate(xAxisDuration: TimeInterval, yAxisDuration: TimeInterval, easing: ChartEasingFunctionBlock?)
-    {
-        animate(xAxisDuration: xAxisDuration, yAxisDuration: yAxisDuration, easingX: easing, easingY: easing)
-    }
-    
-    /// Animates the drawing / rendering of the chart on both x- and y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easingOption: the easing function for the animation
-    @objc open func animate(xAxisDuration: TimeInterval, yAxisDuration: TimeInterval, easingOption: ChartEasingOption = .easeInOutSine)
-    {
-        animate(xAxisDuration: xAxisDuration, yAxisDuration: yAxisDuration, easing: easingFunctionFromOption(easingOption))
-    }
-
-    /// Animates the drawing / rendering of the chart the x-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - easing: an easing function for the animation
-    @objc open func animate(xAxisDuration: TimeInterval, easing: ChartEasingFunctionBlock?)
-    {
-        _startTimeX = CACurrentMediaTime()
-        _durationX = xAxisDuration
-        _endTimeX = _startTimeX + xAxisDuration
-        _endTime = _endTimeX > _endTimeY ? _endTimeX : _endTimeY
-        _enabledX = xAxisDuration > 0.0
-        
-        _easingX = easing
-        
-        // Take care of the first frame if rendering is already scheduled...
-        updateAnimationPhases(_startTimeX)
-        
-        if _enabledX || _enabledY,
-            _displayLink == nil
-        {
-            _displayLink = NSUIDisplayLink(target: self, selector: #selector(animationLoop))
-            _displayLink?.add(to: .main, forMode: RunLoop.Mode.common)
-        }
-    }
-    
-    /// Animates the drawing / rendering of the chart the x-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - easingOption: the easing function for the animation
-    @objc open func animate(xAxisDuration: TimeInterval, easingOption: ChartEasingOption = .easeInOutSine)
-    {
-        animate(xAxisDuration: xAxisDuration, easing: easingFunctionFromOption(easingOption))
-    }
-
-    /// Animates the drawing / rendering of the chart the y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easing: an easing function for the animation
-    @objc open func animate(yAxisDuration: TimeInterval, easing: ChartEasingFunctionBlock?)
-    {
-        _startTimeY = CACurrentMediaTime()
-        _durationY = yAxisDuration
-        _endTimeY = _startTimeY + yAxisDuration
-        _endTime = _endTimeX > _endTimeY ? _endTimeX : _endTimeY
-        _enabledY = yAxisDuration > 0.0
-        
-        _easingY = easing
-        
-        // Take care of the first frame if rendering is already scheduled...
-        updateAnimationPhases(_startTimeY)
-        
-        if _enabledX || _enabledY,
-            _displayLink == nil
-        {
-            _displayLink = NSUIDisplayLink(target: self, selector: #selector(animationLoop))
-            _displayLink?.add(to: .main, forMode: RunLoop.Mode.common)
-        }
-    }
-    
-    /// Animates the drawing / rendering of the chart the y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easingOption: the easing function for the animation
-    @objc open func animate(yAxisDuration: TimeInterval, easingOption: ChartEasingOption = .easeInOutSine)
-    {
-        animate(yAxisDuration: yAxisDuration, easing: easingFunctionFromOption(easingOption))
-    }
-}

+ 0 - 394
Pods/Charts/Source/Charts/Animation/ChartAnimationEasing.swift

@@ -1,394 +0,0 @@
-//
-//  ChartAnimationUtils.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc
-public enum ChartEasingOption: Int
-{
-    case linear
-    case easeInQuad
-    case easeOutQuad
-    case easeInOutQuad
-    case easeInCubic
-    case easeOutCubic
-    case easeInOutCubic
-    case easeInQuart
-    case easeOutQuart
-    case easeInOutQuart
-    case easeInQuint
-    case easeOutQuint
-    case easeInOutQuint
-    case easeInSine
-    case easeOutSine
-    case easeInOutSine
-    case easeInExpo
-    case easeOutExpo
-    case easeInOutExpo
-    case easeInCirc
-    case easeOutCirc
-    case easeInOutCirc
-    case easeInElastic
-    case easeOutElastic
-    case easeInOutElastic
-    case easeInBack
-    case easeOutBack
-    case easeInOutBack
-    case easeInBounce
-    case easeOutBounce
-    case easeInOutBounce
-}
-
-public typealias ChartEasingFunctionBlock = ((_ elapsed: TimeInterval, _ duration: TimeInterval) -> Double)
-
-internal func easingFunctionFromOption(_ easing: ChartEasingOption) -> ChartEasingFunctionBlock
-{
-    switch easing
-    {
-    case .linear:
-        return EasingFunctions.Linear
-    case .easeInQuad:
-        return EasingFunctions.EaseInQuad
-    case .easeOutQuad:
-        return EasingFunctions.EaseOutQuad
-    case .easeInOutQuad:
-        return EasingFunctions.EaseInOutQuad
-    case .easeInCubic:
-        return EasingFunctions.EaseInCubic
-    case .easeOutCubic:
-        return EasingFunctions.EaseOutCubic
-    case .easeInOutCubic:
-        return EasingFunctions.EaseInOutCubic
-    case .easeInQuart:
-        return EasingFunctions.EaseInQuart
-    case .easeOutQuart:
-        return EasingFunctions.EaseOutQuart
-    case .easeInOutQuart:
-        return EasingFunctions.EaseInOutQuart
-    case .easeInQuint:
-        return EasingFunctions.EaseInQuint
-    case .easeOutQuint:
-        return EasingFunctions.EaseOutQuint
-    case .easeInOutQuint:
-        return EasingFunctions.EaseInOutQuint
-    case .easeInSine:
-        return EasingFunctions.EaseInSine
-    case .easeOutSine:
-        return EasingFunctions.EaseOutSine
-    case .easeInOutSine:
-        return EasingFunctions.EaseInOutSine
-    case .easeInExpo:
-        return EasingFunctions.EaseInExpo
-    case .easeOutExpo:
-        return EasingFunctions.EaseOutExpo
-    case .easeInOutExpo:
-        return EasingFunctions.EaseInOutExpo
-    case .easeInCirc:
-        return EasingFunctions.EaseInCirc
-    case .easeOutCirc:
-        return EasingFunctions.EaseOutCirc
-    case .easeInOutCirc:
-        return EasingFunctions.EaseInOutCirc
-    case .easeInElastic:
-        return EasingFunctions.EaseInElastic
-    case .easeOutElastic:
-        return EasingFunctions.EaseOutElastic
-    case .easeInOutElastic:
-        return EasingFunctions.EaseInOutElastic
-    case .easeInBack:
-        return EasingFunctions.EaseInBack
-    case .easeOutBack:
-        return EasingFunctions.EaseOutBack
-    case .easeInOutBack:
-        return EasingFunctions.EaseInOutBack
-    case .easeInBounce:
-        return EasingFunctions.EaseInBounce
-    case .easeOutBounce:
-        return EasingFunctions.EaseOutBounce
-    case .easeInOutBounce:
-        return EasingFunctions.EaseInOutBounce
-    }
-}
-
-internal struct EasingFunctions
-{
-    internal static let Linear = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in return Double(elapsed / duration) }
-    
-    internal static let EaseInQuad = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / duration)
-        return position * position
-    }
-    
-    internal static let EaseOutQuad = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / duration)
-        return -position * (position - 2.0)
-    }
-    
-    internal static let EaseInOutQuad = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / (duration / 2.0))
-        if position < 1.0
-        {
-            return 0.5 * position * position
-        }
-        
-        return -0.5 * ((position - 1.0) * (position - 3.0) - 1.0)
-    }
-    
-    internal static let EaseInCubic = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / duration)
-        return position * position * position
-    }
-    
-    internal static let EaseOutCubic = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / duration)
-        position -= 1.0
-        return (position * position * position + 1.0)
-    }
-    
-    internal static let EaseInOutCubic = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / (duration / 2.0))
-        if position < 1.0
-        {
-            return 0.5 * position * position * position
-        }
-        position -= 2.0
-        return 0.5 * (position * position * position + 2.0)
-    }
-    
-    internal static let EaseInQuart = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / duration)
-        return position * position * position * position
-    }
-    
-    internal static let EaseOutQuart = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / duration)
-        position -= 1.0
-        return -(position * position * position * position - 1.0)
-    }
-    
-    internal static let EaseInOutQuart = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / (duration / 2.0))
-        if position < 1.0
-        {
-            return 0.5 * position * position * position * position
-        }
-        position -= 2.0
-        return -0.5 * (position * position * position * position - 2.0)
-    }
-    
-    internal static let EaseInQuint = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / duration)
-        return position * position * position * position * position
-    }
-    
-    internal static let EaseOutQuint = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / duration)
-        position -= 1.0
-        return (position * position * position * position * position + 1.0)
-    }
-    
-    internal static let EaseInOutQuint = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / (duration / 2.0))
-        if position < 1.0
-        {
-            return 0.5 * position * position * position * position * position
-        }
-        else
-        {
-            position -= 2.0
-            return 0.5 * (position * position * position * position * position + 2.0)
-        }
-    }
-    
-    internal static let EaseInSine = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position: TimeInterval = elapsed / duration
-        return Double( -cos(position * Double.pi / 2) + 1.0 )
-    }
-    
-    internal static let EaseOutSine = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position: TimeInterval = elapsed / duration
-        return Double( sin(position * Double.pi / 2) )
-    }
-    
-    internal static let EaseInOutSine = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position: TimeInterval = elapsed / duration
-        return Double( -0.5 * (cos(Double.pi * position) - 1.0) )
-    }
-    
-    internal static let EaseInExpo = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        return (elapsed == 0) ? 0.0 : Double(pow(2.0, 10.0 * (elapsed / duration - 1.0)))
-    }
-    
-    internal static let EaseOutExpo = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        return (elapsed == duration) ? 1.0 : (-Double(pow(2.0, -10.0 * elapsed / duration)) + 1.0)
-    }
-    
-    internal static let EaseInOutExpo = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        if elapsed == 0
-        {
-            return 0.0
-        }
-        if elapsed == duration
-        {
-            return 1.0
-        }
-        
-        var position: TimeInterval = elapsed / (duration / 2.0)
-        if position < 1.0
-        {
-            return Double( 0.5 * pow(2.0, 10.0 * (position - 1.0)) )
-        }
-        
-        position = position - 1.0
-        return Double( 0.5 * (-pow(2.0, -10.0 * position) + 2.0) )
-    }
-    
-    internal static let EaseInCirc = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / duration)
-        return -(Double(sqrt(1.0 - position * position)) - 1.0)
-    }
-    
-    internal static let EaseOutCirc = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position = Double(elapsed / duration)
-        position -= 1.0
-        return Double( sqrt(1 - position * position) )
-    }
-    
-    internal static let EaseInOutCirc = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position: TimeInterval = elapsed / (duration / 2.0)
-        if position < 1.0
-        {
-            return Double( -0.5 * (sqrt(1.0 - position * position) - 1.0) )
-        }
-        position -= 2.0
-        return Double( 0.5 * (sqrt(1.0 - position * position) + 1.0) )
-    }
-    
-    internal static let EaseInElastic = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        if elapsed == 0.0
-        {
-            return 0.0
-        }
-        
-        var position: TimeInterval = elapsed / duration
-        if position == 1.0
-        {
-            return 1.0
-        }
-        
-        var p = duration * 0.3
-        var s = p / (2.0 * Double.pi) * asin(1.0)
-        position -= 1.0
-        return Double( -(pow(2.0, 10.0 * position) * sin((position * duration - s) * (2.0 * Double.pi) / p)) )
-    }
-    
-    internal static let EaseOutElastic = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        if elapsed == 0.0
-        {
-            return 0.0
-        }
-        
-        var position: TimeInterval = elapsed / duration
-        if position == 1.0
-        {
-            return 1.0
-        }
-        
-        var p = duration * 0.3
-        var s = p / (2.0 * Double.pi) * asin(1.0)
-        return Double( pow(2.0, -10.0 * position) * sin((position * duration - s) * (2.0 * Double.pi) / p) + 1.0 )
-    }
-    
-    internal static let EaseInOutElastic = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        if elapsed == 0.0
-        {
-            return 0.0
-        }
-        
-        var position: TimeInterval = elapsed / (duration / 2.0)
-        if position == 2.0
-        {
-            return 1.0
-        }
-        
-        var p = duration * (0.3 * 1.5)
-        var s = p / (2.0 * Double.pi) * asin(1.0)
-        if position < 1.0
-        {
-            position -= 1.0
-            return Double( -0.5 * (pow(2.0, 10.0 * position) * sin((position * duration - s) * (2.0 * Double.pi) / p)) )
-        }
-        position -= 1.0
-        return Double( pow(2.0, -10.0 * position) * sin((position * duration - s) * (2.0 * Double.pi) / p) * 0.5 + 1.0 )
-    }
-    
-    internal static let EaseInBack = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        let s: TimeInterval = 1.70158
-        var position: TimeInterval = elapsed / duration
-        return Double( position * position * ((s + 1.0) * position - s) )
-    }
-    
-    internal static let EaseOutBack = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        let s: TimeInterval = 1.70158
-        var position: TimeInterval = elapsed / duration
-        position -= 1.0
-        return Double( position * position * ((s + Double(1.0)) * position + s) + Double(1.0) )
-    }
-    
-    internal static let EaseInOutBack = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var s: TimeInterval = 1.70158
-        var position: TimeInterval = elapsed / (duration / 2.0)
-        if position < 1.0
-        {
-            s *= 1.525
-            return Double( 0.5 * (position * position * ((s + 1.0) * position - s)) )
-        }
-        s *= 1.525
-        position -= 2.0
-        return Double( 0.5 * (position * position * ((s + 1.0) * position + s) + 2.0) )
-    }
-    
-    internal static let EaseInBounce = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        return 1.0 - EaseOutBounce(duration - elapsed, duration)
-    }
-    
-    internal static let EaseOutBounce = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        var position: TimeInterval = elapsed / duration
-        if position < (1.0 / 2.75)
-        {
-            return Double( 7.5625 * position * position )
-        }
-        else if position < (2.0 / 2.75)
-        {
-            position -= (1.5 / 2.75)
-            return Double( 7.5625 * position * position + 0.75 )
-        }
-        else if position < (2.5 / 2.75)
-        {
-            position -= (2.25 / 2.75)
-            return Double( 7.5625 * position * position + 0.9375 )
-        }
-        else
-        {
-            position -= (2.625 / 2.75)
-            return Double( 7.5625 * position * position + 0.984375 )
-        }
-    }
-    
-    internal static let EaseInOutBounce = { (elapsed: TimeInterval, duration: TimeInterval) -> Double in
-        if elapsed < (duration / 2.0)
-        {
-            return EaseInBounce(elapsed * 2.0, duration) * 0.5
-        }
-        return EaseOutBounce(elapsed * 2.0 - duration, duration) * 0.5 + 0.5
-    }
-}

+ 0 - 186
Pods/Charts/Source/Charts/Charts/BarChartView.swift

@@ -1,186 +0,0 @@
-//
-//  BarChartView.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-/// Chart that draws bars.
-open class BarChartView: BarLineChartViewBase, BarChartDataProvider
-{
-    /// if set to true, all values are drawn above their bars, instead of below their top
-    private var _drawValueAboveBarEnabled = true
-
-    /// if set to true, a grey area is drawn behind each bar that indicates the maximum value
-    private var _drawBarShadowEnabled = false
-    
-    internal override func initialize()
-    {
-        super.initialize()
-        
-        renderer = BarChartRenderer(dataProvider: self, animator: chartAnimator, viewPortHandler: viewPortHandler)
-        
-        self.highlighter = BarHighlighter(chart: self)
-        
-        self.xAxis.spaceMin = 0.5
-        self.xAxis.spaceMax = 0.5
-    }
-    
-    internal override func calcMinMax()
-    {
-        guard let data = self.data as? BarChartData
-            else { return }
-        
-        if fitBars
-        {
-            xAxis.calculate(
-                min: data.xMin - data.barWidth / 2.0,
-                max: data.xMax + data.barWidth / 2.0)
-        }
-        else
-        {
-            xAxis.calculate(min: data.xMin, max: data.xMax)
-        }
-        
-        // calculate axis range (min / max) according to provided data
-        leftAxis.calculate(
-            min: data.getYMin(axis: .left),
-            max: data.getYMax(axis: .left))
-        rightAxis.calculate(
-            min: data.getYMin(axis: .right),
-            max: data.getYMax(axis: .right))
-    }
-    
-    /// - Returns: The Highlight object (contains x-index and DataSet index) of the selected value at the given touch point inside the BarChart.
-    open override func getHighlightByTouchPoint(_ pt: CGPoint) -> Highlight?
-    {
-        if data === nil
-        {
-            Swift.print("Can't select by touch. No data set.")
-            return nil
-        }
-        
-        guard let h = self.highlighter?.getHighlight(x: pt.x, y: pt.y)
-            else { return nil }
-        
-        if !isHighlightFullBarEnabled { return h }
-        
-        // For isHighlightFullBarEnabled, remove stackIndex
-        return Highlight(
-            x: h.x, y: h.y,
-            xPx: h.xPx, yPx: h.yPx,
-            dataIndex: h.dataIndex,
-            dataSetIndex: h.dataSetIndex,
-            stackIndex: -1,
-            axis: h.axis)
-    }
-        
-    /// - Returns: The bounding box of the specified Entry in the specified DataSet. Returns null if the Entry could not be found in the charts data.
-    @objc open func getBarBounds(entry e: BarChartDataEntry) -> CGRect
-    {
-        guard let
-            data = data as? BarChartData,
-            let set = data.getDataSetForEntry(e) as? BarChartDataSetProtocol
-            else { return .null }
-        
-        let y = e.y
-        let x = e.x
-        
-        let barWidth = data.barWidth
-        
-        let left = x - barWidth / 2.0
-        let right = x + barWidth / 2.0
-        let top = y >= 0.0 ? y : 0.0
-        let bottom = y <= 0.0 ? y : 0.0
-        
-        var bounds = CGRect(x: left, y: top, width: right - left, height: bottom - top)
-        
-        getTransformer(forAxis: set.axisDependency).rectValueToPixel(&bounds)
-        
-        return bounds
-    }
-    
-    /// Groups all BarDataSet objects this data object holds together by modifying the x-value of their entries.
-    /// Previously set x-values of entries will be overwritten. Leaves space between bars and groups as specified by the parameters.
-    /// Calls `notifyDataSetChanged()` afterwards.
-    ///
-    /// - Parameters:
-    ///   - fromX: the starting point on the x-axis where the grouping should begin
-    ///   - groupSpace: the space between groups of bars in values (not pixels) e.g. 0.8f for bar width 1f
-    ///   - barSpace: the space between individual bars in values (not pixels) e.g. 0.1f for bar width 1f
-    @objc open func groupBars(fromX: Double, groupSpace: Double, barSpace: Double)
-    {
-        guard let barData = self.barData
-            else
-        {
-            Swift.print("You need to set data for the chart before grouping bars.", terminator: "\n")
-            return
-        }
-        
-        barData.groupBars(fromX: fromX, groupSpace: groupSpace, barSpace: barSpace)
-        notifyDataSetChanged()
-    }
-    
-    /// Highlights the value at the given x-value in the given DataSet. Provide -1 as the dataSetIndex to undo all highlighting.
-    ///
-    /// - Parameters:
-    ///   - x:
-    ///   - dataSetIndex:
-    ///   - stackIndex: the index inside the stack - only relevant for stacked entries
-    @objc open func highlightValue(x: Double, dataSetIndex: Int, stackIndex: Int)
-    {
-        highlightValue(Highlight(x: x, dataSetIndex: dataSetIndex, stackIndex: stackIndex))
-    }
-
-    // MARK: Accessors
-    
-    /// if set to true, all values are drawn above their bars, instead of below their top
-    @objc open var drawValueAboveBarEnabled: Bool
-    {
-        get { return _drawValueAboveBarEnabled }
-        set
-        {
-            _drawValueAboveBarEnabled = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// if set to true, a grey area is drawn behind each bar that indicates the maximum value
-    @objc open var drawBarShadowEnabled: Bool
-    {
-        get { return _drawBarShadowEnabled }
-        set
-        {
-            _drawBarShadowEnabled = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// Adds half of the bar width to each side of the x-axis range in order to allow the bars of the barchart to be fully displayed.
-    /// **default**: false
-    @objc open var fitBars = false
-    
-    /// Set this to `true` to make the highlight operation full-bar oriented, `false` to make it highlight single values (relevant only for stacked).
-    /// If enabled, highlighting operations will highlight the whole bar, even if only a single stack entry was tapped.
-    @objc open var highlightFullBarEnabled: Bool = false
-    
-    /// `true` the highlight is be full-bar oriented, `false` ifsingle-value
-    open var isHighlightFullBarEnabled: Bool { return highlightFullBarEnabled }
-    
-    // MARK: - BarChartDataProvider
-    
-    open var barData: BarChartData? { return data as? BarChartData }
-    
-    /// `true` if drawing values above bars is enabled, `false` ifnot
-    open var isDrawValueAboveBarEnabled: Bool { return drawValueAboveBarEnabled }
-    
-    /// `true` if drawing shadows (maxvalue) for each bar is enabled, `false` ifnot
-    open var isDrawBarShadowEnabled: Bool { return drawBarShadowEnabled }
-}

Разница между файлами не показана из-за своего большого размера
+ 0 - 1958
Pods/Charts/Source/Charts/Charts/BarLineChartViewBase.swift


+ 0 - 27
Pods/Charts/Source/Charts/Charts/BubbleChartView.swift

@@ -1,27 +0,0 @@
-//
-//  BubbleChartView.swift
-//  Charts
-//
-//  Bubble chart implementation:
-//    Copyright 2015 Pierre-Marc Airoldi
-//    Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-open class BubbleChartView: BarLineChartViewBase, BubbleChartDataProvider
-{
-    open override func initialize()
-    {
-        super.initialize()
-        
-        renderer = BubbleChartRenderer(dataProvider: self, animator: chartAnimator, viewPortHandler: viewPortHandler)
-    }
-    
-    // MARK: - BubbleChartDataProvider
-    
-    open var bubbleData: BubbleChartData? { return data as? BubbleChartData }
-}

+ 0 - 34
Pods/Charts/Source/Charts/Charts/CandleStickChartView.swift

@@ -1,34 +0,0 @@
-//
-//  CandleStickChartView.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-/// Financial chart type that draws candle-sticks.
-open class CandleStickChartView: BarLineChartViewBase, CandleChartDataProvider
-{
-    internal override func initialize()
-    {
-        super.initialize()
-        
-        renderer = CandleStickChartRenderer(dataProvider: self, animator: chartAnimator, viewPortHandler: viewPortHandler)
-        
-        self.xAxis.spaceMin = 0.5
-        self.xAxis.spaceMax = 0.5
-    }
-    
-    // MARK: - CandleChartDataProvider
-    
-    open var candleData: CandleChartData?
-    {
-        return data as? CandleChartData
-    }
-}

+ 0 - 890
Pods/Charts/Source/Charts/Charts/ChartViewBase.swift

@@ -1,890 +0,0 @@
-//
-//  ChartViewBase.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-//  Based on https://github.com/PhilJay/MPAndroidChart/commit/c42b880
-
-import Foundation
-import CoreGraphics
-
-#if !os(OSX)
-    import UIKit
-#endif
-
-@objc
-public protocol ChartViewDelegate
-{
-    /// Called when a value has been selected inside the chart.
-    ///
-    /// - Parameters:
-    ///   - entry: The selected Entry.
-    ///   - highlight: The corresponding highlight object that contains information about the highlighted position such as dataSetIndex etc.
-    @objc optional func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight)
-    
-    /// Called when a user stops panning between values on the chart
-    @objc optional func chartViewDidEndPanning(_ chartView: ChartViewBase)
-    
-    // Called when nothing has been selected or an "un-select" has been made.
-    @objc optional func chartValueNothingSelected(_ chartView: ChartViewBase)
-    
-    // Callbacks when the chart is scaled / zoomed via pinch zoom gesture.
-    @objc optional func chartScaled(_ chartView: ChartViewBase, scaleX: CGFloat, scaleY: CGFloat)
-    
-    // Callbacks when the chart is moved / translated via drag gesture.
-    @objc optional func chartTranslated(_ chartView: ChartViewBase, dX: CGFloat, dY: CGFloat)
-
-    // Callbacks when Animator stops animating
-    @objc optional func chartView(_ chartView: ChartViewBase, animatorDidStop animator: Animator)
-}
-
-open class ChartViewBase: NSUIView, ChartDataProvider, AnimatorDelegate
-{
-    // MARK: - Properties
-    
-    /// The default IValueFormatter that has been determined by the chart considering the provided minimum and maximum values.
-    internal lazy var defaultValueFormatter: ValueFormatter = DefaultValueFormatter(decimals: 0)
-
-    /// object that holds all data that was originally set for the chart, before it was modified or any filtering algorithms had been applied
-    @objc open var data: ChartData?
-        {
-        didSet
-        {
-            offsetsCalculated = false
-
-            guard let data = data else { return }
-
-            // calculate how many digits are needed
-            setupDefaultFormatter(min: data.yMin, max: data.yMax)
-
-            for set in data where set.valueFormatter is DefaultValueFormatter
-            {
-                set.valueFormatter = defaultValueFormatter
-            }
-
-            // let the chart know there is new data
-            notifyDataSetChanged()
-        }
-    }
-
-    /// If set to true, chart continues to scroll after touch up
-    @objc open var dragDecelerationEnabled = true
-
-    /// The object representing the labels on the x-axis
-    @objc open internal(set) lazy var xAxis = XAxis()
-    
-    /// The `Description` object of the chart.
-    @objc open lazy var chartDescription = Description()
-
-    /// The legend object containing all data associated with the legend
-    @objc open internal(set) lazy var legend = Legend()
-
-    /// delegate to receive chart events
-    @objc open weak var delegate: ChartViewDelegate?
-    
-    /// text that is displayed when the chart is empty
-    @objc open var noDataText = "No chart data available."
-    
-    /// Font to be used for the no data text.
-    @objc open var noDataFont = NSUIFont.systemFont(ofSize: 12)
-    
-    /// color of the no data text
-    @objc open var noDataTextColor: NSUIColor = .labelOrBlack
-
-    /// alignment of the no data text
-    @objc open var noDataTextAlignment: TextAlignment = .left
-
-    /// The renderer object responsible for rendering / drawing the Legend.
-    @objc open lazy var legendRenderer = LegendRenderer(viewPortHandler: viewPortHandler, legend: legend)
-
-    /// object responsible for rendering the data
-    @objc open var renderer: DataRenderer?
-    
-    @objc open var highlighter: Highlighter?
-
-    /// The ViewPortHandler of the chart that is responsible for the
-    /// content area of the chart and its offsets and dimensions.
-    @objc open internal(set) lazy var viewPortHandler = ViewPortHandler(width: bounds.size.width, height: bounds.size.height)
-
-    /// The animator responsible for animating chart values.
-    @objc open internal(set) lazy var chartAnimator: Animator = {
-        let animator = Animator()
-        animator.delegate = self
-        return animator
-    }()
-
-    /// flag that indicates if offsets calculation has already been done or not
-    private var offsetsCalculated = false
-
-    /// The array of currently highlighted values. This might an empty if nothing is highlighted.
-    @objc open internal(set) var highlighted = [Highlight]()
-    
-    /// `true` if drawing the marker is enabled when tapping on values
-    /// (use the `marker` property to specify a marker)
-    @objc open var drawMarkers = true
-    
-    /// - Returns: `true` if drawing the marker is enabled when tapping on values
-    /// (use the `marker` property to specify a marker)
-    @objc open var isDrawMarkersEnabled: Bool { return drawMarkers }
-    
-    /// The marker that is displayed when a value is clicked on the chart
-    @objc open var marker: Marker?
-
-    /// An extra offset to be appended to the viewport's top
-    @objc open var extraTopOffset: CGFloat = 0.0
-    
-    /// An extra offset to be appended to the viewport's right
-    @objc open var extraRightOffset: CGFloat = 0.0
-    
-    /// An extra offset to be appended to the viewport's bottom
-    @objc open var extraBottomOffset: CGFloat = 0.0
-    
-    /// An extra offset to be appended to the viewport's left
-    @objc open var extraLeftOffset: CGFloat = 0.0
-
-    @objc open func setExtraOffsets(left: CGFloat, top: CGFloat, right: CGFloat, bottom: CGFloat)
-    {
-        extraLeftOffset = left
-        extraTopOffset = top
-        extraRightOffset = right
-        extraBottomOffset = bottom
-    }
-    
-    // MARK: - Initializers
-    
-    public override init(frame: CGRect)
-    {
-        super.init(frame: frame)
-        initialize()
-    }
-    
-    public required init?(coder aDecoder: NSCoder)
-    {
-        super.init(coder: aDecoder)
-        initialize()
-    }
-    
-    deinit
-    {
-        removeObserver(self, forKeyPath: "bounds")
-        removeObserver(self, forKeyPath: "frame")
-    }
-    
-    internal func initialize()
-    {
-        #if os(iOS)
-            self.backgroundColor = .clear
-        #endif
-
-        addObserver(self, forKeyPath: "bounds", options: .new, context: nil)
-        addObserver(self, forKeyPath: "frame", options: .new, context: nil)
-    }
-    
-    // MARK: - ChartViewBase
-    
-    /// Clears the chart from all data (sets it to null) and refreshes it (by calling setNeedsDisplay()).
-    @objc open func clear()
-    {
-        data = nil
-        offsetsCalculated = false
-        highlighted.removeAll()
-        lastHighlighted = nil
-    
-        setNeedsDisplay()
-    }
-    
-    /// Removes all DataSets (and thereby Entries) from the chart. Does not set the data object to nil. Also refreshes the chart by calling setNeedsDisplay().
-    @objc open func clearValues()
-    {
-        data?.clearValues()
-        setNeedsDisplay()
-    }
-
-    /// - Returns: `true` if the chart is empty (meaning it's data object is either null or contains no entries).
-    @objc open func isEmpty() -> Bool
-    {
-        return data?.isEmpty ?? true
-    }
-    
-    /// Lets the chart know its underlying data has changed and should perform all necessary recalculations.
-    /// It is crucial that this method is called everytime data is changed dynamically. Not calling this method can lead to crashes or unexpected behaviour.
-    @objc open func notifyDataSetChanged()
-    {
-        fatalError("notifyDataSetChanged() cannot be called on ChartViewBase")
-    }
-    
-    /// Calculates the offsets of the chart to the border depending on the position of an eventual legend or depending on the length of the y-axis and x-axis labels and their position
-    internal func calculateOffsets()
-    {
-        fatalError("calculateOffsets() cannot be called on ChartViewBase")
-    }
-    
-    /// calcualtes the y-min and y-max value and the y-delta and x-delta value
-    internal func calcMinMax()
-    {
-        fatalError("calcMinMax() cannot be called on ChartViewBase")
-    }
-    
-    /// calculates the required number of digits for the values that might be drawn in the chart (if enabled), and creates the default value formatter
-    internal func setupDefaultFormatter(min: Double, max: Double)
-    {
-        // check if a custom formatter is set or not
-        var reference = 0.0
-        
-        if let data = data , data.entryCount >= 2
-        {
-            reference = abs(max - min)
-        }
-        else
-        {
-            reference = Swift.max(abs(min), abs(max))
-        }
-        
-    
-        if let formatter = defaultValueFormatter as? DefaultValueFormatter
-        {
-            // setup the formatter with a new number of digits
-            let digits = reference.decimalPlaces
-            formatter.decimals = digits
-        }
-    }
-    
-    open override func draw(_ rect: CGRect)
-    {
-        guard let context = NSUIGraphicsGetCurrentContext() else { return }
-
-        if data === nil && !noDataText.isEmpty
-        {
-            context.saveGState()
-            defer { context.restoreGState() }
-
-            let paragraphStyle = MutableParagraphStyle.default.mutableCopy() as! MutableParagraphStyle
-            paragraphStyle.minimumLineHeight = noDataFont.lineHeight
-            paragraphStyle.lineBreakMode = .byWordWrapping
-            paragraphStyle.alignment = noDataTextAlignment
-
-            context.drawMultilineText(noDataText,
-                                      at: CGPoint(x: bounds.width / 2.0, y: bounds.height / 2.0),
-                                      constrainedTo: bounds.size,
-                                      anchor: CGPoint(x: 0.5, y: 0.5),
-                                      angleRadians: 0.0,
-                                      attributes: [.font: noDataFont,
-                                                   .foregroundColor: noDataTextColor,
-                                                   .paragraphStyle: paragraphStyle])
-
-            return
-        }
-        
-        if !offsetsCalculated
-        {
-            calculateOffsets()
-            offsetsCalculated = true
-        }
-    }
-    
-    /// Draws the description text in the bottom right corner of the chart (per default)
-    internal func drawDescription(in context: CGContext)
-    {
-        let description = chartDescription
-
-        // check if description should be drawn
-        guard
-            description.isEnabled,
-            let descriptionText = description.text,
-            !descriptionText.isEmpty
-            else { return }
-        
-        let position = description.position ?? CGPoint(x: bounds.width - viewPortHandler.offsetRight - description.xOffset,
-                                                       y: bounds.height - viewPortHandler.offsetBottom - description.yOffset - description.font.lineHeight)
-
-        let attrs: [NSAttributedString.Key : Any] = [
-            .font: description.font,
-            .foregroundColor: description.textColor
-        ]
-
-        context.drawText(descriptionText,
-                         at: position,
-                         align: description.textAlign,
-                         attributes: attrs)
-    }
-    
-    // MARK: - Accessibility
-
-    open override func accessibilityChildren() -> [Any]? {
-        return renderer?.accessibleChartElements
-    }
-
-    // MARK: - Highlighting
-
-    /// Set this to false to prevent values from being highlighted by tap gesture.
-    /// Values can still be highlighted via drag or programmatically.
-    /// **default**: true
-    @objc open var highlightPerTapEnabled: Bool = true
-
-    /// `true` if values can be highlighted via tap gesture, `false` ifnot.
-    @objc open var isHighLightPerTapEnabled: Bool
-    {
-        return highlightPerTapEnabled
-    }
-    
-    /// Checks if the highlight array is null, has a length of zero or if the first object is null.
-    ///
-    /// - Returns: `true` if there are values to highlight, `false` ifthere are no values to highlight.
-    @objc open func valuesToHighlight() -> Bool
-    {
-        return !highlighted.isEmpty
-    }
-
-    /// Highlights the values at the given indices in the given DataSets. Provide
-    /// null or an empty array to undo all highlighting. 
-    /// This should be used to programmatically highlight values.
-    /// This method *will not* call the delegate.
-    @objc open func highlightValues(_ highs: [Highlight]?)
-    {
-        // set the indices to highlight
-        highlighted = highs ?? []
-
-        lastHighlighted = highlighted.first
-
-        // redraw the chart
-        setNeedsDisplay()
-    }
-    
-    /// Highlights any y-value at the given x-value in the given DataSet.
-    /// Provide -1 as the dataSetIndex to undo all highlighting.
-    /// This method will call the delegate.
-    ///
-    /// - Parameters:
-    ///   - x: The x-value to highlight
-    ///   - dataSetIndex: The dataset index to search in
-    ///   - dataIndex: The data index to search in (only used in CombinedChartView currently)
-    @objc open func highlightValue(x: Double, dataSetIndex: Int, dataIndex: Int = -1)
-    {
-        highlightValue(x: x, dataSetIndex: dataSetIndex, dataIndex: dataIndex, callDelegate: true)
-    }
-    
-    /// Highlights the value at the given x-value and y-value in the given DataSet.
-    /// Provide -1 as the dataSetIndex to undo all highlighting.
-    /// This method will call the delegate.
-    ///
-    /// - Parameters:
-    ///   - x: The x-value to highlight
-    ///   - y: The y-value to highlight. Supply `NaN` for "any"
-    ///   - dataSetIndex: The dataset index to search in
-    ///   - dataIndex: The data index to search in (only used in CombinedChartView currently)
-    @objc open func highlightValue(x: Double, y: Double, dataSetIndex: Int, dataIndex: Int = -1)
-    {
-        highlightValue(x: x, y: y, dataSetIndex: dataSetIndex, dataIndex: dataIndex, callDelegate: true)
-    }
-    
-    /// Highlights any y-value at the given x-value in the given DataSet.
-    /// Provide -1 as the dataSetIndex to undo all highlighting.
-    ///
-    /// - Parameters:
-    ///   - x: The x-value to highlight
-    ///   - dataSetIndex: The dataset index to search in
-    ///   - dataIndex: The data index to search in (only used in CombinedChartView currently)
-    ///   - callDelegate: Should the delegate be called for this change
-    @objc open func highlightValue(x: Double, dataSetIndex: Int, dataIndex: Int = -1, callDelegate: Bool)
-    {
-        highlightValue(x: x, y: .nan, dataSetIndex: dataSetIndex, dataIndex: dataIndex, callDelegate: callDelegate)
-    }
-    
-    /// Highlights the value at the given x-value and y-value in the given DataSet.
-    /// Provide -1 as the dataSetIndex to undo all highlighting.
-    ///
-    /// - Parameters:
-    ///   - x: The x-value to highlight
-    ///   - y: The y-value to highlight. Supply `NaN` for "any"
-    ///   - dataSetIndex: The dataset index to search in
-    ///   - dataIndex: The data index to search in (only used in CombinedChartView currently)
-    ///   - callDelegate: Should the delegate be called for this change
-    @objc open func highlightValue(x: Double, y: Double, dataSetIndex: Int, dataIndex: Int = -1, callDelegate: Bool)
-    {
-        guard let data = data else
-        {
-            Swift.print("Value not highlighted because data is nil")
-            return
-        }
-
-        if data.indices.contains(dataSetIndex)
-        {
-            highlightValue(Highlight(x: x, y: y, dataSetIndex: dataSetIndex, dataIndex: dataIndex), callDelegate: callDelegate)
-        }
-        else
-        {
-            highlightValue(nil, callDelegate: callDelegate)
-        }
-    }
-    
-    /// Highlights the values represented by the provided Highlight object
-    /// This method *will not* call the delegate.
-    ///
-    /// - Parameters:
-    ///   - highlight: contains information about which entry should be highlighted
-    @objc open func highlightValue(_ highlight: Highlight?)
-    {
-        highlightValue(highlight, callDelegate: false)
-    }
-
-    /// Highlights the value selected by touch gesture.
-    @objc open func highlightValue(_ highlight: Highlight?, callDelegate: Bool)
-    {
-        var high = highlight
-        guard
-            let h = high,
-            let entry = data?.entry(for: h)
-            else
-        {
-                high = nil
-                highlighted.removeAll(keepingCapacity: false)
-                if callDelegate
-                {
-                    delegate?.chartValueNothingSelected?(self)
-                }
-                setNeedsDisplay()
-                return
-        }
-
-        // set the indices to highlight
-       highlighted = [h]
-
-        if callDelegate
-        {
-            // notify the listener
-            delegate?.chartValueSelected?(self, entry: entry, highlight: h)
-        }
-
-        // redraw the chart
-        setNeedsDisplay()
-    }
-    
-    /// - Returns: The Highlight object (contains x-index and DataSet index) of the
-    /// selected value at the given touch point inside the Line-, Scatter-, or
-    /// CandleStick-Chart.
-    @objc open func getHighlightByTouchPoint(_ pt: CGPoint) -> Highlight?
-    {
-        guard data != nil else
-        {
-            Swift.print("Can't select by touch. No data set.")
-            return nil
-        }
-        
-        return self.highlighter?.getHighlight(x: pt.x, y: pt.y)
-    }
-
-    /// The last value that was highlighted via touch.
-    @objc open var lastHighlighted: Highlight?
-  
-    // MARK: - Markers
-
-    /// draws all MarkerViews on the highlighted positions
-    internal func drawMarkers(context: CGContext)
-    {
-        // if there is no marker view or drawing marker is disabled
-        guard
-            let marker = marker,
-            isDrawMarkersEnabled,
-            valuesToHighlight()
-            else { return }
-        
-        for highlight in highlighted
-        {
-            guard
-                let set = data?[highlight.dataSetIndex],
-                let e = data?.entry(for: highlight)
-                else { continue }
-            
-            let entryIndex = set.entryIndex(entry: e)
-            guard entryIndex <= Int(Double(set.entryCount) * chartAnimator.phaseX) else { continue }
-
-            let pos = getMarkerPosition(highlight: highlight)
-
-            // check bounds
-            guard viewPortHandler.isInBounds(x: pos.x, y: pos.y) else { continue }
-
-            // callbacks to update the content
-            marker.refreshContent(entry: e, highlight: highlight)
-            
-            // draw the marker
-            marker.draw(context: context, point: pos)
-        }
-    }
-    
-    /// - Returns: The actual position in pixels of the MarkerView for the given Entry in the given DataSet.
-    @objc open func getMarkerPosition(highlight: Highlight) -> CGPoint
-    {
-        return CGPoint(x: highlight.drawX, y: highlight.drawY)
-    }
-    
-    // MARK: - Animation
-
-    /// Animates the drawing / rendering of the chart on both x- and y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easingX: an easing function for the animation on the x axis
-    ///   - easingY: an easing function for the animation on the y axis
-    @objc open func animate(xAxisDuration: TimeInterval, yAxisDuration: TimeInterval, easingX: ChartEasingFunctionBlock?, easingY: ChartEasingFunctionBlock?)
-    {
-        chartAnimator.animate(xAxisDuration: xAxisDuration, yAxisDuration: yAxisDuration, easingX: easingX, easingY: easingY)
-    }
-    
-    /// Animates the drawing / rendering of the chart on both x- and y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easingOptionX: the easing function for the animation on the x axis
-    ///   - easingOptionY: the easing function for the animation on the y axis
-    @objc open func animate(xAxisDuration: TimeInterval, yAxisDuration: TimeInterval, easingOptionX: ChartEasingOption, easingOptionY: ChartEasingOption)
-    {
-        chartAnimator.animate(xAxisDuration: xAxisDuration, yAxisDuration: yAxisDuration, easingOptionX: easingOptionX, easingOptionY: easingOptionY)
-    }
-    
-    /// Animates the drawing / rendering of the chart on both x- and y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easing: an easing function for the animation
-    @objc open func animate(xAxisDuration: TimeInterval, yAxisDuration: TimeInterval, easing: ChartEasingFunctionBlock?)
-    {
-        chartAnimator.animate(xAxisDuration: xAxisDuration, yAxisDuration: yAxisDuration, easing: easing)
-    }
-    
-    /// Animates the drawing / rendering of the chart on both x- and y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easingOption: the easing function for the animation
-    @objc open func animate(xAxisDuration: TimeInterval, yAxisDuration: TimeInterval, easingOption: ChartEasingOption)
-    {
-        chartAnimator.animate(xAxisDuration: xAxisDuration, yAxisDuration: yAxisDuration, easingOption: easingOption)
-    }
-    
-    /// Animates the drawing / rendering of the chart on both x- and y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - yAxisDuration: duration for animating the y axis
-    @objc open func animate(xAxisDuration: TimeInterval, yAxisDuration: TimeInterval)
-    {
-        chartAnimator.animate(xAxisDuration: xAxisDuration, yAxisDuration: yAxisDuration)
-    }
-    
-    /// Animates the drawing / rendering of the chart the x-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - easing: an easing function for the animation
-    @objc open func animate(xAxisDuration: TimeInterval, easing: ChartEasingFunctionBlock?)
-    {
-        chartAnimator.animate(xAxisDuration: xAxisDuration, easing: easing)
-    }
-    
-    /// Animates the drawing / rendering of the chart the x-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    ///   - easingOption: the easing function for the animation
-    @objc open func animate(xAxisDuration: TimeInterval, easingOption: ChartEasingOption)
-    {
-        chartAnimator.animate(xAxisDuration: xAxisDuration, easingOption: easingOption)
-    }
-    
-    /// Animates the drawing / rendering of the chart the x-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - xAxisDuration: duration for animating the x axis
-    @objc open func animate(xAxisDuration: TimeInterval)
-    {
-        chartAnimator.animate(xAxisDuration: xAxisDuration)
-    }
-    
-    /// Animates the drawing / rendering of the chart the y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easing: an easing function for the animation
-    @objc open func animate(yAxisDuration: TimeInterval, easing: ChartEasingFunctionBlock?)
-    {
-        chartAnimator.animate(yAxisDuration: yAxisDuration, easing: easing)
-    }
-    
-    /// Animates the drawing / rendering of the chart the y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - yAxisDuration: duration for animating the y axis
-    ///   - easingOption: the easing function for the animation
-    @objc open func animate(yAxisDuration: TimeInterval, easingOption: ChartEasingOption)
-    {
-        chartAnimator.animate(yAxisDuration: yAxisDuration, easingOption: easingOption)
-    }
-    
-    /// Animates the drawing / rendering of the chart the y-axis with the specified animation time.
-    /// If `animate(...)` is called, no further calling of `invalidate()` is necessary to refresh the chart.
-    ///
-    /// - Parameters:
-    ///   - yAxisDuration: duration for animating the y axis
-    @objc open func animate(yAxisDuration: TimeInterval)
-    {
-        chartAnimator.animate(yAxisDuration: yAxisDuration)
-    }
-    
-    // MARK: - Accessors
-
-    /// The current y-max value across all DataSets
-    open var chartYMax: Double
-    {
-        return data?.yMax ?? 0.0
-    }
-
-    /// The current y-min value across all DataSets
-    open var chartYMin: Double
-    {
-        return data?.yMin ?? 0.0
-    }
-    
-    open var chartXMax: Double
-    {
-        return xAxis._axisMaximum
-    }
-    
-    open var chartXMin: Double
-    {
-        return xAxis._axisMinimum
-    }
-    
-    open var xRange: Double
-    {
-        return xAxis.axisRange
-    }
-    
-    /// - Note: (Equivalent of getCenter() in MPAndroidChart, as center is already a standard in iOS that returns the center point relative to superview, and MPAndroidChart returns relative to self)*
-    /// The center point of the chart (the whole View) in pixels.
-    @objc open var midPoint: CGPoint
-    {
-        return CGPoint(x: bounds.origin.x + bounds.size.width / 2.0, y: bounds.origin.y + bounds.size.height / 2.0)
-    }
-    
-    /// The center of the chart taking offsets under consideration. (returns the center of the content rectangle)
-    open var centerOffsets: CGPoint
-    {
-        return viewPortHandler.contentCenter
-    }
-
-    /// The rectangle that defines the borders of the chart-value surface (into which the actual values are drawn).
-    @objc open var contentRect: CGRect
-    {
-        return viewPortHandler.contentRect
-    }
-
-    /// - Returns: The bitmap that represents the chart.
-    @objc open func getChartImage(transparent: Bool) -> NSUIImage?
-    {
-        NSUIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque || !transparent, NSUIMainScreen()?.nsuiScale ?? 1.0)
-        
-        guard let context = NSUIGraphicsGetCurrentContext()
-            else { return nil }
-        
-        let rect = CGRect(origin: .zero, size: bounds.size)
-        
-        if isOpaque || !transparent
-        {
-            // Background color may be partially transparent, we must fill with white if we want to output an opaque image
-            context.setFillColor(NSUIColor.white.cgColor)
-            context.fill(rect)
-            
-            if let backgroundColor = self.backgroundColor
-            {
-                context.setFillColor(backgroundColor.cgColor)
-                context.fill(rect)
-            }
-        }
-        
-        nsuiLayer?.render(in: context)
-        
-        let image = NSUIGraphicsGetImageFromCurrentImageContext()
-        
-        NSUIGraphicsEndImageContext()
-        
-        return image
-    }
-    
-    public enum ImageFormat
-    {
-        case jpeg
-        case png
-    }
-    
-    /// Saves the current chart state with the given name to the given path on
-    /// the sdcard leaving the path empty "" will put the saved file directly on
-    /// the SD card chart is saved as a PNG image, example:
-    /// saveToPath("myfilename", "foldername1/foldername2")
-    ///
-    /// - Parameters:
-    ///   - to: path to the image to save
-    ///   - format: the format to save
-    ///   - compressionQuality: compression quality for lossless formats (JPEG)
-    /// - Returns: `true` if the image was saved successfully
-    open func save(to path: String, format: ImageFormat, compressionQuality: Double) -> Bool
-    {
-        guard let image = getChartImage(transparent: format != .jpeg) else { return false }
-        
-        let imageData: Data?
-        switch (format)
-        {
-        case .png: imageData = NSUIImagePNGRepresentation(image)
-        case .jpeg: imageData = NSUIImageJPEGRepresentation(image, CGFloat(compressionQuality))
-        }
-        
-        guard let data = imageData else { return false }
-        
-        do
-        {
-            try data.write(to: URL(fileURLWithPath: path), options: .atomic)
-        }
-        catch
-        {
-            return false
-        }
-        
-        return true
-    }
-    
-    internal var _viewportJobs = [ViewPortJob]()
-    
-    open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
-    {
-        if keyPath == "bounds" || keyPath == "frame"
-        {
-            let bounds = self.bounds
-            
-            if ((bounds.size.width != viewPortHandler.chartWidth ||
-                bounds.size.height != viewPortHandler.chartHeight))
-            {
-                viewPortHandler.setChartDimens(width: bounds.size.width, height: bounds.size.height)
-                
-                // This may cause the chart view to mutate properties affecting the view port -- lets do this
-                // before we try to run any pending jobs on the view port itself
-                notifyDataSetChanged()
-
-                // Finish any pending viewport changes
-                while (!_viewportJobs.isEmpty)
-                {
-                    let job = _viewportJobs.remove(at: 0)
-                    job.doJob()
-                }
-            }
-        }
-    }
-    
-    @objc open func removeViewportJob(_ job: ViewPortJob)
-    {
-        if let index = _viewportJobs.firstIndex(where: { $0 === job })
-        {
-            _viewportJobs.remove(at: index)
-        }
-    }
-    
-    @objc open func clearAllViewportJobs()
-    {
-        _viewportJobs.removeAll(keepingCapacity: false)
-    }
-    
-    @objc open func addViewportJob(_ job: ViewPortJob)
-    {
-        if viewPortHandler.hasChartDimens
-        {
-            job.doJob()
-        }
-        else
-        {
-            _viewportJobs.append(job)
-        }
-    }
-    
-    /// **default**: true
-    /// `true` if chart continues to scroll after touch up, `false` ifnot.
-    @objc open var isDragDecelerationEnabled: Bool
-        {
-            return dragDecelerationEnabled
-    }
-    
-    /// Deceleration friction coefficient in [0 ; 1] interval, higher values indicate that speed will decrease slowly, for example if it set to 0, it will stop immediately.
-    /// 1 is an invalid value, and will be converted to 0.999 automatically.
-    @objc open var dragDecelerationFrictionCoef: CGFloat
-    {
-        get
-        {
-            return _dragDecelerationFrictionCoef
-        }
-        set
-        {
-            _dragDecelerationFrictionCoef = max(0, min(newValue, 0.999))
-        }
-    }
-    private var _dragDecelerationFrictionCoef: CGFloat = 0.9
-    
-    /// The maximum distance in screen pixels away from an entry causing it to highlight.
-    /// **default**: 500.0
-    open var maxHighlightDistance: CGFloat = 500.0
-    
-    /// the number of maximum visible drawn values on the chart only active when `drawValuesEnabled` is enabled
-    open var maxVisibleCount: Int
-    {
-        return .max
-    }
-    
-    // MARK: - AnimatorDelegate
-    
-    open func animatorUpdated(_ chartAnimator: Animator)
-    {
-        setNeedsDisplay()
-    }
-    
-    open func animatorStopped(_ chartAnimator: Animator)
-    {
-        delegate?.chartView?(self, animatorDidStop: chartAnimator)
-    }
-    
-    // MARK: - Touches
-    
-    open override func nsuiTouchesBegan(_ touches: Set<NSUITouch>, withEvent event: NSUIEvent?)
-    {
-        super.nsuiTouchesBegan(touches, withEvent: event)
-    }
-    
-    open override func nsuiTouchesMoved(_ touches: Set<NSUITouch>, withEvent event: NSUIEvent?)
-    {
-        super.nsuiTouchesMoved(touches, withEvent: event)
-    }
-    
-    open override func nsuiTouchesEnded(_ touches: Set<NSUITouch>, withEvent event: NSUIEvent?)
-    {
-        super.nsuiTouchesEnded(touches, withEvent: event)
-    }
-    
-    open override func nsuiTouchesCancelled(_ touches: Set<NSUITouch>?, withEvent event: NSUIEvent?)
-    {
-        super.nsuiTouchesCancelled(touches, withEvent: event)
-    }
-}

+ 0 - 246
Pods/Charts/Source/Charts/Charts/CombinedChartView.swift

@@ -1,246 +0,0 @@
-//
-//  CombinedChartView.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-/// This chart class allows the combination of lines, bars, scatter and candle data all displayed in one chart area.
-open class CombinedChartView: BarLineChartViewBase, CombinedChartDataProvider
-{
-    /// the fill-formatter used for determining the position of the fill-line
-    internal var _fillFormatter: FillFormatter!
-    
-    /// enum that allows to specify the order in which the different data objects for the combined-chart are drawn
-    @objc(CombinedChartDrawOrder)
-    public enum DrawOrder: Int
-    {
-        case bar
-        case bubble
-        case line
-        case candle
-        case scatter
-    }
-    
-    open override func initialize()
-    {
-        super.initialize()
-        
-        self.highlighter = CombinedHighlighter(chart: self, barDataProvider: self)
-        
-        // Old default behaviour
-        self.highlightFullBarEnabled = true
-        
-        _fillFormatter = DefaultFillFormatter()
-        
-        renderer = CombinedChartRenderer(chart: self, animator: chartAnimator, viewPortHandler: viewPortHandler)
-    }
-    
-    open override var data: ChartData?
-    {
-        get
-        {
-            return super.data
-        }
-        set
-        {
-            super.data = newValue
-            
-            self.highlighter = CombinedHighlighter(chart: self, barDataProvider: self)
-            
-            (renderer as? CombinedChartRenderer)?.createRenderers()
-            renderer?.initBuffers()
-        }
-    }
-    
-    @objc open var fillFormatter: FillFormatter
-    {
-        get
-        {
-            return _fillFormatter
-        }
-        set
-        {
-            _fillFormatter = newValue
-            if _fillFormatter == nil
-            {
-                _fillFormatter = DefaultFillFormatter()
-            }
-        }
-    }
-    
-    /// - Returns: The Highlight object (contains x-index and DataSet index) of the selected value at the given touch point inside the CombinedChart.
-    open override func getHighlightByTouchPoint(_ pt: CGPoint) -> Highlight?
-    {
-        if data === nil
-        {
-            Swift.print("Can't select by touch. No data set.")
-            return nil
-        }
-        
-        guard let h = self.highlighter?.getHighlight(x: pt.x, y: pt.y)
-            else { return nil }
-        
-        if !isHighlightFullBarEnabled { return h }
-        
-        // For isHighlightFullBarEnabled, remove stackIndex
-        return Highlight(
-            x: h.x, y: h.y,
-            xPx: h.xPx, yPx: h.yPx,
-            dataIndex: h.dataIndex,
-            dataSetIndex: h.dataSetIndex,
-            stackIndex: -1,
-            axis: h.axis)
-    }
-    
-    // MARK: - CombinedChartDataProvider
-    
-    open var combinedData: CombinedChartData?
-    {
-        get
-        {
-            return data as? CombinedChartData
-        }
-    }
-    
-    // MARK: - LineChartDataProvider
-    
-    open var lineData: LineChartData?
-    {
-        get
-        {
-            return combinedData?.lineData
-        }
-    }
-    
-    // MARK: - BarChartDataProvider
-    
-    open var barData: BarChartData?
-    {
-        get
-        {
-            return combinedData?.barData
-        }
-    }
-    
-    // MARK: - ScatterChartDataProvider
-    
-    open var scatterData: ScatterChartData?
-    {
-        get
-        {
-            return combinedData?.scatterData
-        }
-    }
-    
-    // MARK: - CandleChartDataProvider
-    
-    open var candleData: CandleChartData?
-    {
-        get
-        {
-            return combinedData?.candleData
-        }
-    }
-    
-    // MARK: - BubbleChartDataProvider
-    
-    open var bubbleData: BubbleChartData?
-    {
-        get
-        {
-            return combinedData?.bubbleData
-        }
-    }
-    
-    // MARK: - Accessors
-    
-    /// if set to true, all values are drawn above their bars, instead of below their top
-    @objc open var drawValueAboveBarEnabled: Bool
-        {
-        get { return (renderer as! CombinedChartRenderer).drawValueAboveBarEnabled }
-        set { (renderer as! CombinedChartRenderer).drawValueAboveBarEnabled = newValue }
-    }
-    
-    /// if set to true, a grey area is drawn behind each bar that indicates the maximum value
-    @objc open var drawBarShadowEnabled: Bool
-    {
-        get { return (renderer as! CombinedChartRenderer).drawBarShadowEnabled }
-        set { (renderer as! CombinedChartRenderer).drawBarShadowEnabled = newValue }
-    }
-    
-    /// `true` if drawing values above bars is enabled, `false` ifnot
-    open var isDrawValueAboveBarEnabled: Bool { return (renderer as! CombinedChartRenderer).drawValueAboveBarEnabled }
-    
-    /// `true` if drawing shadows (maxvalue) for each bar is enabled, `false` ifnot
-    open var isDrawBarShadowEnabled: Bool { return (renderer as! CombinedChartRenderer).drawBarShadowEnabled }
-    
-    /// the order in which the provided data objects should be drawn.
-    /// The earlier you place them in the provided array, the further they will be in the background. 
-    /// e.g. if you provide [DrawOrder.Bar, DrawOrder.Line], the bars will be drawn behind the lines.
-    @objc open var drawOrder: [Int]
-    {
-        get
-        {
-            return (renderer as! CombinedChartRenderer).drawOrder.map { $0.rawValue }
-        }
-        set
-        {
-            (renderer as! CombinedChartRenderer).drawOrder = newValue.map { DrawOrder(rawValue: $0)! }
-        }
-    }
-    
-    /// Set this to `true` to make the highlight operation full-bar oriented, `false` to make it highlight single values
-    @objc open var highlightFullBarEnabled: Bool = false
-    
-    /// `true` the highlight is be full-bar oriented, `false` ifsingle-value
-    open var isHighlightFullBarEnabled: Bool { return highlightFullBarEnabled }
-    
-    // MARK: - ChartViewBase
-    
-    /// draws all MarkerViews on the highlighted positions
-    override func drawMarkers(context: CGContext)
-    {
-        guard
-            let marker = marker, 
-            isDrawMarkersEnabled && valuesToHighlight()
-            else { return }
-        
-        for i in highlighted.indices
-        {
-            let highlight = highlighted[i]
-            
-            guard 
-                let set = combinedData?.getDataSetByHighlight(highlight),
-                let e = data?.entry(for: highlight)
-                else { continue }
-            
-            let entryIndex = set.entryIndex(entry: e)
-            if entryIndex > Int(Double(set.entryCount) * chartAnimator.phaseX)
-            {
-                continue
-            }
-            
-            let pos = getMarkerPosition(highlight: highlight)
-            
-            // check bounds
-            if !viewPortHandler.isInBounds(x: pos.x, y: pos.y)
-            {
-                continue
-            }
-            
-            // callbacks to update the content
-            marker.refreshContent(entry: e, highlight: highlight)
-            
-            // draw the marker
-            marker.draw(context: context, point: pos)
-        }
-    }
-}

+ 0 - 269
Pods/Charts/Source/Charts/Charts/HorizontalBarChartView.swift

@@ -1,269 +0,0 @@
-//
-//  HorizontalBarChartView.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-/// BarChart with horizontal bar orientation. In this implementation, x- and y-axis are switched.
-open class HorizontalBarChartView: BarChartView
-{
-    internal override func initialize()
-    {
-        super.initialize()
-        
-        _leftAxisTransformer = TransformerHorizontalBarChart(viewPortHandler: viewPortHandler)
-        _rightAxisTransformer = TransformerHorizontalBarChart(viewPortHandler: viewPortHandler)
-
-        renderer = HorizontalBarChartRenderer(dataProvider: self, animator: chartAnimator, viewPortHandler: viewPortHandler)
-        leftYAxisRenderer = YAxisRendererHorizontalBarChart(viewPortHandler: viewPortHandler, axis: leftAxis, transformer: _leftAxisTransformer)
-        rightYAxisRenderer = YAxisRendererHorizontalBarChart(viewPortHandler: viewPortHandler, axis: rightAxis, transformer: _rightAxisTransformer)
-        xAxisRenderer = XAxisRendererHorizontalBarChart(viewPortHandler: viewPortHandler, axis: xAxis, transformer: _leftAxisTransformer, chart: self)
-
-        self.highlighter = HorizontalBarHighlighter(chart: self)
-    }
-    
-    internal override func calculateLegendOffsets(offsetLeft: inout CGFloat, offsetTop: inout CGFloat, offsetRight: inout CGFloat, offsetBottom: inout CGFloat)
-    {
-        guard
-            legend.isEnabled,
-            !legend.drawInside
-        else { return }
-        
-        // setup offsets for legend
-        switch legend.orientation
-        {
-        case .vertical:
-            switch legend.horizontalAlignment
-            {
-            case .left:
-                offsetLeft += min(legend.neededWidth, viewPortHandler.chartWidth * legend.maxSizePercent) + legend.xOffset
-                
-            case .right:
-                offsetRight += min(legend.neededWidth, viewPortHandler.chartWidth * legend.maxSizePercent) + legend.xOffset
-                
-            case .center:
-                
-                switch legend.verticalAlignment
-                {
-                case .top:
-                    offsetTop += min(legend.neededHeight, viewPortHandler.chartHeight * legend.maxSizePercent) + legend.yOffset
-                    
-                case .bottom:
-                    offsetBottom += min(legend.neededHeight, viewPortHandler.chartHeight * legend.maxSizePercent) + legend.yOffset
-                    
-                default:
-                    break
-                }
-            }
-            
-        case .horizontal:
-            switch legend.verticalAlignment
-            {
-            case .top:
-                offsetTop += min(legend.neededHeight, viewPortHandler.chartHeight * legend.maxSizePercent) + legend.yOffset
-                
-                // left axis equals the top x-axis in a horizontal chart
-                if leftAxis.isEnabled && leftAxis.isDrawLabelsEnabled
-                {
-                    offsetTop += leftAxis.getRequiredHeightSpace()
-                }
-                
-            case .bottom:
-                offsetBottom += min(legend.neededHeight, viewPortHandler.chartHeight * legend.maxSizePercent) + legend.yOffset
-
-                // right axis equals the bottom x-axis in a horizontal chart
-                if rightAxis.isEnabled && rightAxis.isDrawLabelsEnabled
-                {
-                    offsetBottom += rightAxis.getRequiredHeightSpace()
-                }
-            default:
-                break
-            }
-        }
-    }
-    
-    internal override func calculateOffsets()
-    {
-        var offsetLeft: CGFloat = 0.0,
-        offsetRight: CGFloat = 0.0,
-        offsetTop: CGFloat = 0.0,
-        offsetBottom: CGFloat = 0.0
-        
-        calculateLegendOffsets(offsetLeft: &offsetLeft,
-                               offsetTop: &offsetTop,
-                               offsetRight: &offsetRight,
-                               offsetBottom: &offsetBottom)
-        
-        // offsets for y-labels
-        if leftAxis.needsOffset
-        {
-            offsetTop += leftAxis.getRequiredHeightSpace()
-        }
-        
-        if rightAxis.needsOffset
-        {
-            offsetBottom += rightAxis.getRequiredHeightSpace()
-        }
-        
-        let xlabelwidth = xAxis.labelRotatedWidth
-        
-        if xAxis.isEnabled
-        {
-            // offsets for x-labels
-            if xAxis.labelPosition == .bottom
-            {
-                offsetLeft += xlabelwidth
-            }
-            else if xAxis.labelPosition == .top
-            {
-                offsetRight += xlabelwidth
-            }
-            else if xAxis.labelPosition == .bothSided
-            {
-                offsetLeft += xlabelwidth
-                offsetRight += xlabelwidth
-            }
-        }
-        
-        offsetTop += self.extraTopOffset
-        offsetRight += self.extraRightOffset
-        offsetBottom += self.extraBottomOffset
-        offsetLeft += self.extraLeftOffset
-
-        viewPortHandler.restrainViewPort(
-            offsetLeft: max(self.minOffset, offsetLeft),
-            offsetTop: max(self.minOffset, offsetTop),
-            offsetRight: max(self.minOffset, offsetRight),
-            offsetBottom: max(self.minOffset, offsetBottom))
-        
-        prepareOffsetMatrix()
-        prepareValuePxMatrix()
-    }
-    
-    internal override func prepareValuePxMatrix()
-    {
-        _rightAxisTransformer.prepareMatrixValuePx(chartXMin: rightAxis._axisMinimum, deltaX: CGFloat(rightAxis.axisRange), deltaY: CGFloat(xAxis.axisRange), chartYMin: xAxis._axisMinimum)
-        _leftAxisTransformer.prepareMatrixValuePx(chartXMin: leftAxis._axisMinimum, deltaX: CGFloat(leftAxis.axisRange), deltaY: CGFloat(xAxis.axisRange), chartYMin: xAxis._axisMinimum)
-    }
-    
-    open override func getMarkerPosition(highlight: Highlight) -> CGPoint
-    {
-        return CGPoint(x: highlight.drawY, y: highlight.drawX)
-    }
-    
-    open override func getBarBounds(entry e: BarChartDataEntry) -> CGRect
-    {
-        guard
-            let data = data as? BarChartData,
-            let set = data.getDataSetForEntry(e) as? BarChartDataSetProtocol
-            else { return .null }
-        
-        let y = e.y
-        let x = e.x
-        
-        let barWidth = data.barWidth
-        
-        let top = x - 0.5 + barWidth / 2.0
-        let bottom = x + 0.5 - barWidth / 2.0
-        let left = y >= 0.0 ? y : 0.0
-        let right = y <= 0.0 ? y : 0.0
-        
-        var bounds = CGRect(x: left, y: top, width: right - left, height: bottom - top)
-        
-        getTransformer(forAxis: set.axisDependency).rectValueToPixel(&bounds)
-        
-        return bounds
-    }
-    
-    open override func getPosition(entry e: ChartDataEntry, axis: YAxis.AxisDependency) -> CGPoint
-    {
-        var vals = CGPoint(x: CGFloat(e.y), y: CGFloat(e.x))
-        
-        getTransformer(forAxis: axis).pointValueToPixel(&vals)
-        
-        return vals
-    }
-
-    open override func getHighlightByTouchPoint(_ pt: CGPoint) -> Highlight?
-    {
-        if data === nil
-        {
-            Swift.print("Can't select by touch. No data set.", terminator: "\n")
-            return nil
-        }
-        
-        return self.highlighter?.getHighlight(x: pt.y, y: pt.x)
-    }
-    
-    /// The lowest x-index (value on the x-axis) that is still visible on he chart.
-    open override var lowestVisibleX: Double
-    {
-        var pt = CGPoint(
-            x: viewPortHandler.contentLeft,
-            y: viewPortHandler.contentBottom)
-        
-        getTransformer(forAxis: .left).pixelToValues(&pt)
-        
-        return max(xAxis._axisMinimum, Double(pt.y))
-    }
-    
-    /// The highest x-index (value on the x-axis) that is still visible on the chart.
-    open override var highestVisibleX: Double
-    {
-        var pt = CGPoint(
-            x: viewPortHandler.contentLeft,
-            y: viewPortHandler.contentTop)
-        
-        getTransformer(forAxis: .left).pixelToValues(&pt)
-        
-        return min(xAxis._axisMaximum, Double(pt.y))
-    }
-    
-    // MARK: - Viewport
-    
-    open override func setVisibleXRangeMaximum(_ maxXRange: Double)
-    {
-        let xScale = xAxis.axisRange / maxXRange
-        viewPortHandler.setMinimumScaleY(CGFloat(xScale))
-    }
-    
-    open override func setVisibleXRangeMinimum(_ minXRange: Double)
-    {
-        let xScale = xAxis.axisRange / minXRange
-        viewPortHandler.setMaximumScaleY(CGFloat(xScale))
-    }
-    
-    open override func setVisibleXRange(minXRange: Double, maxXRange: Double)
-    {
-        let minScale = xAxis.axisRange / minXRange
-        let maxScale = xAxis.axisRange / maxXRange
-        viewPortHandler.setMinMaxScaleY(minScaleY: CGFloat(minScale), maxScaleY: CGFloat(maxScale))
-    }
-    
-    open override func setVisibleYRangeMaximum(_ maxYRange: Double, axis: YAxis.AxisDependency)
-    {
-        let yScale = getAxisRange(axis: axis) / maxYRange
-        viewPortHandler.setMinimumScaleX(CGFloat(yScale))
-    }
-    
-    open override func setVisibleYRangeMinimum(_ minYRange: Double, axis: YAxis.AxisDependency)
-    {
-        let yScale = getAxisRange(axis: axis) / minYRange
-        viewPortHandler.setMaximumScaleX(CGFloat(yScale))
-    }
-    
-    open override func setVisibleYRange(minYRange: Double, maxYRange: Double, axis: YAxis.AxisDependency)
-    {
-        let minScale = getAxisRange(axis: axis) / minYRange
-        let maxScale = getAxisRange(axis: axis) / maxYRange
-        viewPortHandler.setMinMaxScaleX(minScaleX: CGFloat(minScale), maxScaleX: CGFloat(maxScale))
-    }
-}

+ 0 - 28
Pods/Charts/Source/Charts/Charts/LineChartView.swift

@@ -1,28 +0,0 @@
-//
-//  LineChartView.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-/// Chart that draws lines, surfaces, circles, ...
-open class LineChartView: BarLineChartViewBase, LineChartDataProvider
-{
-    internal override func initialize()
-    {
-        super.initialize()
-        
-        renderer = LineChartRenderer(dataProvider: self, animator: chartAnimator, viewPortHandler: viewPortHandler)
-    }
-    
-    // MARK: - LineChartDataProvider
-    
-    open var lineData: LineChartData? { return data as? LineChartData }
-}

+ 0 - 675
Pods/Charts/Source/Charts/Charts/PieChartView.swift

@@ -1,675 +0,0 @@
-//
-//  PieChartView.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-#if !os(OSX)
-    import UIKit
-#endif
-
-/// View that represents a pie chart. Draws cake like slices.
-open class PieChartView: PieRadarChartViewBase
-{
-    /// rect object that represents the bounds of the piechart, needed for drawing the circle
-    private var _circleBox = CGRect()
-    
-    /// flag indicating if entry labels should be drawn or not
-    private var _drawEntryLabelsEnabled = true
-    
-    /// array that holds the width of each pie-slice in degrees
-    private var _drawAngles = [CGFloat]()
-    
-    /// array that holds the absolute angle in degrees of each slice
-    private var _absoluteAngles = [CGFloat]()
-    
-    /// if true, the hole inside the chart will be drawn
-    private var _drawHoleEnabled = true
-    
-    private var _holeColor: NSUIColor? = NSUIColor.white
-    
-    /// Sets the color the entry labels are drawn with.
-    private var _entryLabelColor: NSUIColor? = NSUIColor.white
-    
-    /// Sets the font the entry labels are drawn with.
-    private var _entryLabelFont: NSUIFont? = NSUIFont(name: "HelveticaNeue", size: 13.0)
-    
-    /// if true, the hole will see-through to the inner tips of the slices
-    private var _drawSlicesUnderHoleEnabled = false
-    
-    /// if true, the values inside the piechart are drawn as percent values
-    private var _usePercentValuesEnabled = false
-    
-    /// variable for the text that is drawn in the center of the pie-chart
-    private var _centerAttributedText: NSAttributedString?
-    
-    /// the offset on the x- and y-axis the center text has in dp.
-    private var _centerTextOffset: CGPoint = CGPoint()
-    
-    /// indicates the size of the hole in the center of the piechart
-    ///
-    /// **default**: `0.5`
-    private var _holeRadiusPercent = CGFloat(0.5)
-    
-    private var _transparentCircleColor: NSUIColor? = NSUIColor(white: 1.0, alpha: 105.0/255.0)
-    
-    /// the radius of the transparent circle next to the chart-hole in the center
-    private var _transparentCircleRadiusPercent = CGFloat(0.55)
-    
-    /// if enabled, centertext is drawn
-    private var _drawCenterTextEnabled = true
-    
-    private var _centerTextRadiusPercent: CGFloat = 1.0
-    
-    /// maximum angle for this pie
-    private var _maxAngle: CGFloat = 360.0
-
-    public override init(frame: CGRect)
-    {
-        super.init(frame: frame)
-    }
-    
-    public required init?(coder aDecoder: NSCoder)
-    {
-        super.init(coder: aDecoder)
-    }
-    
-    internal override func initialize()
-    {
-        super.initialize()
-        
-        renderer = PieChartRenderer(chart: self, animator: chartAnimator, viewPortHandler: viewPortHandler)
-
-        self.highlighter = PieHighlighter(chart: self)
-    }
-    
-    open override func draw(_ rect: CGRect)
-    {
-        super.draw(rect)
-        
-        if data === nil
-        {
-            return
-        }
-        
-        let optionalContext = NSUIGraphicsGetCurrentContext()
-        guard let context = optionalContext, let renderer = renderer else
-        {
-            return
-        }
-        
-        renderer.drawData(context: context)
-        
-        if (valuesToHighlight())
-        {
-            renderer.drawHighlighted(context: context, indices: highlighted)
-        }
-        
-        renderer.drawExtras(context: context)
-        
-        renderer.drawValues(context: context)
-        
-        legendRenderer.renderLegend(context: context)
-        
-        drawDescription(in: context)
-        
-        drawMarkers(context: context)
-    }
-
-    /// if width is larger than height
-    private var widthLarger: Bool
-    {
-        return viewPortHandler.contentRect.orientation == .landscape
-    }
-
-    /// adjusted radius. Use diameter when it's half pie and width is larger
-    private var adjustedRadius: CGFloat
-    {
-        return maxAngle <= 180 && widthLarger ? diameter : diameter / 2.0
-    }
-
-    /// true centerOffsets considering half pie & width is larger
-    private func adjustedCenterOffsets() -> CGPoint
-    {
-        var c = self.centerOffsets
-        c.y = maxAngle <= 180 && widthLarger ? c.y + adjustedRadius / 2 : c.y
-        return c
-    }
-    
-    internal override func calculateOffsets()
-    {
-        super.calculateOffsets()
-        
-        // prevent nullpointer when no data set
-        if data === nil
-        {
-            return
-        }
-
-        let radius = adjustedRadius
-        
-        let c = adjustedCenterOffsets()
-        
-        let shift = (data as? PieChartData)?.dataSet?.selectionShift ?? 0.0
-        
-        // create the circle box that will contain the pie-chart (the bounds of the pie-chart)
-        _circleBox.origin.x = (c.x - radius) + shift
-        _circleBox.origin.y = (c.y - radius) + shift
-        _circleBox.size.width = radius * 2 - shift * 2.0
-        _circleBox.size.height = radius * 2 - shift * 2.0
-
-    }
-
-    internal override func calcMinMax()
-    {
-        calcAngles()
-    }
-
-    @objc open override func angleForPoint(x: CGFloat, y: CGFloat) -> CGFloat
-    {
-        let c = adjustedCenterOffsets()
-
-        let tx = Double(x - c.x)
-        let ty = Double(y - c.y)
-        let length = sqrt(tx * tx + ty * ty)
-        let r = acos(ty / length)
-
-        var angle = r.RAD2DEG
-
-        if x > c.x
-        {
-            angle = 360.0 - angle
-        }
-
-        // add 90° because chart starts EAST
-        angle = angle + 90.0
-
-        // neutralize overflow
-        if angle > 360.0
-        {
-            angle = angle - 360.0
-        }
-
-        return CGFloat(angle)
-    }
-
-    /// - Returns: The distance of a certain point on the chart to the center of the chart.
-    @objc open override func distanceToCenter(x: CGFloat, y: CGFloat) -> CGFloat
-    {
-        let c = adjustedCenterOffsets()
-        var dist = CGFloat(0.0)
-
-        let xDist = x > c.x ? x - c.x : c.x - x
-        let yDist = y > c.y ? y - c.y : c.y - y
-
-        // pythagoras
-        dist = sqrt(pow(xDist, 2.0) + pow(yDist, 2.0))
-
-        return dist
-    }
-
-    open override func getMarkerPosition(highlight: Highlight) -> CGPoint
-    {
-        let center = self.centerCircleBox
-        var r = self.radius
-        
-        var off = r / 10.0 * 3.6
-        
-        if self.isDrawHoleEnabled
-        {
-            off = (r - (r * self.holeRadiusPercent)) / 2.0
-        }
-        
-        r -= off // offset to keep things inside the chart
-        
-        let rotationAngle = self.rotationAngle
-        
-        let entryIndex = Int(highlight.x)
-        
-        // offset needed to center the drawn text in the slice
-        let offset = drawAngles[entryIndex] / 2.0
-        
-        // calculate the text position
-        let x = (r * cos(((rotationAngle + absoluteAngles[entryIndex] - offset) * CGFloat(chartAnimator.phaseY)).DEG2RAD) + center.x)
-        let y = (r * sin(((rotationAngle + absoluteAngles[entryIndex] - offset) * CGFloat(chartAnimator.phaseY)).DEG2RAD) + center.y)
-
-        return CGPoint(x: x, y: y)
-    }
-    
-    /// calculates the needed angles for the chart slices
-    private func calcAngles()
-    {
-        _drawAngles = [CGFloat]()
-        _absoluteAngles = [CGFloat]()
-        
-        guard let data = data else { return }
-
-        let entryCount = data.entryCount
-        
-        _drawAngles.reserveCapacity(entryCount)
-        _absoluteAngles.reserveCapacity(entryCount)
-        
-        let yValueSum = (data as! PieChartData).yValueSum
-
-        var cnt = 0
-
-        for set in data
-        {
-            for j in 0 ..< set.entryCount
-            {
-                guard let e = set.entryForIndex(j) else { continue }
-                
-                _drawAngles.append(calcAngle(value: abs(e.y), yValueSum: yValueSum))
-
-                if cnt == 0
-                {
-                    _absoluteAngles.append(_drawAngles[cnt])
-                }
-                else
-                {
-                    _absoluteAngles.append(_absoluteAngles[cnt - 1] + _drawAngles[cnt])
-                }
-
-                cnt += 1
-            }
-        }
-    }
-    
-    /// Checks if the given index is set to be highlighted.
-    @objc open func needsHighlight(index: Int) -> Bool
-    {
-        return highlighted.contains { Int($0.x) == index }
-    }
-    
-    /// calculates the needed angle for a given value
-    private func calcAngle(_ value: Double) -> CGFloat
-    {
-        return calcAngle(value: value, yValueSum: (data as! PieChartData).yValueSum)
-    }
-    
-    /// calculates the needed angle for a given value
-    private func calcAngle(value: Double, yValueSum: Double) -> CGFloat
-    {
-        return CGFloat(value) / CGFloat(yValueSum) * _maxAngle
-    }
-    
-    /// This will throw an exception, PieChart has no XAxis object.
-    open override var xAxis: XAxis
-    {
-        get { fatalError("PieChart has no XAxis") }
-        set { fatalError("PieChart has no XAxis") }
-    }
-
-    open override func indexForAngle(_ angle: CGFloat) -> Int
-    {
-        // TODO: Return nil instead of -1
-        // take the current angle of the chart into consideration
-        let a = (angle - self.rotationAngle).normalizedAngle
-        return _absoluteAngles.firstIndex { $0 > a } ?? -1
-    }
-    
-    /// - Returns: The index of the DataSet this x-index belongs to.
-    @objc open func dataSetIndexForIndex(_ xValue: Double) -> Int
-    {
-        // TODO: Return nil instead of -1
-        return data?.firstIndex {
-            $0.entryForXValue(xValue, closestToY: .nan) != nil
-        } ?? -1
-    }
-    
-    /// - Returns: An integer array of all the different angles the chart slices
-    /// have the angles in the returned array determine how much space (of 360°)
-    /// each slice takes
-    @objc open var drawAngles: [CGFloat]
-    {
-        return _drawAngles
-    }
-
-    /// - Returns: The absolute angles of the different chart slices (where the
-    /// slices end)
-    @objc open var absoluteAngles: [CGFloat]
-    {
-        return _absoluteAngles
-    }
-    
-    /// The color for the hole that is drawn in the center of the PieChart (if enabled).
-    /// 
-    /// - Note: Use holeTransparent with holeColor = nil to make the hole transparent.*
-    @objc open var holeColor: NSUIColor?
-    {
-        get
-        {
-            return _holeColor
-        }
-        set
-        {
-            _holeColor = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// if true, the hole will see-through to the inner tips of the slices
-    ///
-    /// **default**: `false`
-    @objc open var drawSlicesUnderHoleEnabled: Bool
-    {
-        get
-        {
-            return _drawSlicesUnderHoleEnabled
-        }
-        set
-        {
-            _drawSlicesUnderHoleEnabled = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// `true` if the inner tips of the slices are visible behind the hole, `false` if not.
-    @objc open var isDrawSlicesUnderHoleEnabled: Bool
-    {
-        return drawSlicesUnderHoleEnabled
-    }
-    
-    /// `true` if the hole in the center of the pie-chart is set to be visible, `false` ifnot
-    @objc open var drawHoleEnabled: Bool
-    {
-        get
-        {
-            return _drawHoleEnabled
-        }
-        set
-        {
-            _drawHoleEnabled = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// `true` if the hole in the center of the pie-chart is set to be visible, `false` ifnot
-    @objc open var isDrawHoleEnabled: Bool
-    {
-        get
-        {
-            return drawHoleEnabled
-        }
-    }
-    
-    /// the text that is displayed in the center of the pie-chart
-    @objc open var centerText: String?
-    {
-        get
-        {
-            return self.centerAttributedText?.string
-        }
-        set
-        {
-            var attrString: NSMutableAttributedString?
-            if newValue == nil
-            {
-                attrString = nil
-            }
-            else
-            {
-                let paragraphStyle = ParagraphStyle.default.mutableCopy() as! MutableParagraphStyle
-                paragraphStyle.lineBreakMode = .byTruncatingTail
-                paragraphStyle.alignment = .center
-                
-                attrString = NSMutableAttributedString(string: newValue!)
-                attrString?.setAttributes([
-                    .foregroundColor: NSUIColor.labelOrBlack,
-                    .font: NSUIFont.systemFont(ofSize: 12.0),
-                    .paragraphStyle: paragraphStyle
-                    ], range: NSMakeRange(0, attrString!.length))
-            }
-            self.centerAttributedText = attrString
-        }
-    }
-    
-    /// the text that is displayed in the center of the pie-chart
-    @objc open var centerAttributedText: NSAttributedString?
-    {
-        get
-        {
-            return _centerAttributedText
-        }
-        set
-        {
-            _centerAttributedText = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// Sets the offset the center text should have from it's original position in dp. Default x = 0, y = 0
-    @objc open var centerTextOffset: CGPoint
-    {
-        get
-        {
-            return _centerTextOffset
-        }
-        set
-        {
-            _centerTextOffset = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// `true` if drawing the center text is enabled
-    @objc open var drawCenterTextEnabled: Bool
-    {
-        get
-        {
-            return _drawCenterTextEnabled
-        }
-        set
-        {
-            _drawCenterTextEnabled = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// `true` if drawing the center text is enabled
-    @objc open var isDrawCenterTextEnabled: Bool
-    {
-        get
-        {
-            return drawCenterTextEnabled
-        }
-    }
-    
-    internal override var requiredLegendOffset: CGFloat
-    {
-        return legend.font.pointSize * 2.0
-    }
-    
-    internal override var requiredBaseOffset: CGFloat
-    {
-        return 0.0
-    }
-    
-    open override var radius: CGFloat
-    {
-        return _circleBox.width / 2.0
-    }
-    
-    /// The circlebox, the boundingbox of the pie-chart slices
-    @objc open var circleBox: CGRect
-    {
-        return _circleBox
-    }
-    
-    /// The center of the circlebox
-    @objc open var centerCircleBox: CGPoint
-    {
-        return CGPoint(x: _circleBox.midX, y: _circleBox.midY)
-    }
-    
-    /// the radius of the hole in the center of the piechart in percent of the maximum radius (max = the radius of the whole chart)
-    /// 
-    /// **default**: 0.5 (50%) (half the pie)
-    @objc open var holeRadiusPercent: CGFloat
-    {
-        get
-        {
-            return _holeRadiusPercent
-        }
-        set
-        {
-            _holeRadiusPercent = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// The color that the transparent-circle should have.
-    ///
-    /// **default**: `nil`
-    @objc open var transparentCircleColor: NSUIColor?
-    {
-        get
-        {
-            return _transparentCircleColor
-        }
-        set
-        {
-            _transparentCircleColor = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// the radius of the transparent circle that is drawn next to the hole in the piechart in percent of the maximum radius (max = the radius of the whole chart)
-    /// 
-    /// **default**: 0.55 (55%) -> means 5% larger than the center-hole by default
-    @objc open var transparentCircleRadiusPercent: CGFloat
-    {
-        get
-        {
-            return _transparentCircleRadiusPercent
-        }
-        set
-        {
-            _transparentCircleRadiusPercent = newValue
-            setNeedsDisplay()
-        }
-    }
-        
-    /// The color the entry labels are drawn with.
-    @objc open var entryLabelColor: NSUIColor?
-    {
-        get { return _entryLabelColor }
-        set
-        {
-            _entryLabelColor = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// The font the entry labels are drawn with.
-    @objc open var entryLabelFont: NSUIFont?
-    {
-        get { return _entryLabelFont }
-        set
-        {
-            _entryLabelFont = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// Set this to true to draw the enrty labels into the pie slices
-    @objc open var drawEntryLabelsEnabled: Bool
-    {
-        get
-        {
-            return _drawEntryLabelsEnabled
-        }
-        set
-        {
-            _drawEntryLabelsEnabled = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// `true` if drawing entry labels is enabled, `false` ifnot
-    @objc open var isDrawEntryLabelsEnabled: Bool
-    {
-        get
-        {
-            return drawEntryLabelsEnabled
-        }
-    }
-    
-    /// If this is enabled, values inside the PieChart are drawn in percent and not with their original value. Values provided for the ValueFormatter to format are then provided in percent.
-    @objc open var usePercentValuesEnabled: Bool
-    {
-        get
-        {
-            return _usePercentValuesEnabled
-        }
-        set
-        {
-            _usePercentValuesEnabled = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// `true` if drawing x-values is enabled, `false` ifnot
-    @objc open var isUsePercentValuesEnabled: Bool
-    {
-        get
-        {
-            return usePercentValuesEnabled
-        }
-    }
-    
-    /// the rectangular radius of the bounding box for the center text, as a percentage of the pie hole
-    @objc open var centerTextRadiusPercent: CGFloat
-    {
-        get
-        {
-            return _centerTextRadiusPercent
-        }
-        set
-        {
-            _centerTextRadiusPercent = newValue
-            setNeedsDisplay()
-        }
-    }
-    
-    /// The max angle that is used for calculating the pie-circle.
-    /// 360 means it's a full pie-chart, 180 results in a half-pie-chart.
-    /// **default**: 360.0
-    @objc open var maxAngle: CGFloat
-    {
-        get
-        {
-            return _maxAngle
-        }
-        set
-        {
-            _maxAngle = newValue
-            
-            if _maxAngle > 360.0
-            {
-                _maxAngle = 360.0
-            }
-            
-            if _maxAngle < 90.0
-            {
-                _maxAngle = 90.0
-            }
-        }
-    }
-    
-    /// smallest pie slice angle that will have a label drawn in degrees, 0 by default
-    @objc open var sliceTextDrawingThreshold: CGFloat = 0.0
-    {
-        didSet {
-            setNeedsDisplay()
-        }
-    }
-}

+ 0 - 854
Pods/Charts/Source/Charts/Charts/PieRadarChartViewBase.swift

@@ -1,854 +0,0 @@
-//
-//  PieRadarChartViewBase.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-import QuartzCore
-
-#if canImport(AppKit)
-import AppKit
-#endif
-
-
-/// Base class of PieChartView and RadarChartView.
-open class PieRadarChartViewBase: ChartViewBase
-{
-    /// holds the normalized version of the current rotation angle of the chart
-    private var _rotationAngle = CGFloat(270.0)
-    
-    /// holds the raw version of the current rotation angle of the chart
-    private var _rawRotationAngle = CGFloat(270.0)
-    
-    /// flag that indicates if rotation is enabled or not
-    @objc open var rotationEnabled = true
-    
-    /// Sets the minimum offset (padding) around the chart, defaults to 0.0
-    @objc open var minOffset = CGFloat(0.0)
-
-    /// iOS && OSX only: Enabled multi-touch rotation using two fingers.
-    private var _rotationWithTwoFingers = false
-    
-    private var _tapGestureRecognizer: NSUITapGestureRecognizer!
-    #if !os(tvOS)
-    private var _rotationGestureRecognizer: NSUIRotationGestureRecognizer!
-    #endif
-    
-    public override init(frame: CGRect)
-    {
-        super.init(frame: frame)
-    }
-    
-    public required init?(coder aDecoder: NSCoder)
-    {
-        super.init(coder: aDecoder)
-    }
-    
-    deinit
-    {
-        stopDeceleration()
-    }
-    
-    internal override func initialize()
-    {
-        super.initialize()
-        
-        _tapGestureRecognizer = NSUITapGestureRecognizer(target: self, action: #selector(tapGestureRecognized(_:)))
-        
-        self.addGestureRecognizer(_tapGestureRecognizer)
-
-        #if !os(tvOS)
-        _rotationGestureRecognizer = NSUIRotationGestureRecognizer(target: self, action: #selector(rotationGestureRecognized(_:)))
-        self.addGestureRecognizer(_rotationGestureRecognizer)
-        _rotationGestureRecognizer.isEnabled = rotationWithTwoFingers
-        #endif
-    }
-    
-    internal override func calcMinMax()
-    {
-        /*_xAxis.axisRange = Double((data?.xVals.count ?? 0) - 1)*/
-    }
-    
-    open override var maxVisibleCount: Int
-    {
-        get
-        {
-            return data?.entryCount ?? 0
-        }
-    }
-    
-    open override func notifyDataSetChanged()
-    {
-        calcMinMax()
-        
-        if let data = data
-        {
-            legendRenderer.computeLegend(data: data)
-        }
-        
-        calculateOffsets()
-        
-        setNeedsDisplay()
-    }
-  
-    internal override func calculateOffsets()
-    {
-        var legendLeft = CGFloat(0.0)
-        var legendRight = CGFloat(0.0)
-        var legendBottom = CGFloat(0.0)
-        var legendTop = CGFloat(0.0)
-
-        if legend.enabled && !legend.drawInside
-        {
-            let fullLegendWidth = min(legend.neededWidth, viewPortHandler.chartWidth * legend.maxSizePercent)
-            
-            switch legend.orientation
-            {
-            case .vertical:
-                
-                var xLegendOffset: CGFloat = 0.0
-                
-                if legend.horizontalAlignment == .left
-                    || legend.horizontalAlignment == .right
-                {
-                    if legend.verticalAlignment == .center
-                    {
-                        // this is the space between the legend and the chart
-                        let spacing = CGFloat(13.0)
-                        
-                        xLegendOffset = fullLegendWidth + spacing
-                    }
-                    else
-                    {
-                        // this is the space between the legend and the chart
-                        let spacing = CGFloat(8.0)
-                        
-                        let legendWidth = fullLegendWidth + spacing
-                        let legendHeight = legend.neededHeight + legend.textHeightMax
-                        
-                        let c = self.midPoint
-                        
-                        let bottomX = legend.horizontalAlignment == .right
-                            ? self.bounds.width - legendWidth + 15.0
-                            : legendWidth - 15.0
-                        let bottomY = legendHeight + 15
-                        let distLegend = distanceToCenter(x: bottomX, y: bottomY)
-                        
-                        let reference = getPosition(center: c, dist: self.radius,
-                                                    angle: angleForPoint(x: bottomX, y: bottomY))
-                        
-                        let distReference = distanceToCenter(x: reference.x, y: reference.y)
-                        let minOffset = CGFloat(5.0)
-                        
-                        if bottomY >= c.y
-                            && self.bounds.height - legendWidth > self.bounds.width
-                        {
-                            xLegendOffset = legendWidth
-                        }
-                        else if distLegend < distReference
-                        {
-                            let diff = distReference - distLegend
-                            xLegendOffset = minOffset + diff
-                        }
-                    }
-                }
-                
-                switch legend.horizontalAlignment
-                {
-                case .left:
-                    legendLeft = xLegendOffset
-                    
-                case .right:
-                    legendRight = xLegendOffset
-                    
-                case .center:
-                    
-                    switch legend.verticalAlignment
-                    {
-                    case .top:
-                        legendTop = min(legend.neededHeight, viewPortHandler.chartHeight * legend.maxSizePercent)
-                        
-                    case .bottom:
-                        legendBottom = min(legend.neededHeight, viewPortHandler.chartHeight * legend.maxSizePercent)
-                        
-                    default:
-                        break
-                    }
-                }
-            
-            case .horizontal:
-                
-                var yLegendOffset: CGFloat = 0.0
-                
-                if legend.verticalAlignment == .top
-                    || legend.verticalAlignment == .bottom
-                {
-                    // It's possible that we do not need this offset anymore as it
-                    //   is available through the extraOffsets, but changing it can mean
-                    //   changing default visibility for existing apps.
-                    let yOffset = self.requiredLegendOffset
-                    
-                    yLegendOffset = min(
-                        legend.neededHeight + yOffset,
-                        viewPortHandler.chartHeight * legend.maxSizePercent)
-                }
-                
-                switch legend.verticalAlignment
-                {
-                case .top:
-                    
-                    legendTop = yLegendOffset
-                    
-                case .bottom:
-                    
-                    legendBottom = yLegendOffset
-                    
-                default:
-                    break
-                }
-            }
-
-            legendLeft += self.requiredBaseOffset
-            legendRight += self.requiredBaseOffset
-            legendTop += self.requiredBaseOffset
-            legendBottom += self.requiredBaseOffset
-        }
-        
-        legendTop += self.extraTopOffset
-        legendRight += self.extraRightOffset
-        legendBottom += self.extraBottomOffset
-        legendLeft += self.extraLeftOffset
-        
-        var minOffset = self.minOffset
-        
-        if self is RadarChartView
-        {
-            let x = self.xAxis
-            
-            if x.isEnabled && x.drawLabelsEnabled
-            {
-                minOffset = max(minOffset, x.labelRotatedWidth)
-            }
-        }
-
-        let offsetLeft = max(minOffset, legendLeft)
-        let offsetTop = max(minOffset, legendTop)
-        let offsetRight = max(minOffset, legendRight)
-        let offsetBottom = max(minOffset, max(self.requiredBaseOffset, legendBottom))
-
-        viewPortHandler.restrainViewPort(offsetLeft: offsetLeft, offsetTop: offsetTop, offsetRight: offsetRight, offsetBottom: offsetBottom)
-    }
-
-    /// - Returns: The angle relative to the chart center for the given point on the chart in degrees.
-    /// The angle is always between 0 and 360°, 0° is NORTH, 90° is EAST, ...
-    @objc open func angleForPoint(x: CGFloat, y: CGFloat) -> CGFloat
-    {
-        let c = centerOffsets
-        
-        let tx = Double(x - c.x)
-        let ty = Double(y - c.y)
-        let length = sqrt(tx * tx + ty * ty)
-        let r = acos(ty / length)
-
-        var angle = r.RAD2DEG
-
-        if x > c.x
-        {
-            angle = 360.0 - angle
-        }
-
-        // add 90° because chart starts EAST
-        angle = angle + 90.0
-
-        // neutralize overflow
-        if angle > 360.0
-        {
-            angle = angle - 360.0
-        }
-
-        return CGFloat(angle)
-    }
-    
-    /// Calculates the position around a center point, depending on the distance
-    /// from the center, and the angle of the position around the center.
-    @objc open func getPosition(center: CGPoint, dist: CGFloat, angle: CGFloat) -> CGPoint
-    {
-        return CGPoint(x: center.x + dist * cos(angle.DEG2RAD),
-                y: center.y + dist * sin(angle.DEG2RAD))
-    }
-
-    /// - Returns: The distance of a certain point on the chart to the center of the chart.
-    @objc open func distanceToCenter(x: CGFloat, y: CGFloat) -> CGFloat
-    {
-        let c = self.centerOffsets
-
-        var dist = CGFloat(0.0)
-
-        var xDist = CGFloat(0.0)
-        var yDist = CGFloat(0.0)
-
-        if x > c.x
-        {
-            xDist = x - c.x
-        }
-        else
-        {
-            xDist = c.x - x
-        }
-
-        if y > c.y
-        {
-            yDist = y - c.y
-        }
-        else
-        {
-            yDist = c.y - y
-        }
-
-        // pythagoras
-        dist = sqrt(pow(xDist, 2.0) + pow(yDist, 2.0))
-
-        return dist
-    }
-
-    /// - Returns: The xIndex for the given angle around the center of the chart.
-    /// -1 if not found / outofbounds.
-    @objc open func indexForAngle(_ angle: CGFloat) -> Int
-    {
-        fatalError("indexForAngle() cannot be called on PieRadarChartViewBase")
-    }
-
-    /// current rotation angle of the pie chart
-    ///
-    /// **default**: 270 --> top (NORTH)
-    /// Will always return a normalized value, which will be between 0.0 < 360.0
-    @objc open var rotationAngle: CGFloat
-    {
-        get
-        {
-            return _rotationAngle
-        }
-        set
-        {
-            _rawRotationAngle = newValue
-            _rotationAngle = newValue.normalizedAngle
-            setNeedsDisplay()
-        }
-    }
-    
-    /// gets the raw version of the current rotation angle of the pie chart the returned value could be any value, negative or positive, outside of the 360 degrees. 
-    /// this is used when working with rotation direction, mainly by gestures and animations.
-    @objc open var rawRotationAngle: CGFloat
-    {
-        return _rawRotationAngle
-    }
-
-    /// The diameter of the pie- or radar-chart
-    @objc open var diameter: CGFloat
-    {
-        var content = viewPortHandler.contentRect
-        content.origin.x += extraLeftOffset
-        content.origin.y += extraTopOffset
-        content.size.width -= extraLeftOffset + extraRightOffset
-        content.size.height -= extraTopOffset + extraBottomOffset
-        return min(content.width, content.height)
-    }
-
-    /// The radius of the chart in pixels.
-    @objc open var radius: CGFloat
-    {
-        fatalError("radius cannot be called on PieRadarChartViewBase")
-    }
-
-    /// The required offset for the chart legend.
-    internal var requiredLegendOffset: CGFloat
-    {
-        fatalError("requiredLegendOffset cannot be called on PieRadarChartViewBase")
-    }
-
-    /// - Returns: The base offset needed for the chart without calculating the
-    /// legend size.
-    internal var requiredBaseOffset: CGFloat
-    {
-        fatalError("requiredBaseOffset cannot be called on PieRadarChartViewBase")
-    }
-    
-    open override var chartYMax: Double
-    {
-        return 0.0
-    }
-    
-    open override var chartYMin: Double
-    {
-        return 0.0
-    }
-    
-    @objc open var isRotationEnabled: Bool { return rotationEnabled }
-    
-    /// flag that indicates if rotation is done with two fingers or one.
-    /// when the chart is inside a scrollview, you need a two-finger rotation because a one-finger rotation eats up all touch events.
-    ///
-    /// On iOS this will disable one-finger rotation.
-    /// On OSX this will keep two-finger multitouch rotation, and one-pointer mouse rotation.
-    /// 
-    /// **default**: false
-    @objc open var rotationWithTwoFingers: Bool
-    {
-        get
-        {
-            return _rotationWithTwoFingers
-        }
-        set
-        {
-            _rotationWithTwoFingers = newValue
-            #if !os(tvOS)
-            _rotationGestureRecognizer.isEnabled = _rotationWithTwoFingers
-            #endif
-        }
-    }
-    
-    /// flag that indicates if rotation is done with two fingers or one.
-    /// when the chart is inside a scrollview, you need a two-finger rotation because a one-finger rotation eats up all touch events.
-    ///
-    /// On iOS this will disable one-finger rotation.
-    /// On OSX this will keep two-finger multitouch rotation, and one-pointer mouse rotation.
-    ///
-    /// **default**: false
-    @objc open var isRotationWithTwoFingers: Bool
-    {
-        return _rotationWithTwoFingers
-    }
-    
-    // MARK: - Animation
-    
-    private var _spinAnimator: Animator!
-    
-    /// Applys a spin animation to the Chart.
-    @objc open func spin(duration: TimeInterval, fromAngle: CGFloat, toAngle: CGFloat, easing: ChartEasingFunctionBlock?)
-    {
-        if _spinAnimator != nil
-        {
-            _spinAnimator.stop()
-        }
-        
-        _spinAnimator = Animator()
-        _spinAnimator.updateBlock = {
-            self.rotationAngle = (toAngle - fromAngle) * CGFloat(self._spinAnimator.phaseX) + fromAngle
-        }
-        _spinAnimator.stopBlock = { self._spinAnimator = nil }
-        
-        _spinAnimator.animate(xAxisDuration: duration, easing: easing)
-    }
-    
-    @objc open func spin(duration: TimeInterval, fromAngle: CGFloat, toAngle: CGFloat, easingOption: ChartEasingOption)
-    {
-        spin(duration: duration, fromAngle: fromAngle, toAngle: toAngle, easing: easingFunctionFromOption(easingOption))
-    }
-    
-    @objc open func spin(duration: TimeInterval, fromAngle: CGFloat, toAngle: CGFloat)
-    {
-        spin(duration: duration, fromAngle: fromAngle, toAngle: toAngle, easing: nil)
-    }
-    
-    @objc open func stopSpinAnimation()
-    {
-        if _spinAnimator != nil
-        {
-            _spinAnimator.stop()
-        }
-    }
-    
-    // MARK: - Gestures
-    
-    private var _rotationGestureStartPoint: CGPoint!
-    private var _isRotating = false
-    private var _startAngle = CGFloat(0.0)
-    
-    private struct AngularVelocitySample
-    {
-        var time: TimeInterval
-        var angle: CGFloat
-    }
-    
-    private var velocitySamples = [AngularVelocitySample]()
-    
-    private var _decelerationLastTime: TimeInterval = 0.0
-    private var _decelerationDisplayLink: NSUIDisplayLink!
-    private var _decelerationAngularVelocity: CGFloat = 0.0
-    
-    internal final func processRotationGestureBegan(location: CGPoint)
-    {
-        self.resetVelocity()
-        
-        if rotationEnabled
-        {
-            self.sampleVelocity(touchLocation: location)
-        }
-        
-        self.setGestureStartAngle(x: location.x, y: location.y)
-        
-        _rotationGestureStartPoint = location
-    }
-    
-    internal final func processRotationGestureMoved(location: CGPoint)
-    {
-        if isDragDecelerationEnabled
-        {
-            sampleVelocity(touchLocation: location)
-        }
-        
-        if !_isRotating &&
-            distance(
-                eventX: location.x,
-                startX: _rotationGestureStartPoint.x,
-                eventY: location.y,
-                startY: _rotationGestureStartPoint.y) > CGFloat(8.0)
-        {
-            _isRotating = true
-        }
-        else
-        {
-            self.updateGestureRotation(x: location.x, y: location.y)
-            setNeedsDisplay()
-        }
-    }
-    
-    internal final func processRotationGestureEnded(location: CGPoint)
-    {
-        if isDragDecelerationEnabled
-        {
-            stopDeceleration()
-            
-            sampleVelocity(touchLocation: location)
-            
-            _decelerationAngularVelocity = calculateVelocity()
-            
-            if _decelerationAngularVelocity != 0.0
-            {
-                _decelerationLastTime = CACurrentMediaTime()
-                _decelerationDisplayLink = NSUIDisplayLink(target: self, selector: #selector(PieRadarChartViewBase.decelerationLoop))
-                _decelerationDisplayLink.add(to: RunLoop.main, forMode: RunLoop.Mode.common)
-            }
-        }
-    }
-    
-    internal final func processRotationGestureCancelled()
-    {
-        if _isRotating
-        {
-            _isRotating = false
-        }
-    }
-    
-    #if !os(OSX)
-    open override func nsuiTouchesBegan(_ touches: Set<NSUITouch>, withEvent event: NSUIEvent?)
-    {
-        // if rotation by touch is enabled
-        if rotationEnabled
-        {
-            stopDeceleration()
-            
-            if !rotationWithTwoFingers, let touchLocation = touches.first?.location(in: self)
-            {
-                processRotationGestureBegan(location: touchLocation)
-            }
-        }
-        
-        if !_isRotating
-        {
-            super.nsuiTouchesBegan(touches, withEvent: event)
-        }
-    }
-    
-    open override func nsuiTouchesMoved(_ touches: Set<NSUITouch>, withEvent event: NSUIEvent?)
-    {
-        if rotationEnabled && !rotationWithTwoFingers, let touch = touches.first
-        {
-            let touchLocation = touch.location(in: self)
-            processRotationGestureMoved(location: touchLocation)
-        }
-        
-        if !_isRotating
-        {
-            super.nsuiTouchesMoved(touches, withEvent: event)
-        }
-    }
-    
-    open override func nsuiTouchesEnded(_ touches: Set<NSUITouch>, withEvent event: NSUIEvent?)
-    {
-        if !_isRotating
-        {
-            super.nsuiTouchesEnded(touches, withEvent: event)
-        }
-        
-        if rotationEnabled && !rotationWithTwoFingers, let touch = touches.first
-        {
-            let touchLocation = touch.location(in: self)
-            processRotationGestureEnded(location: touchLocation)
-        }
-        
-        if _isRotating
-        {
-            _isRotating = false
-        }
-    }
-    
-    open override func nsuiTouchesCancelled(_ touches: Set<NSUITouch>?, withEvent event: NSUIEvent?)
-    {
-        super.nsuiTouchesCancelled(touches, withEvent: event)
-        
-        processRotationGestureCancelled()
-    }
-    #endif
-    
-    #if os(OSX)
-    open override func mouseDown(with theEvent: NSEvent)
-    {
-        // if rotation by touch is enabled
-        if rotationEnabled
-        {
-            stopDeceleration()
-        
-            let location = self.convert(theEvent.locationInWindow, from: nil)
-            
-            processRotationGestureBegan(location: location)
-        }
-        
-        if !_isRotating
-        {
-            super.mouseDown(with: theEvent)
-        }
-    }
-    
-    open override func mouseDragged(with theEvent: NSEvent)
-    {
-        if rotationEnabled
-        {
-            let location = self.convert(theEvent.locationInWindow, from: nil)
-            
-            processRotationGestureMoved(location: location)
-        }
-        
-        if !_isRotating
-        {
-            super.mouseDragged(with: theEvent)
-        }
-    }
-    
-    open override func mouseUp(with theEvent: NSEvent)
-    {
-        if !_isRotating
-        {
-            super.mouseUp(with: theEvent)
-        }
-        
-        if rotationEnabled
-        {
-            let location = self.convert(theEvent.locationInWindow, from: nil)
-            
-            processRotationGestureEnded(location: location)
-        }
-        
-        if _isRotating
-        {
-            _isRotating = false
-        }
-    }
-    #endif
-    
-    private func resetVelocity()
-    {
-        velocitySamples.removeAll(keepingCapacity: false)
-    }
-    
-    private func sampleVelocity(touchLocation: CGPoint)
-    {
-        let currentSample: AngularVelocitySample = {
-            let time = CACurrentMediaTime()
-            let angle = angleForPoint(x: touchLocation.x, y: touchLocation.y)
-            return AngularVelocitySample(time: time, angle: angle)
-        }()
-
-        // Remove samples older than our sample time - 1 seconds
-        // while keeping at least one sample
-        var i = 0, count = velocitySamples.count
-        while (i < count - 2)
-        {
-            if currentSample.time - velocitySamples[i].time > 1.0
-            {
-                velocitySamples.remove(at: 0)
-                i -= 1
-                count -= 1
-            }
-            else
-            {
-                break
-            }
-
-            i += 1
-        }
-
-        velocitySamples.append(currentSample)
-    }
-
-    private func calculateVelocity() -> CGFloat
-    {
-        guard var firstSample = velocitySamples.first,
-            var lastSample = velocitySamples.last
-            else { return 0 }
-
-        // Look for a sample that's closest to the latest sample, but not the same, so we can deduce the direction
-        let beforeLastSample = velocitySamples.last { $0.angle != lastSample.angle }
-            ?? firstSample
-
-        // Calculate the sampling time
-        let timeDelta: CGFloat = {
-            let delta = CGFloat(lastSample.time - firstSample.time)
-            return delta == 0 ? 0.1 : delta
-        }()
-
-        // Calculate clockwise/ccw by choosing two values that should be closest to each other,
-        // so if the angles are two far from each other we know they are inverted "for sure"
-        let isClockwise: Bool = {
-            let isClockwise = lastSample.angle >= beforeLastSample.angle
-            let isInverted = abs(lastSample.angle - beforeLastSample.angle) > 270.0
-            return isInverted ? !isClockwise : isClockwise
-        }()
-
-        // Now if the "gesture" is over a too big of an angle - then we know the angles are inverted, and we need to move them closer to each other from both sides of the 360.0 wrapping point
-        if lastSample.angle - firstSample.angle > 180.0
-        {
-            firstSample.angle += 360.0
-        }
-        else if firstSample.angle - lastSample.angle > 180.0
-        {
-            lastSample.angle += 360.0
-        }
-
-        // The velocity
-        let velocity = abs((lastSample.angle - firstSample.angle) / timeDelta)
-        return isClockwise ? velocity : -velocity
-    }
-
-    /// sets the starting angle of the rotation, this is only used by the touch listener, x and y is the touch position
-    private func setGestureStartAngle(x: CGFloat, y: CGFloat)
-    {
-        _startAngle = angleForPoint(x: x, y: y)
-        
-        // take the current angle into consideration when starting a new drag
-        _startAngle -= _rotationAngle
-    }
-    
-    /// updates the view rotation depending on the given touch position, also takes the starting angle into consideration
-    private func updateGestureRotation(x: CGFloat, y: CGFloat)
-    {
-        self.rotationAngle = angleForPoint(x: x, y: y) - _startAngle
-    }
-    
-    @objc open func stopDeceleration()
-    {
-        if _decelerationDisplayLink !== nil
-        {
-            _decelerationDisplayLink.remove(from: RunLoop.main, forMode: RunLoop.Mode.common)
-            _decelerationDisplayLink = nil
-        }
-    }
-    
-    @objc private func decelerationLoop()
-    {
-        let currentTime = CACurrentMediaTime()
-        
-        _decelerationAngularVelocity *= self.dragDecelerationFrictionCoef
-        
-        let timeInterval = CGFloat(currentTime - _decelerationLastTime)
-        
-        self.rotationAngle += _decelerationAngularVelocity * timeInterval
-        
-        _decelerationLastTime = currentTime
-        
-        if(abs(_decelerationAngularVelocity) < 0.001)
-        {
-            stopDeceleration()
-        }
-    }
-    
-    /// - Returns: The distance between two points
-    private func distance(eventX: CGFloat, startX: CGFloat, eventY: CGFloat, startY: CGFloat) -> CGFloat
-    {
-        let dx = eventX - startX
-        let dy = eventY - startY
-        return sqrt(dx * dx + dy * dy)
-    }
-    
-    /// - Returns: The distance between two points
-    private func distance(from: CGPoint, to: CGPoint) -> CGFloat
-    {
-        let dx = from.x - to.x
-        let dy = from.y - to.y
-        return sqrt(dx * dx + dy * dy)
-    }
-    
-    /// reference to the last highlighted object
-    private var _lastHighlight: Highlight!
-    
-    @objc private func tapGestureRecognized(_ recognizer: NSUITapGestureRecognizer)
-    {
-        if recognizer.state == NSUIGestureRecognizerState.ended
-        {
-            if !self.isHighLightPerTapEnabled { return }
-            
-            let location = recognizer.location(in: self)
-            
-            let high = self.getHighlightByTouchPoint(location)
-            self.highlightValue(high, callDelegate: true)
-        }
-    }
-    
-    #if !os(tvOS)
-    @objc private func rotationGestureRecognized(_ recognizer: NSUIRotationGestureRecognizer)
-    {
-        if recognizer.state == NSUIGestureRecognizerState.began
-        {
-            stopDeceleration()
-            
-            _startAngle = self.rawRotationAngle
-        }
-        
-        if recognizer.state == NSUIGestureRecognizerState.began || recognizer.state == NSUIGestureRecognizerState.changed
-        {
-            let angle = recognizer.nsuiRotation.RAD2DEG
-            
-            self.rotationAngle = _startAngle + angle
-            setNeedsDisplay()
-        }
-        else if recognizer.state == NSUIGestureRecognizerState.ended
-        {
-            let angle = recognizer.nsuiRotation.RAD2DEG
-            
-            self.rotationAngle = _startAngle + angle
-            setNeedsDisplay()
-            
-            if isDragDecelerationEnabled
-            {
-                stopDeceleration()
-                
-                _decelerationAngularVelocity = recognizer.velocity.RAD2DEG
-                
-                if _decelerationAngularVelocity != 0.0
-                {
-                    _decelerationLastTime = CACurrentMediaTime()
-                    _decelerationDisplayLink = NSUIDisplayLink(target: self, selector: #selector(PieRadarChartViewBase.decelerationLoop))
-                    _decelerationDisplayLink.add(to: RunLoop.main, forMode: RunLoop.Mode.common)
-                }
-            }
-        }
-    }
-    #endif
-}

+ 0 - 220
Pods/Charts/Source/Charts/Charts/RadarChartView.swift

@@ -1,220 +0,0 @@
-//
-//  RadarChartView.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-/// Implementation of the RadarChart, a "spidernet"-like chart. It works best
-/// when displaying 5-10 entries per DataSet.
-open class RadarChartView: PieRadarChartViewBase
-{
-    /// width of the web lines that come from the center.
-    @objc open var webLineWidth = CGFloat(1.5)
-    
-    /// width of the web lines that are in between the lines coming from the center
-    @objc open var innerWebLineWidth = CGFloat(0.75)
-    
-    /// color for the web lines that come from the center
-    @objc open var webColor = NSUIColor(red: 122/255.0, green: 122/255.0, blue: 122.0/255.0, alpha: 1.0)
-    
-    /// color for the web lines in between the lines that come from the center.
-    @objc open var innerWebColor = NSUIColor(red: 122/255.0, green: 122/255.0, blue: 122.0/255.0, alpha: 1.0)
-    
-    /// transparency the grid is drawn with (0.0 - 1.0)
-    @objc open var webAlpha: CGFloat = 150.0 / 255.0
-    
-    /// flag indicating if the web lines should be drawn or not
-    @objc open var drawWeb = true
-    
-    /// modulus that determines how many labels and web-lines are skipped before the next is drawn
-    private var _skipWebLineCount = 0
-    
-    /// the object reprsenting the y-axis labels
-    private var _yAxis: YAxis!
-    
-    internal var _yAxisRenderer: YAxisRendererRadarChart!
-    internal var _xAxisRenderer: XAxisRendererRadarChart!
-    
-    public override init(frame: CGRect)
-    {
-        super.init(frame: frame)
-    }
-    
-    public required init?(coder aDecoder: NSCoder)
-    {
-        super.init(coder: aDecoder)
-    }
-    
-    internal override func initialize()
-    {
-        super.initialize()
-        
-        _yAxis = YAxis(position: .left)
-        _yAxis.labelXOffset = 10.0
-        
-        renderer = RadarChartRenderer(chart: self, animator: chartAnimator, viewPortHandler: viewPortHandler)
-        
-        _yAxisRenderer = YAxisRendererRadarChart(viewPortHandler: viewPortHandler, axis: _yAxis, chart: self)
-        _xAxisRenderer = XAxisRendererRadarChart(viewPortHandler: viewPortHandler, axis: xAxis, chart: self)
-
-        self.highlighter = RadarHighlighter(chart: self)
-    }
-
-    internal override func calcMinMax()
-    {
-        super.calcMinMax()
-        
-        guard let data = data else { return }
-        
-        _yAxis.calculate(min: data.getYMin(axis: .left), max: data.getYMax(axis: .left))
-        xAxis.calculate(min: 0.0, max: Double(data.maxEntryCountSet?.entryCount ?? 0))
-    }
-    
-    open override func notifyDataSetChanged()
-    {
-        calcMinMax()
-
-        _yAxisRenderer?.computeAxis(min: _yAxis._axisMinimum, max: _yAxis._axisMaximum, inverted: _yAxis.isInverted)
-        _xAxisRenderer?.computeAxis(min: xAxis._axisMinimum, max: xAxis._axisMaximum, inverted: false)
-        
-        if let data = data,
-            !legend.isLegendCustom
-        {
-            legendRenderer.computeLegend(data: data)
-        }
-        
-        calculateOffsets()
-        
-        setNeedsDisplay()
-    }
-    
-    open override func draw(_ rect: CGRect)
-    {
-        super.draw(rect)
-
-        guard data != nil, let renderer = renderer else { return }
-        
-        let optionalContext = NSUIGraphicsGetCurrentContext()
-        guard let context = optionalContext else { return }
-        
-        if xAxis.isEnabled
-        {
-            _xAxisRenderer.computeAxis(min: xAxis._axisMinimum, max: xAxis._axisMaximum, inverted: false)
-        }
-        
-        _xAxisRenderer?.renderAxisLabels(context: context)
-        
-        if drawWeb
-        {
-            renderer.drawExtras(context: context)
-        }
-        
-        if _yAxis.isEnabled && _yAxis.isDrawLimitLinesBehindDataEnabled
-        {
-            _yAxisRenderer.renderLimitLines(context: context)
-        }
-
-        renderer.drawData(context: context)
-
-        if valuesToHighlight()
-        {
-            renderer.drawHighlighted(context: context, indices: highlighted)
-        }
-        
-        if _yAxis.isEnabled && !_yAxis.isDrawLimitLinesBehindDataEnabled
-        {
-            _yAxisRenderer.renderLimitLines(context: context)
-        }
-        
-        _yAxisRenderer.renderAxisLabels(context: context)
-
-        renderer.drawValues(context: context)
-
-        legendRenderer.renderLegend(context: context)
-
-        drawDescription(in: context)
-
-        drawMarkers(context: context)
-    }
-
-    /// The factor that is needed to transform values into pixels.
-    @objc open var factor: CGFloat
-    {
-        let content = viewPortHandler.contentRect
-        return min(content.width / 2.0, content.height / 2.0)
-                / CGFloat(_yAxis.axisRange)
-    }
-
-    /// The angle that each slice in the radar chart occupies.
-    @objc open var sliceAngle: CGFloat
-    {
-        return 360.0 / CGFloat(data?.maxEntryCountSet?.entryCount ?? 0)
-    }
-
-    open override func indexForAngle(_ angle: CGFloat) -> Int
-    {
-        // take the current angle of the chart into consideration
-        let a = (angle - self.rotationAngle).normalizedAngle
-        
-        let sliceAngle = self.sliceAngle
-        
-        let max = data?.maxEntryCountSet?.entryCount ?? 0
-        return (0..<max).firstIndex {
-            sliceAngle * CGFloat($0 + 1) - sliceAngle / 2.0 > a
-        } ?? 0
-    }
-
-    /// The object that represents all y-labels of the RadarChart.
-    @objc open var yAxis: YAxis
-    {
-        return _yAxis
-    }
-
-    /// Sets the number of web-lines that should be skipped on chart web before the next one is drawn. This targets the lines that come from the center of the RadarChart.
-    /// if count = 1 -> 1 line is skipped in between
-    @objc open var skipWebLineCount: Int
-    {
-        get
-        {
-            return _skipWebLineCount
-        }
-        set
-        {
-            _skipWebLineCount = max(0, newValue)
-        }
-    }
-    
-    internal override var requiredLegendOffset: CGFloat
-    {
-        return legend.font.pointSize * 4.0
-    }
-
-    internal override var requiredBaseOffset: CGFloat
-    {
-        return xAxis.isEnabled && xAxis.isDrawLabelsEnabled ? xAxis.labelRotatedWidth : 10.0
-    }
-
-    open override var radius: CGFloat
-    {
-        let content = viewPortHandler.contentRect
-        return min(content.width / 2.0, content.height / 2.0)
-    }
-
-    /// The maximum value this chart can display on it's y-axis.
-    open override var chartYMax: Double { return _yAxis._axisMaximum }
-    
-    /// The minimum value this chart can display on it's y-axis.
-    open override var chartYMin: Double { return _yAxis._axisMinimum }
-    
-    /// The range of y-values this chart can display.
-    @objc open var yRange: Double { return _yAxis.axisRange }
-}

+ 0 - 31
Pods/Charts/Source/Charts/Charts/ScatterChartView.swift

@@ -1,31 +0,0 @@
-//
-//  ScatterChartView.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-/// The ScatterChart. Draws dots, triangles, squares and custom shapes into the chartview.
-open class ScatterChartView: BarLineChartViewBase, ScatterChartDataProvider
-{
-    open override func initialize()
-    {
-        super.initialize()
-        
-        renderer = ScatterChartRenderer(dataProvider: self, animator: chartAnimator, viewPortHandler: viewPortHandler)
-
-        xAxis.spaceMin = 0.5
-        xAxis.spaceMax = 0.5
-    }
-    
-    // MARK: - ScatterChartDataProvider
-    
-    open var scatterData: ScatterChartData? { return data as? ScatterChartData }
-}

+ 0 - 358
Pods/Charts/Source/Charts/Components/AxisBase.swift

@@ -1,358 +0,0 @@
-//
-//  AxisBase.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-/// Base class for all axes
-@objc(ChartAxisBase)
-open class AxisBase: ComponentBase
-{
-    public override init()
-    {
-        super.init()
-    }
-    
-    /// Custom formatter that is used instead of the auto-formatter if set
-    private lazy var _axisValueFormatter: AxisValueFormatter = DefaultAxisValueFormatter(decimals: decimals)
-    
-    @objc open var labelFont = NSUIFont.systemFont(ofSize: 10.0)
-    @objc open var labelTextColor = NSUIColor.labelOrBlack
-    
-    @objc open var axisLineColor = NSUIColor.gray
-    @objc open var axisLineWidth = CGFloat(0.5)
-    @objc open var axisLineDashPhase = CGFloat(0.0)
-    @objc open var axisLineDashLengths: [CGFloat]!
-    
-    @objc open var gridColor = NSUIColor.gray.withAlphaComponent(0.9)
-    @objc open var gridLineWidth = CGFloat(0.5)
-    @objc open var gridLineDashPhase = CGFloat(0.0)
-    @objc open var gridLineDashLengths: [CGFloat]!
-    @objc open var gridLineCap = CGLineCap.butt
-    
-    @objc open var drawGridLinesEnabled = true
-    @objc open var drawAxisLineEnabled = true
-    
-    /// flag that indicates of the labels of this axis should be drawn or not
-    @objc open var drawLabelsEnabled = true
-    
-    private var _centerAxisLabelsEnabled = false
-
-    /// Centers the axis labels instead of drawing them at their original position.
-    /// This is useful especially for grouped BarChart.
-    @objc open var centerAxisLabelsEnabled: Bool
-    {
-        get { return _centerAxisLabelsEnabled && entryCount > 0 }
-        set { _centerAxisLabelsEnabled = newValue }
-    }
-    
-    @objc open var isCenterAxisLabelsEnabled: Bool
-    {
-        get { return centerAxisLabelsEnabled }
-    }
-
-    /// array of limitlines that can be set for the axis
-    private var _limitLines = [ChartLimitLine]()
-    
-    /// Are the LimitLines drawn behind the data or in front of the data?
-    ///
-    /// **default**: false
-    @objc open var drawLimitLinesBehindDataEnabled = false
-    
-    /// Are the grid lines drawn behind the data or in front of the data?
-    ///
-    /// **default**: true
-    @objc open var drawGridLinesBehindDataEnabled = true
-
-    /// the flag can be used to turn off the antialias for grid lines
-    @objc open var gridAntialiasEnabled = true
-    
-    /// the actual array of entries
-    @objc open var entries = [Double]()
-    
-    /// axis label entries only used for centered labels
-    @objc open var centeredEntries = [Double]()
-    
-    /// the number of entries the legend contains
-    @objc open var entryCount: Int { return entries.count }
-    
-    /// the number of label entries the axis should have
-    ///
-    /// **default**: 6
-    private var _labelCount = Int(6)
-    
-    /// the number of decimal digits to use (for the default formatter
-    @objc open var decimals: Int = 0
-    
-    /// When true, axis labels are controlled by the `granularity` property.
-    /// When false, axis values could possibly be repeated.
-    /// This could happen if two adjacent axis values are rounded to same value.
-    /// If using granularity this could be avoided by having fewer axis values visible.
-    @objc open var granularityEnabled = false
-    
-    private var _granularity = Double(1.0)
-    
-    /// The minimum interval between axis values.
-    /// This can be used to avoid label duplicating when zooming in.
-    ///
-    /// **default**: 1.0
-    @objc open var granularity: Double
-    {
-        get
-        {
-            return _granularity
-        }
-        set
-        {
-            _granularity = newValue
-            
-            // set this to `true` if it was disabled, as it makes no sense to set this property with granularity disabled
-            granularityEnabled = true
-        }
-    }
-    
-    /// The minimum interval between axis values.
-    @objc open var isGranularityEnabled: Bool
-    {
-        get
-        {
-            return granularityEnabled
-        }
-    }
-    
-    /// if true, the set number of y-labels will be forced
-    @objc open var forceLabelsEnabled = false
-    
-    @objc open func getLongestLabel() -> String
-    {
-        let longest = entries.indices
-            .lazy
-            .map(getFormattedLabel(_:))
-            .max(by: \.count)
-
-        return longest ?? ""
-    }
-    
-    /// - Returns: The formatted label at the specified index. This will either use the auto-formatter or the custom formatter (if one is set).
-    @objc open func getFormattedLabel(_ index: Int) -> String
-    {
-        guard entries.indices.contains(index) else { return "" }
-        
-        return valueFormatter?.stringForValue(entries[index], axis: self) ?? ""
-    }
-    
-    /// Sets the formatter to be used for formatting the axis labels.
-    /// If no formatter is set, the chart will automatically determine a reasonable formatting (concerning decimals) for all the values that are drawn inside the chart.
-    /// Use `nil` to use the formatter calculated by the chart.
-    @objc open var valueFormatter: AxisValueFormatter?
-    {
-        get
-        {
-            if _axisValueFormatter is DefaultAxisValueFormatter &&
-            (_axisValueFormatter as! DefaultAxisValueFormatter).hasAutoDecimals &&
-                (_axisValueFormatter as! DefaultAxisValueFormatter).decimals != decimals
-            {
-                (self._axisValueFormatter as! DefaultAxisValueFormatter).decimals = self.decimals
-            }
-
-            return _axisValueFormatter
-        }
-        set
-        {
-            _axisValueFormatter = newValue ?? DefaultAxisValueFormatter(decimals: decimals)
-        }
-    }
-    
-    @objc open var isDrawGridLinesEnabled: Bool { return drawGridLinesEnabled }
-    
-    @objc open var isDrawAxisLineEnabled: Bool { return drawAxisLineEnabled }
-    
-    @objc open var isDrawLabelsEnabled: Bool { return drawLabelsEnabled }
-    
-    /// Are the LimitLines drawn behind the data or in front of the data?
-    /// 
-    /// **default**: false
-    @objc open var isDrawLimitLinesBehindDataEnabled: Bool { return drawLimitLinesBehindDataEnabled }
-    
-    /// Are the grid lines drawn behind the data or in front of the data?
-    ///
-    /// **default**: true
-    @objc open var isDrawGridLinesBehindDataEnabled: Bool { return drawGridLinesBehindDataEnabled }
-    
-    /// Extra spacing for `axisMinimum` to be added to automatically calculated `axisMinimum`
-    @objc open var spaceMin: Double = 0.0
-    
-    /// Extra spacing for `axisMaximum` to be added to automatically calculated `axisMaximum`
-    @objc open var spaceMax: Double = 0.0
-    
-    /// Flag indicating that the axis-min value has been customized
-    internal var _customAxisMin: Bool = false
-    
-    /// Flag indicating that the axis-max value has been customized
-    internal var _customAxisMax: Bool = false
-    
-    /// Do not touch this directly, instead, use axisMinimum.
-    /// This is automatically calculated to represent the real min value,
-    /// and is used when calculating the effective minimum.
-    internal var _axisMinimum = Double(0)
-    
-    /// Do not touch this directly, instead, use axisMaximum.
-    /// This is automatically calculated to represent the real max value,
-    /// and is used when calculating the effective maximum.
-    internal var _axisMaximum = Double(0)
-    
-    /// the total range of values this axis covers
-    @objc open var axisRange = Double(0)
-    
-    /// The minumum number of labels on the axis
-    @objc open var axisMinLabels = Int(2) {
-        didSet { axisMinLabels = axisMinLabels > 0 ? axisMinLabels : oldValue }
-    }
-    
-    /// The maximum number of labels on the axis
-    @objc open var axisMaxLabels = Int(25) {
-        didSet { axisMaxLabels = axisMaxLabels > 0 ? axisMaxLabels : oldValue }
-    }
-    
-    /// the number of label entries the axis should have
-    /// max = 25,
-    /// min = 2,
-    /// default = 6,
-    /// be aware that this number is not fixed and can only be approximated
-    @objc open var labelCount: Int
-    {
-        get
-        {
-            return _labelCount
-        }
-        set
-        {
-            let range = axisMinLabels...axisMaxLabels as ClosedRange
-            _labelCount = newValue.clamped(to: range)
-                        
-            forceLabelsEnabled = false
-        }
-    }
-    
-    @objc open func setLabelCount(_ count: Int, force: Bool)
-    {
-        self.labelCount = count
-        forceLabelsEnabled = force
-    }
-    
-    /// `true` if focing the y-label count is enabled. Default: false
-    @objc open var isForceLabelsEnabled: Bool { return forceLabelsEnabled }
-    
-    /// Adds a new ChartLimitLine to this axis.
-    @objc open func addLimitLine(_ line: ChartLimitLine)
-    {
-        _limitLines.append(line)
-    }
-    
-    /// Removes the specified ChartLimitLine from the axis.
-    @objc open func removeLimitLine(_ line: ChartLimitLine)
-    {
-        guard let i = _limitLines.firstIndex(of: line) else { return }
-        _limitLines.remove(at: i)
-    }
-    
-    /// Removes all LimitLines from the axis.
-    @objc open func removeAllLimitLines()
-    {
-        _limitLines.removeAll(keepingCapacity: false)
-    }
-    
-    /// The LimitLines of this axis.
-    @objc open var limitLines : [ChartLimitLine]
-    {
-        return _limitLines
-    }
-    
-    // MARK: Custom axis ranges
-    
-    /// By calling this method, any custom minimum value that has been previously set is reseted, and the calculation is done automatically.
-    @objc open func resetCustomAxisMin()
-    {
-        _customAxisMin = false
-    }
-    
-    @objc open var isAxisMinCustom: Bool { return _customAxisMin }
-    
-    /// By calling this method, any custom maximum value that has been previously set is reseted, and the calculation is done automatically.
-    @objc open func resetCustomAxisMax()
-    {
-        _customAxisMax = false
-    }
-    
-    @objc open var isAxisMaxCustom: Bool { return _customAxisMax }
-        
-    /// The minimum value for this axis.
-    /// If set, this value will not be calculated automatically depending on the provided data.
-    /// Use `resetCustomAxisMin()` to undo this.
-    @objc open var axisMinimum: Double
-    {
-        get
-        {
-            return _axisMinimum
-        }
-        set
-        {
-            _customAxisMin = true
-            _axisMinimum = newValue
-            axisRange = abs(_axisMaximum - newValue)
-        }
-    }
-    
-    /// The maximum value for this axis.
-    /// If set, this value will not be calculated automatically depending on the provided data.
-    /// Use `resetCustomAxisMax()` to undo this.
-    @objc open var axisMaximum: Double
-    {
-        get
-        {
-            return _axisMaximum
-        }
-        set
-        {
-            _customAxisMax = true
-            _axisMaximum = newValue
-            axisRange = abs(newValue - _axisMinimum)
-        }
-    }
-    
-    /// Calculates the minimum, maximum and range values of the YAxis with the given minimum and maximum values from the chart data.
-    ///
-    /// - Parameters:
-    ///   - dataMin: the y-min value according to chart data
-    ///   - dataMax: the y-max value according to chart
-    @objc open func calculate(min dataMin: Double, max dataMax: Double)
-    {
-        // if custom, use value as is, else use data value
-        var min = _customAxisMin ? _axisMinimum : (dataMin - spaceMin)
-        var max = _customAxisMax ? _axisMaximum : (dataMax + spaceMax)
-        
-        // temporary range (before calculations)
-        let range = abs(max - min)
-        
-        // in case all values are equal
-        if range == 0.0
-        {
-            max = max + 1.0
-            min = min - 1.0
-        }
-        
-        _axisMinimum = min
-        _axisMaximum = max
-        
-        // actual range
-        axisRange = abs(max - min)
-    }
-}

+ 0 - 74
Pods/Charts/Source/Charts/Components/ChartLimitLine.swift

@@ -1,74 +0,0 @@
-//
-//  ChartLimitLine.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-/// The limit line is an additional feature for all Line, Bar and ScatterCharts.
-/// It allows the displaying of an additional line in the chart that marks a certain maximum / limit on the specified axis (x- or y-axis).
-open class ChartLimitLine: ComponentBase
-{
-    @objc(ChartLimitLabelPosition)
-    public enum LabelPosition: Int
-    {
-        case leftTop
-        case leftBottom
-        case rightTop
-        case rightBottom
-    }
-    
-    /// limit / maximum (the y-value or xIndex)
-    @objc open var limit = Double(0.0)
-    
-    private var _lineWidth = CGFloat(2.0)
-    @objc open var lineColor = NSUIColor(red: 237.0/255.0, green: 91.0/255.0, blue: 91.0/255.0, alpha: 1.0)
-    @objc open var lineDashPhase = CGFloat(0.0)
-    @objc open var lineDashLengths: [CGFloat]?
-    
-    @objc open var valueTextColor = NSUIColor.labelOrBlack
-    @objc open var valueFont = NSUIFont.systemFont(ofSize: 13.0)
-    
-    @objc open var drawLabelEnabled = true
-    @objc open var label = ""
-    @objc open var labelPosition = LabelPosition.rightTop
-    
-    public override init()
-    {
-        super.init()
-    }
-    
-    @objc public init(limit: Double)
-    {
-        super.init()
-        self.limit = limit
-    }
-    
-    @objc public init(limit: Double, label: String)
-    {
-        super.init()
-        self.limit = limit
-        self.label = label
-    }
-    
-    /// set the line width of the chart (min = 0.2, max = 12); default 2
-    @objc open var lineWidth: CGFloat
-    {
-        get
-        {
-            return _lineWidth
-        }
-        set
-        {
-            _lineWidth = newValue.clamped(to: 0.2...12)
-        }
-    }
-}

+ 0 - 37
Pods/Charts/Source/Charts/Components/ComponentBase.swift

@@ -1,37 +0,0 @@
-//
-//  ComponentBase.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-/// This class encapsulates everything both Axis, Legend and LimitLines have in common
-@objc(ChartComponentBase)
-open class ComponentBase: NSObject
-{
-    /// flag that indicates if this component is enabled or not
-    @objc open var enabled = true
-    
-    /// The offset this component has on the x-axis
-    /// **default**: 5.0
-    @objc open var xOffset = CGFloat(5.0)
-    
-    /// The offset this component has on the x-axis
-    /// **default**: 5.0 (or 0.0 on ChartYAxis)
-    @objc open var yOffset = CGFloat(5.0)
-    
-    public override init()
-    {
-        super.init()
-    }
-
-    @objc open var isEnabled: Bool { return enabled }
-}

+ 0 - 54
Pods/Charts/Source/Charts/Components/Description.swift

@@ -1,54 +0,0 @@
-//
-//  Description.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-#if canImport(UIKit)
-    import UIKit
-#endif
-
-#if canImport(Cocoa)
-import Cocoa
-#endif
-
-@objc(ChartDescription)
-open class Description: ComponentBase
-{
-    public override init()
-    {
-        #if os(tvOS)
-        // 23 is the smallest recommended font size on the TV
-        font = .systemFont(ofSize: 23)
-        #elseif os(OSX)
-        font = .systemFont(ofSize: NSUIFont.systemFontSize)
-        #else
-        font = .systemFont(ofSize: 8.0)
-        #endif
-        
-        super.init()
-    }
-    
-    /// The text to be shown as the description.
-    @objc open var text: String?
-    
-    /// Custom position for the description text in pixels on the screen.
-    open var position: CGPoint? = nil
-    
-    /// The text alignment of the description text. Default RIGHT.
-    @objc open var textAlign: TextAlignment = TextAlignment.right
-    
-    /// Font object used for drawing the description text.
-    @objc open var font: NSUIFont
-    
-    /// Text color used for drawing the description text
-    @objc open var textColor = NSUIColor.labelOrBlack
-}

+ 0 - 418
Pods/Charts/Source/Charts/Components/Legend.swift

@@ -1,418 +0,0 @@
-//
-//  Legend.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc(ChartLegend)
-open class Legend: ComponentBase
-{
-    @objc(ChartLegendForm)
-    public enum Form: Int
-    {
-        /// Avoid drawing a form
-        case none
-        
-        /// Do not draw the a form, but leave space for it
-        case empty
-        
-        /// Use default (default dataset's form to the legend's form)
-        case `default`
-        
-        /// Draw a square
-        case square
-        
-        /// Draw a circle
-        case circle
-        
-        /// Draw a horizontal line
-        case line
-    }
-    
-    @objc(ChartLegendHorizontalAlignment)
-    public enum HorizontalAlignment: Int
-    {
-        case left
-        case center
-        case right
-    }
-    
-    @objc(ChartLegendVerticalAlignment)
-    public enum VerticalAlignment: Int
-    {
-        case top
-        case center
-        case bottom
-    }
-    
-    @objc(ChartLegendOrientation)
-    public enum Orientation: Int
-    {
-        case horizontal
-        case vertical
-    }
-    
-    @objc(ChartLegendDirection)
-    public enum Direction: Int
-    {
-        case leftToRight
-        case rightToLeft
-    }
-    
-    /// The legend entries array
-    @objc open var entries = [LegendEntry]()
-    
-    /// Entries that will be appended to the end of the auto calculated entries after calculating the legend.
-    /// (if the legend has already been calculated, you will need to call notifyDataSetChanged() to let the changes take effect)
-    @objc open var extraEntries = [LegendEntry]()
-    
-    /// Are the legend labels/colors a custom value or auto calculated? If false, then it's auto, if true, then custom.
-    /// 
-    /// **default**: false (automatic legend)
-    private var _isLegendCustom = false
-
-    /// The horizontal alignment of the legend
-    @objc open var horizontalAlignment: HorizontalAlignment = HorizontalAlignment.left
-    
-    /// The vertical alignment of the legend
-    @objc open var verticalAlignment: VerticalAlignment = VerticalAlignment.bottom
-    
-    /// The orientation of the legend
-    @objc open var orientation: Orientation = Orientation.horizontal
-    
-    /// Flag indicating whether the legend will draw inside the chart or outside
-    @objc open var drawInside: Bool = false
-    
-    /// Flag indicating whether the legend will draw inside the chart or outside
-    @objc open var isDrawInsideEnabled: Bool { return drawInside }
-    
-    /// The text direction of the legend
-    @objc open var direction: Direction = Direction.leftToRight
-
-    @objc open var font: NSUIFont = NSUIFont.systemFont(ofSize: 10.0)
-    @objc open var textColor = NSUIColor.labelOrBlack
-
-    /// The form/shape of the legend forms
-    @objc open var form = Form.square
-    
-    /// The size of the legend forms
-    @objc open var formSize = CGFloat(8.0)
-    
-    /// The line width for forms that consist of lines
-    @objc open var formLineWidth = CGFloat(3.0)
-    
-    /// Line dash configuration for shapes that consist of lines.
-    ///
-    /// This is how much (in pixels) into the dash pattern are we starting from.
-    @objc open var formLineDashPhase: CGFloat = 0.0
-    
-    /// Line dash configuration for shapes that consist of lines.
-    ///
-    /// This is the actual dash pattern.
-    /// I.e. [2, 3] will paint [--   --   ]
-    /// [1, 3, 4, 2] will paint [-   ----  -   ----  ]
-    @objc open var formLineDashLengths: [CGFloat]?
-    
-    @objc open var xEntrySpace = CGFloat(6.0)
-    @objc open var yEntrySpace = CGFloat(0.0)
-    @objc open var formToTextSpace = CGFloat(5.0)
-    @objc open var stackSpace = CGFloat(3.0)
-    
-    @objc open var calculatedLabelSizes = [CGSize]()
-    @objc open var calculatedLabelBreakPoints = [Bool]()
-    @objc open var calculatedLineSizes = [CGSize]()
-    
-    public override init()
-    {
-        super.init()
-        
-        self.xOffset = 5.0
-        self.yOffset = 3.0
-    }
-    
-    @objc public init(entries: [LegendEntry])
-    {
-        super.init()
-        
-        self.entries = entries
-    }
-    
-    @objc open func getMaximumEntrySize(withFont font: NSUIFont) -> CGSize
-    {
-        var maxW = CGFloat(0.0)
-        var maxH = CGFloat(0.0)
-        
-        var maxFormSize: CGFloat = 0.0
-
-        for entry in entries
-        {
-            let formSize = entry.formSize.isNaN ? self.formSize : entry.formSize
-            if formSize > maxFormSize
-            {
-                maxFormSize = formSize
-            }
-            
-            guard let label = entry.label
-                else { continue }
-            
-            let size = (label as NSString).size(withAttributes: [.font: font])
-            
-            if size.width > maxW
-            {
-                maxW = size.width
-            }
-            if size.height > maxH
-            {
-                maxH = size.height
-            }
-        }
-        
-        return CGSize(
-            width: maxW + maxFormSize + formToTextSpace,
-            height: maxH
-        )
-    }
-
-    @objc open var neededWidth = CGFloat(0.0)
-    @objc open var neededHeight = CGFloat(0.0)
-    @objc open var textWidthMax = CGFloat(0.0)
-    @objc open var textHeightMax = CGFloat(0.0)
-    
-    /// flag that indicates if word wrapping is enabled
-    /// this is currently supported only for `orientation == Horizontal`.
-    /// you may want to set maxSizePercent when word wrapping, to set the point where the text wraps.
-    /// 
-    /// **default**: true
-    @objc open var wordWrapEnabled = true
-    
-    /// if this is set, then word wrapping the legend is enabled.
-    @objc open var isWordWrapEnabled: Bool { return wordWrapEnabled }
-
-    /// The maximum relative size out of the whole chart view in percent.
-    /// If the legend is to the right/left of the chart, then this affects the width of the legend.
-    /// If the legend is to the top/bottom of the chart, then this affects the height of the legend.
-    /// 
-    /// **default**: 0.95 (95%)
-    @objc open var maxSizePercent: CGFloat = 0.95
-    
-    @objc open func calculateDimensions(labelFont: NSUIFont, viewPortHandler: ViewPortHandler)
-    {
-        let maxEntrySize = getMaximumEntrySize(withFont: labelFont)
-        let defaultFormSize = self.formSize
-        let stackSpace = self.stackSpace
-        let formToTextSpace = self.formToTextSpace
-        let xEntrySpace = self.xEntrySpace
-        let yEntrySpace = self.yEntrySpace
-        let wordWrapEnabled = self.wordWrapEnabled
-        let entries = self.entries
-        let entryCount = entries.count
-        
-        textWidthMax = maxEntrySize.width
-        textHeightMax = maxEntrySize.height
-        
-        switch orientation
-        {
-        case .vertical:
-            
-            var maxWidth = CGFloat(0.0)
-            var width = CGFloat(0.0)
-            var maxHeight = CGFloat(0.0)
-            let labelLineHeight = labelFont.lineHeight
-            
-            var wasStacked = false
-            
-            for i in entries.indices
-            {
-                let e = entries[i]
-                let drawingForm = e.form != .none
-                let formSize = e.formSize.isNaN ? defaultFormSize : e.formSize
-
-                if !wasStacked
-                {
-                    width = 0.0
-                }
-                
-                if drawingForm
-                {
-                    if wasStacked
-                    {
-                        width += stackSpace
-                    }
-                    width += formSize
-                }
-                
-                if let label = e.label
-                {
-                    let size = (label as NSString).size(withAttributes: [.font: labelFont])
-
-                    if drawingForm && !wasStacked
-                    {
-                        width += formToTextSpace
-                    }
-                    else if wasStacked
-                    {
-                        maxWidth = max(maxWidth, width)
-                        maxHeight += labelLineHeight + yEntrySpace
-                        width = 0.0
-                        wasStacked = false
-                    }
-                    
-                    width += size.width
-                    maxHeight += labelLineHeight + yEntrySpace
-                }
-                else
-                {
-                    wasStacked = true
-                    width += formSize
-                    
-                    if i < entryCount - 1
-                    {
-                        width += stackSpace
-                    }
-                }
-                
-                maxWidth = max(maxWidth, width)
-            }
-            
-            neededWidth = maxWidth
-            neededHeight = maxHeight
-            
-        case .horizontal:
-            
-            let labelLineHeight = labelFont.lineHeight
-            
-            let contentWidth: CGFloat = viewPortHandler.contentWidth * maxSizePercent
-            
-            // Prepare arrays for calculated layout
-            if calculatedLabelSizes.count != entryCount
-            {
-                calculatedLabelSizes = [CGSize](repeating: CGSize(), count: entryCount)
-            }
-            
-            if calculatedLabelBreakPoints.count != entryCount
-            {
-                calculatedLabelBreakPoints = [Bool](repeating: false, count: entryCount)
-            }
-            
-            calculatedLineSizes.removeAll(keepingCapacity: true)
-            
-            // Start calculating layout
-            
-            var maxLineWidth: CGFloat = 0.0
-            var currentLineWidth: CGFloat = 0.0
-            var requiredWidth: CGFloat = 0.0
-            var stackedStartIndex: Int = -1
-            
-            for i in entries.indices
-            {
-                let e = entries[i]
-                let drawingForm = e.form != .none
-                let label = e.label
-                
-                calculatedLabelBreakPoints[i] = false
-                
-                if stackedStartIndex == -1
-                {
-                    // we are not stacking, so required width is for this label only
-                    requiredWidth = 0.0
-                }
-                else
-                {
-                    // add the spacing appropriate for stacked labels/forms
-                    requiredWidth += stackSpace
-                }
-                
-                // grouped forms have null labels
-                if let label = label
-                {
-                    calculatedLabelSizes[i] = (label as NSString).size(withAttributes: [.font: labelFont])
-                    requiredWidth += drawingForm ? formToTextSpace + formSize : 0.0
-                    requiredWidth += calculatedLabelSizes[i].width
-                }
-                else
-                {
-                    calculatedLabelSizes[i] = CGSize()
-                    requiredWidth += drawingForm ? formSize : 0.0
-                    
-                    if stackedStartIndex == -1
-                    {
-                        // mark this index as we might want to break here later
-                        stackedStartIndex = i
-                    }
-                }
-                
-                if label != nil || i == entryCount - 1
-                {
-                    let requiredSpacing = currentLineWidth == 0.0 ? 0.0 : xEntrySpace
-                    
-                    if (!wordWrapEnabled || // No word wrapping, it must fit.
-                        currentLineWidth == 0.0 || // The line is empty, it must fit.
-                        (contentWidth - currentLineWidth >= requiredSpacing + requiredWidth)) // It simply fits
-                    {
-                        // Expand current line
-                        currentLineWidth += requiredSpacing + requiredWidth
-                    }
-                    else
-                    { // It doesn't fit, we need to wrap a line
-                        
-                        // Add current line size to array
-                        calculatedLineSizes.append(CGSize(width: currentLineWidth, height: labelLineHeight))
-                        maxLineWidth = max(maxLineWidth, currentLineWidth)
-                        
-                        // Start a new line
-                        calculatedLabelBreakPoints[stackedStartIndex > -1 ? stackedStartIndex : i] = true
-                        currentLineWidth = requiredWidth
-                    }
-                    
-                    if i == entryCount - 1
-                    { // Add last line size to array
-                        calculatedLineSizes.append(CGSize(width: currentLineWidth, height: labelLineHeight))
-                        maxLineWidth = max(maxLineWidth, currentLineWidth)
-                    }
-                }
-                
-                stackedStartIndex = label != nil ? -1 : stackedStartIndex
-            }
-            
-            neededWidth = maxLineWidth
-            neededHeight = labelLineHeight * CGFloat(calculatedLineSizes.count) +
-                yEntrySpace * CGFloat(calculatedLineSizes.isEmpty ? 0 : (calculatedLineSizes.count - 1))
-        }
-        
-        neededWidth += xOffset
-        neededHeight += yOffset
-    }
-    
-    /// MARK: - Custom legend
-    
-    /// Sets a custom legend's entries array.
-    /// * A nil label will start a group.
-    /// This will disable the feature that automatically calculates the legend entries from the datasets.
-    /// Call `resetCustom(...)` to re-enable automatic calculation (and then `notifyDataSetChanged()` is needed).
-    @objc open func setCustom(entries: [LegendEntry])
-    {
-        self.entries = entries
-        _isLegendCustom = true
-    }
-    
-    /// Calling this will disable the custom legend entries (set by `setLegend(...)`). Instead, the entries will again be calculated automatically (after `notifyDataSetChanged()` is called).
-    @objc open func resetCustom()
-    {
-        _isLegendCustom = false
-    }
-    
-    /// **default**: false (automatic legend)
-    /// `true` if a custom legend entries has been set
-    @objc open var isLegendCustom: Bool
-    {
-        return _isLegendCustom
-    }
-}

+ 0 - 73
Pods/Charts/Source/Charts/Components/LegendEntry.swift

@@ -1,73 +0,0 @@
-//
-//  LegendEntry.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc(ChartLegendEntry)
-open class LegendEntry: NSObject
-{
-    public override init()
-    {
-        super.init()
-    }
-    
-    /// - Parameters:
-    ///   - label:                  The legend entry text.
-    ///                                     A `nil` label will start a group.
-    @objc public init(label: String?)
-    {
-        self.label = label
-    }
-
-    /// The legend entry text.
-    /// A `nil` label will start a group.
-    @objc open var label: String?
-
-    /// The color for drawing the label
-    @objc open var labelColor: NSUIColor?
-
-    /// The form to draw for this entry.
-    ///
-    /// `None` will avoid drawing a form, and any related space.
-    /// `Empty` will avoid drawing a form, but keep its space.
-    /// `Default` will use the Legend's default.
-    @objc open var form: Legend.Form = .default
-    
-    /// Form size will be considered except for when .None is used
-    ///
-    /// Set as NaN to use the legend's default
-    @objc open var formSize: CGFloat = CGFloat.nan
-    
-    /// Line width used for shapes that consist of lines.
-    ///
-    /// Set to NaN to use the legend's default.
-    @objc open var formLineWidth: CGFloat = CGFloat.nan
-    
-    /// Line dash configuration for shapes that consist of lines.
-    ///
-    /// This is how much (in pixels) into the dash pattern are we starting from.
-    ///
-    /// Set to NaN to use the legend's default.
-    @objc open var formLineDashPhase: CGFloat = 0.0
-    
-    /// Line dash configuration for shapes that consist of lines.
-    ///
-    /// This is the actual dash pattern.
-    /// I.e. [2, 3] will paint [--   --   ]
-    /// [1, 3, 4, 2] will paint [-   ----  -   ----  ]
-    ///
-    /// Set to nil to use the legend's default.
-    @objc open var formLineDashLengths: [CGFloat]?
-    
-    /// The color for drawing the form
-    @objc open var formColor: NSUIColor?
-}

+ 0 - 39
Pods/Charts/Source/Charts/Components/Marker.swift

@@ -1,39 +0,0 @@
-//
-//  ChartMarker.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc(ChartMarker)
-public protocol Marker: AnyObject
-{
-    /// - Returns: The desired (general) offset you wish the IMarker to have on the x-axis.
-    /// By returning x: -(width / 2) you will center the IMarker horizontally.
-    /// By returning y: -(height / 2) you will center the IMarker vertically.
-    var offset: CGPoint { get }
-    
-    /// - Parameters:
-    ///   - point: This is the point at which the marker wants to be drawn. You can adjust the offset conditionally based on this argument.
-    /// - Returns: The offset for drawing at the specific `point`.
-    ///            This allows conditional adjusting of the Marker position.
-    ///            If you have no adjustments to make, return self.offset().
-    func offsetForDrawing(atPoint: CGPoint) -> CGPoint
-    
-    /// This method enables a custom Marker to update it's content every time the Marker is redrawn according to the data entry it points to.
-    ///
-    /// - Parameters:
-    ///   - entry: The Entry the IMarker belongs to. This can also be any subclass of Entry, like BarEntry or CandleEntry, simply cast it at runtime.
-    ///   - highlight: The highlight object contains information about the highlighted value such as it's dataset-index, the selected range or stack-index (only stacked bar entries).
-    func refreshContent(entry: ChartDataEntry, highlight: Highlight)
-    
-    /// Draws the Marker on the given position on the given context
-    func draw(context: CGContext, point: CGPoint)
-}

+ 0 - 106
Pods/Charts/Source/Charts/Components/MarkerImage.swift

@@ -1,106 +0,0 @@
-//
-//  ChartMarkerImage.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc(ChartMarkerImage)
-open class MarkerImage: NSObject, Marker
-{
-    /// The marker image to render
-    @objc open var image: NSUIImage?
-    
-    open var offset: CGPoint = CGPoint()
-    
-    @objc open weak var chartView: ChartViewBase?
-    
-    /// As long as size is 0.0/0.0 - it will default to the image's size
-    @objc open var size: CGSize = CGSize()
-    
-    public override init()
-    {
-        super.init()
-    }
-    
-    open func offsetForDrawing(atPoint point: CGPoint) -> CGPoint
-    {
-        var offset = self.offset
-        
-        let chart = self.chartView
-        
-        var size = self.size
-        
-        if size.width == 0.0 && image != nil
-        {
-            size.width = image?.size.width ?? 0.0
-        }
-        if size.height == 0.0 && image != nil
-        {
-            size.height = image?.size.height ?? 0.0
-        }
-        
-        let width = size.width
-        let height = size.height
-        
-        if point.x + offset.x < 0.0
-        {
-            offset.x = -point.x
-        }
-        else if chart != nil && point.x + width + offset.x > chart!.bounds.size.width
-        {
-            offset.x = chart!.bounds.size.width - point.x - width
-        }
-        
-        if point.y + offset.y < 0
-        {
-            offset.y = -point.y
-        }
-        else if chart != nil && point.y + height + offset.y > chart!.bounds.size.height
-        {
-            offset.y = chart!.bounds.size.height - point.y - height
-        }
-        
-        return offset
-    }
-    
-    open func refreshContent(entry: ChartDataEntry, highlight: Highlight)
-    {
-        // Do nothing here...
-    }
-    
-    open func draw(context: CGContext, point: CGPoint)
-    {
-        guard let image = image else { return }
-
-        let offset = offsetForDrawing(atPoint: point)
-        
-        var size = self.size
-        
-        if size.width == 0.0
-        {
-            size.width = image.size.width
-        }
-        if size.height == 0.0
-        {
-            size.height = image.size.height
-        }
-        
-        let rect = CGRect(
-            x: point.x + offset.x,
-            y: point.y + offset.y,
-            width: size.width,
-            height: size.height)
-        
-        NSUIGraphicsPushContext(context)
-        image.draw(in: rect)
-        NSUIGraphicsPopContext()
-    }
-}

+ 0 - 99
Pods/Charts/Source/Charts/Components/MarkerView.swift

@@ -1,99 +0,0 @@
-//
-//  ChartMarkerView.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-#if canImport(AppKit)
-import AppKit
-#endif
-
-@objc(ChartMarkerView)
-open class MarkerView: NSUIView, Marker
-{
-    open var offset: CGPoint = CGPoint()
-    
-    @objc open weak var chartView: ChartViewBase?
-    
-    open func offsetForDrawing(atPoint point: CGPoint) -> CGPoint
-    {
-        guard let chart = chartView else { return self.offset }
-        
-        var offset = self.offset
-        
-        let width = self.bounds.size.width
-        let height = self.bounds.size.height
-        
-        if point.x + offset.x < 0.0
-        {
-            offset.x = -point.x
-        }
-        else if point.x + width + offset.x > chart.bounds.size.width
-        {
-            offset.x = chart.bounds.size.width - point.x - width
-        }
-        
-        if point.y + offset.y < 0
-        {
-            offset.y = -point.y
-        }
-        else if point.y + height + offset.y > chart.bounds.size.height
-        {
-            offset.y = chart.bounds.size.height - point.y - height
-        }
-        
-        return offset
-    }
-    
-    open func refreshContent(entry: ChartDataEntry, highlight: Highlight)
-    {
-        // Do nothing here...
-    }
-    
-    open func draw(context: CGContext, point: CGPoint)
-    {
-        let offset = self.offsetForDrawing(atPoint: point)
-        
-        context.saveGState()
-        context.translateBy(x: point.x + offset.x,
-                              y: point.y + offset.y)
-        NSUIGraphicsPushContext(context)
-        self.nsuiLayer?.render(in: context)
-        NSUIGraphicsPopContext()
-        context.restoreGState()
-    }
-    
-    @objc
-    open class func viewFromXib(in bundle: Bundle = .main) -> MarkerView?
-    {
-        #if !os(OSX)
-        
-        return bundle.loadNibNamed(
-            String(describing: self),
-            owner: nil,
-            options: nil)?[0] as? MarkerView
-        #else
-        
-        var loadedObjects: NSArray? = NSArray()
-        
-        if bundle.loadNibNamed(
-            NSNib.Name(String(describing: self)),
-            owner: nil,
-            topLevelObjects: &loadedObjects)
-        {
-            return loadedObjects?[0] as? MarkerView
-        }
-        
-        return nil
-        #endif
-    }
-    
-}

+ 0 - 75
Pods/Charts/Source/Charts/Components/XAxis.swift

@@ -1,75 +0,0 @@
-//
-//  XAxis.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc(ChartXAxis)
-open class XAxis: AxisBase
-{
-    @objc(XAxisLabelPosition)
-    public enum LabelPosition: Int
-    {
-        case top
-        case bottom
-        case bothSided
-        case topInside
-        case bottomInside
-    }
-    
-    /// width of the x-axis labels in pixels - this is automatically calculated by the `computeSize()` methods in the renderers
-    @objc open var labelWidth = CGFloat(1.0)
-    
-    /// height of the x-axis labels in pixels - this is automatically calculated by the `computeSize()` methods in the renderers
-    @objc open var labelHeight = CGFloat(1.0)
-    
-    /// width of the (rotated) x-axis labels in pixels - this is automatically calculated by the `computeSize()` methods in the renderers
-    @objc open var labelRotatedWidth = CGFloat(1.0)
-    
-    /// height of the (rotated) x-axis labels in pixels - this is automatically calculated by the `computeSize()` methods in the renderers
-    @objc open var labelRotatedHeight = CGFloat(1.0)
-    
-    /// This is the angle for drawing the X axis labels (in degrees)
-    @objc open var labelRotationAngle = CGFloat(0.0)
-
-    /// if set to true, the chart will avoid that the first and last label entry in the chart "clip" off the edge of the chart
-    @objc open var avoidFirstLastClippingEnabled = false
-    
-    /// the position of the x-labels relative to the chart
-    @objc open var labelPosition = LabelPosition.top
-    
-    /// if set to true, word wrapping the labels will be enabled.
-    /// word wrapping is done using `(value width * labelRotatedWidth)`
-    ///
-    /// - Note: currently supports all charts except pie/radar/horizontal-bar*
-    @objc open var wordWrapEnabled = false
-    
-    /// `true` if word wrapping the labels is enabled
-    @objc open var isWordWrapEnabled: Bool { return wordWrapEnabled }
-    
-    /// the width for wrapping the labels, as percentage out of one value width.
-    /// used only when isWordWrapEnabled = true.
-    /// 
-    /// **default**: 1.0
-    @objc open var wordWrapWidthPercent: CGFloat = 1.0
-    
-    public override init()
-    {
-        super.init()
-        
-        self.yOffset = 4.0
-    }
-    
-    @objc open var isAvoidFirstLastClippingEnabled: Bool
-    {
-        return avoidFirstLastClippingEnabled
-    }
-}

+ 0 - 206
Pods/Charts/Source/Charts/Components/YAxis.swift

@@ -1,206 +0,0 @@
-//
-//  YAxis.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-#if canImport(UIKit)
-    import UIKit
-#endif
-
-#if canImport(Cocoa)
-import Cocoa
-#endif
-
-
-/// Class representing the y-axis labels settings and its entries.
-/// Be aware that not all features the YLabels class provides are suitable for the RadarChart.
-/// Customizations that affect the value range of the axis need to be applied before setting data for the chart.
-@objc(ChartYAxis)
-open class YAxis: AxisBase
-{
-    @objc(YAxisLabelPosition)
-    public enum LabelPosition: Int
-    {
-        case outsideChart
-        case insideChart
-    }
-    
-    ///  Enum that specifies the axis a DataSet should be plotted against, either Left or Right.
-    @objc
-    public enum AxisDependency: Int
-    {
-        case left
-        case right
-    }
-    
-    /// indicates if the bottom y-label entry is drawn or not
-    @objc open var drawBottomYLabelEntryEnabled = true
-    
-    /// indicates if the top y-label entry is drawn or not
-    @objc open var drawTopYLabelEntryEnabled = true
-    
-    /// flag that indicates if the axis is inverted or not
-    @objc open var inverted = false
-    
-    /// flag that indicates if the zero-line should be drawn regardless of other grid lines
-    @objc open var drawZeroLineEnabled = false
-    
-    /// Color of the zero line
-    @objc open var zeroLineColor: NSUIColor? = NSUIColor.gray
-    
-    /// Width of the zero line
-    @objc open var zeroLineWidth: CGFloat = 1.0
-    
-    /// This is how much (in pixels) into the dash pattern are we starting from.
-    @objc open var zeroLineDashPhase = CGFloat(0.0)
-    
-    /// This is the actual dash pattern.
-    /// I.e. [2, 3] will paint [--   --   ]
-    /// [1, 3, 4, 2] will paint [-   ----  -   ----  ]
-    @objc open var zeroLineDashLengths: [CGFloat]?
-
-    /// axis space from the largest value to the top in percent of the total axis range
-    @objc open var spaceTop = CGFloat(0.1)
-
-    /// axis space from the smallest value to the bottom in percent of the total axis range
-    @objc open var spaceBottom = CGFloat(0.1)
-    
-    /// the position of the y-labels relative to the chart
-    @objc open var labelPosition = LabelPosition.outsideChart
-
-    /// the alignment of the text in the y-label
-    @objc open var labelAlignment: TextAlignment = .left
-
-    /// the horizontal offset of the y-label
-    @objc open var labelXOffset: CGFloat = 0.0
-    
-    /// the side this axis object represents
-    private var _axisDependency = AxisDependency.left
-    
-    /// the minimum width that the axis should take
-    /// 
-    /// **default**: 0.0
-    @objc open var minWidth = CGFloat(0)
-    
-    /// the maximum width that the axis can take.
-    /// use Infinity for disabling the maximum.
-    /// 
-    /// **default**: CGFloat.infinity
-    @objc open var maxWidth = CGFloat(CGFloat.infinity)
-    
-    public override init()
-    {
-        super.init()
-        
-        self.yOffset = 0.0
-    }
-    
-    @objc public init(position: AxisDependency)
-    {
-        super.init()
-        
-        _axisDependency = position
-        
-        self.yOffset = 0.0
-    }
-    
-    @objc open var axisDependency: AxisDependency
-    {
-        return _axisDependency
-    }
-    
-    @objc open func requiredSize() -> CGSize
-    {
-        let label = getLongestLabel() as NSString
-        var size = label.size(withAttributes: [.font: labelFont])
-        size.width += xOffset * 2.0
-        size.height += yOffset * 2.0
-        size.width = max(minWidth, min(size.width, maxWidth > 0.0 ? maxWidth : size.width))
-        return size
-    }
-    
-    @objc open func getRequiredHeightSpace() -> CGFloat
-    {
-        return requiredSize().height
-    }
-    
-    /// `true` if this axis needs horizontal offset, `false` ifno offset is needed.
-    @objc open var needsOffset: Bool
-    {
-        if isEnabled && isDrawLabelsEnabled && labelPosition == .outsideChart
-        {
-            return true
-        }
-        else
-        {
-            return false
-        }
-    }
-    
-    @objc open var isInverted: Bool { return inverted }
-    
-    open override func calculate(min dataMin: Double, max dataMax: Double)
-    {
-        // if custom, use value as is, else use data value
-        var min = _customAxisMin ? _axisMinimum : dataMin
-        var max = _customAxisMax ? _axisMaximum : dataMax
-        
-        // Make sure max is greater than min
-        // Discussion: https://github.com/danielgindi/Charts/pull/3650#discussion_r221409991
-        if min > max
-        {
-            switch(_customAxisMax, _customAxisMin)
-            {
-            case(true, true):
-                (min, max) = (max, min)
-            case(true, false):
-                min = max < 0 ? max * 1.5 : max * 0.5
-            case(false, true):
-                max = min < 0 ? min * 0.5 : min * 1.5
-            case(false, false):
-                break
-            }
-        }
-        
-        // temporary range (before calculations)
-        let range = abs(max - min)
-        
-        // in case all values are equal
-        if range == 0.0
-        {
-            max = max + 1.0
-            min = min - 1.0
-        }
-        
-        // bottom-space only effects non-custom min
-        if !_customAxisMin
-        {
-            let bottomSpace = range * Double(spaceBottom)
-            _axisMinimum = (min - bottomSpace)
-        }
-        
-        // top-space only effects non-custom max
-        if !_customAxisMax
-        {
-            let topSpace = range * Double(spaceTop)
-            _axisMaximum = (max + topSpace)
-        }
-        
-        // calc actual range
-        axisRange = abs(_axisMaximum - _axisMinimum)
-    }
-    
-    @objc open var isDrawBottomYLabelEntryEnabled: Bool { return drawBottomYLabelEntryEnabled }
-    
-    @objc open var isDrawTopYLabelEntryEnabled: Bool { return drawTopYLabelEntryEnabled }
-
-}

+ 0 - 413
Pods/Charts/Source/Charts/Data/Implementations/ChartBaseDataSet.swift

@@ -1,413 +0,0 @@
-//
-//  BaseDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-open class ChartBaseDataSet: NSObject, ChartDataSetProtocol, NSCopying
-{
-    public required override init()
-    {
-        super.init()
-        
-        // default color
-        colors.append(NSUIColor(red: 140.0/255.0, green: 234.0/255.0, blue: 255.0/255.0, alpha: 1.0))
-        valueColors.append(.labelOrBlack)
-    }
-    
-    @objc public init(label: String)
-    {
-        super.init()
-        
-        // default color
-        colors.append(NSUIColor(red: 140.0/255.0, green: 234.0/255.0, blue: 255.0/255.0, alpha: 1.0))
-        valueColors.append(.labelOrBlack)
-        
-        self.label = label
-    }
-    
-    // MARK: - Data functions and accessors
-    
-    /// Use this method to tell the data set that the underlying data has changed
-    open func notifyDataSetChanged()
-    {
-        calcMinMax()
-    }
-    
-    open func calcMinMax()
-    {
-        fatalError("calcMinMax is not implemented in ChartBaseDataSet")
-    }
-    
-    open func calcMinMaxY(fromX: Double, toX: Double)
-    {
-        fatalError("calcMinMaxY(fromX:, toX:) is not implemented in ChartBaseDataSet")
-    }
-    
-    open var yMin: Double
-    {
-        fatalError("yMin is not implemented in ChartBaseDataSet")
-    }
-    
-    open var yMax: Double
-    {
-        fatalError("yMax is not implemented in ChartBaseDataSet")
-    }
-    
-    open var xMin: Double
-    {
-        fatalError("xMin is not implemented in ChartBaseDataSet")
-    }
-    
-    open var xMax: Double
-    {
-        fatalError("xMax is not implemented in ChartBaseDataSet")
-    }
-    
-    open var entryCount: Int
-    {
-        fatalError("entryCount is not implemented in ChartBaseDataSet")
-    }
-        
-    open func entryForIndex(_ i: Int) -> ChartDataEntry?
-    {
-        fatalError("entryForIndex is not implemented in ChartBaseDataSet")
-    }
-    
-    open func entryForXValue(
-        _ x: Double,
-        closestToY y: Double,
-        rounding: ChartDataSetRounding) -> ChartDataEntry?
-    {
-        fatalError("entryForXValue(x, closestToY, rounding) is not implemented in ChartBaseDataSet")
-    }
-    
-    open func entryForXValue(
-        _ x: Double,
-        closestToY y: Double) -> ChartDataEntry?
-    {
-        fatalError("entryForXValue(x, closestToY) is not implemented in ChartBaseDataSet")
-    }
-    
-    open func entriesForXValue(_ x: Double) -> [ChartDataEntry]
-    {
-        fatalError("entriesForXValue is not implemented in ChartBaseDataSet")
-    }
-    
-    open func entryIndex(
-        x xValue: Double,
-        closestToY y: Double,
-        rounding: ChartDataSetRounding) -> Int
-    {
-        fatalError("entryIndex(x, closestToY, rounding) is not implemented in ChartBaseDataSet")
-    }
-    
-    open func entryIndex(entry e: ChartDataEntry) -> Int
-    {
-        fatalError("entryIndex(entry) is not implemented in ChartBaseDataSet")
-    }
-    
-    open func addEntry(_ e: ChartDataEntry) -> Bool
-    {
-        fatalError("addEntry is not implemented in ChartBaseDataSet")
-    }
-    
-    open func addEntryOrdered(_ e: ChartDataEntry) -> Bool
-    {
-        fatalError("addEntryOrdered is not implemented in ChartBaseDataSet")
-    }
-    
-    @discardableResult open func removeEntry(_ entry: ChartDataEntry) -> Bool
-    {
-        fatalError("removeEntry is not implemented in ChartBaseDataSet")
-    }
-    
-    @discardableResult open func removeEntry(index: Int) -> Bool
-    {
-        if let entry = entryForIndex(index)
-        {
-            return removeEntry(entry)
-        }
-        return false
-    }
-    
-    @discardableResult open func removeEntry(x: Double) -> Bool
-    {
-        if let entry = entryForXValue(x, closestToY: Double.nan)
-        {
-            return removeEntry(entry)
-        }
-        return false
-    }
-    
-    @discardableResult open func removeFirst() -> Bool
-    {
-        if entryCount > 0
-        {
-            if let entry = entryForIndex(0)
-            {
-                return removeEntry(entry)
-            }
-        }
-        return false
-    }
-    
-    @discardableResult open func removeLast() -> Bool
-    {
-        if entryCount > 0
-        {
-            if let entry = entryForIndex(entryCount - 1)
-            {
-                return removeEntry(entry)
-            }
-        }
-        return false
-    }
-    
-    open func contains(_ e: ChartDataEntry) -> Bool
-    {
-        fatalError("removeEntry is not implemented in ChartBaseDataSet")
-    }
-    
-    open func clear()
-    {
-        fatalError("clear is not implemented in ChartBaseDataSet")
-    }
-    
-    // MARK: - Styling functions and accessors
-    
-    /// All the colors that are used for this DataSet.
-    /// Colors are reused as soon as the number of Entries the DataSet represents is higher than the size of the colors array.
-    open var colors = [NSUIColor]()
-    
-    /// List representing all colors that are used for drawing the actual values for this DataSet
-    open var valueColors = [NSUIColor]()
-
-    /// The label string that describes the DataSet.
-    open var label: String? = "DataSet"
-    
-    /// The axis this DataSet should be plotted against.
-    open var axisDependency = YAxis.AxisDependency.left
-    
-    /// - Returns: The color at the given index of the DataSet's color array.
-    /// This prevents out-of-bounds by performing a modulus on the color index, so colours will repeat themselves.
-    open func color(atIndex index: Int) -> NSUIColor
-    {
-        var index = index
-        if index < 0
-        {
-            index = 0
-        }
-        return colors[index % colors.count]
-    }
-    
-    /// Resets all colors of this DataSet and recreates the colors array.
-    open func resetColors()
-    {
-        colors.removeAll(keepingCapacity: false)
-    }
-    
-    /// Adds a new color to the colors array of the DataSet.
-    ///
-    /// - Parameters:
-    ///   - color: the color to add
-    open func addColor(_ color: NSUIColor)
-    {
-        colors.append(color)
-    }
-    
-    /// Sets the one and **only** color that should be used for this DataSet.
-    /// Internally, this recreates the colors array and adds the specified color.
-    ///
-    /// - Parameters:
-    ///   - color: the color to set
-    open func setColor(_ color: NSUIColor)
-    {
-        colors.removeAll(keepingCapacity: false)
-        colors.append(color)
-    }
-    
-    /// Sets colors to a single color a specific alpha value.
-    ///
-    /// - Parameters:
-    ///   - color: the color to set
-    ///   - alpha: alpha to apply to the set `color`
-    @objc open func setColor(_ color: NSUIColor, alpha: CGFloat)
-    {
-        setColor(color.withAlphaComponent(alpha))
-    }
-    
-    /// Sets colors with a specific alpha value.
-    ///
-    /// - Parameters:
-    ///   - colors: the colors to set
-    ///   - alpha: alpha to apply to the set `colors`
-    @objc open func setColors(_ colors: [NSUIColor], alpha: CGFloat)
-    {
-        self.colors = colors.map { $0.withAlphaComponent(alpha) }
-    }
-    
-    /// Sets colors with a specific alpha value.
-    ///
-    /// - Parameters:
-    ///   - colors: the colors to set
-    ///   - alpha: alpha to apply to the set `colors`
-    open func setColors(_ colors: NSUIColor...)
-    {
-        self.colors = colors
-    }
-    
-    /// if true, value highlighting is enabled
-    open var highlightEnabled = true
-    
-    /// `true` if value highlighting is enabled for this dataset
-    open var isHighlightEnabled: Bool { return highlightEnabled }
-        
-    /// Custom formatter that is used instead of the auto-formatter if set
-    open lazy var valueFormatter: ValueFormatter = DefaultValueFormatter()
-
-    /// Sets/get a single color for value text.
-    /// Setting the color clears the colors array and adds a single color.
-    /// Getting will return the first color in the array.
-    open var valueTextColor: NSUIColor
-    {
-        get
-        {
-            return valueColors[0]
-        }
-        set
-        {
-            valueColors.removeAll(keepingCapacity: false)
-            valueColors.append(newValue)
-        }
-    }
-    
-    /// - Returns: The color at the specified index that is used for drawing the values inside the chart. Uses modulus internally.
-    open func valueTextColorAt(_ index: Int) -> NSUIColor
-    {
-        var index = index
-        if index < 0
-        {
-            index = 0
-        }
-        return valueColors[index % valueColors.count]
-    }
-    
-    /// the font for the value-text labels
-    open var valueFont: NSUIFont = NSUIFont.systemFont(ofSize: 7.0)
-    
-    /// The rotation angle (in degrees) for value-text labels
-    open var valueLabelAngle: CGFloat = CGFloat(0.0)
-    
-    /// The form to draw for this dataset in the legend.
-    open var form = Legend.Form.default
-    
-    /// The form size to draw for this dataset in the legend.
-    ///
-    /// Return `NaN` to use the default legend form size.
-    open var formSize: CGFloat = CGFloat.nan
-    
-    /// The line width for drawing the form of this dataset in the legend
-    ///
-    /// Return `NaN` to use the default legend form line width.
-    open var formLineWidth: CGFloat = CGFloat.nan
-    
-    /// Line dash configuration for legend shapes that consist of lines.
-    ///
-    /// This is how much (in pixels) into the dash pattern are we starting from.
-    open var formLineDashPhase: CGFloat = 0.0
-    
-    /// Line dash configuration for legend shapes that consist of lines.
-    ///
-    /// This is the actual dash pattern.
-    /// I.e. [2, 3] will paint [--   --   ]
-    /// [1, 3, 4, 2] will paint [-   ----  -   ----  ]
-    open var formLineDashLengths: [CGFloat]? = nil
-    
-    /// Set this to true to draw y-values on the chart.
-    ///
-    /// - Note: For bar and line charts: if `maxVisibleCount` is reached, no values will be drawn even if this is enabled.
-    open var drawValuesEnabled = true
-    
-    /// `true` if y-value drawing is enabled, `false` ifnot
-    open var isDrawValuesEnabled: Bool
-    {
-        return drawValuesEnabled
-    }
-
-    /// Set this to true to draw y-icons on the chart.
-    ///
-    /// - Note: For bar and line charts: if `maxVisibleCount` is reached, no icons will be drawn even if this is enabled.
-    open var drawIconsEnabled = true
-    
-    /// Returns true if y-icon drawing is enabled, false if not
-    open var isDrawIconsEnabled: Bool
-    {
-        return drawIconsEnabled
-    }
-    
-    /// Offset of icons drawn on the chart.  
-    ///
-    /// For all charts except Pie and Radar it will be ordinary (x offset, y offset).
-    ///
-    /// For Pie and Radar chart it will be (y offset, distance from center offset); so if you want icon to be rendered under value, you should increase X component of CGPoint, and if you want icon to be rendered closet to center, you should decrease height component of CGPoint.
-    open var iconsOffset = CGPoint(x: 0, y: 0)
-    
-    /// Set the visibility of this DataSet. If not visible, the DataSet will not be drawn to the chart upon refreshing it.
-    open var visible = true
-    
-    /// `true` if this DataSet is visible inside the chart, or `false` ifit is currently hidden.
-    open var isVisible: Bool
-    {
-        return visible
-    }
-    
-    // MARK: - NSObject
-    
-    open override var description: String
-    {
-        return String(format: "%@, label: %@, %i entries", arguments: [NSStringFromClass(type(of: self)), self.label ?? "", self.entryCount])
-    }
-    
-    open override var debugDescription: String
-    {
-        return (0..<entryCount).reduce(description + ":") {
-            "\($0)\n\(self.entryForIndex($1)?.description ?? "")"
-        }
-    }
-    
-    // MARK: - NSCopying
-    
-    open func copy(with zone: NSZone? = nil) -> Any 
-    {
-        let copy = type(of: self).init()
-        
-        copy.colors = colors
-        copy.valueColors = valueColors
-        copy.label = label
-        copy.axisDependency = axisDependency
-        copy.highlightEnabled = highlightEnabled
-        copy.valueFormatter = valueFormatter
-        copy.valueFont = valueFont
-        copy.form = form
-        copy.formSize = formSize
-        copy.formLineWidth = formLineWidth
-        copy.formLineDashPhase = formLineDashPhase
-        copy.formLineDashLengths = formLineDashLengths
-        copy.drawValuesEnabled = drawValuesEnabled
-        copy.drawIconsEnabled = drawIconsEnabled
-        copy.iconsOffset = iconsOffset
-        copy.visible = visible
-        
-        return copy
-    }
-}

+ 0 - 108
Pods/Charts/Source/Charts/Data/Implementations/Standard/BarChartData.swift

@@ -1,108 +0,0 @@
-//
-//  BarChartData.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-open class BarChartData: BarLineScatterCandleBubbleChartData
-{
-    public required init()
-    {
-        super.init()
-    }
-    
-    public override init(dataSets: [ChartDataSetProtocol])
-    {
-        super.init(dataSets: dataSets)
-    }
-
-    public required init(arrayLiteral elements: ChartDataSetProtocol...)
-    {
-        super.init(dataSets: elements)
-    }
-
-    /// The width of the bars on the x-axis, in values (not pixels)
-    ///
-    /// **default**: 0.85
-    @objc open var barWidth = Double(0.85)
-    
-    /// Groups all BarDataSet objects this data object holds together by modifying the x-value of their entries.
-    /// Previously set x-values of entries will be overwritten. Leaves space between bars and groups as specified by the parameters.
-    /// Do not forget to call notifyDataSetChanged() on your BarChart object after calling this method.
-    ///
-    /// - Parameters:
-    ///   - fromX: the starting point on the x-axis where the grouping should begin
-    ///   - groupSpace: The space between groups of bars in values (not pixels) e.g. 0.8f for bar width 1f
-    ///   - barSpace: The space between individual bars in values (not pixels) e.g. 0.1f for bar width 1f
-    @objc open func groupBars(fromX: Double, groupSpace: Double, barSpace: Double)
-    {
-        guard !isEmpty else {
-            print("BarData needs to hold at least 2 BarDataSets to allow grouping.", terminator: "\n")
-            return
-        }
-
-        let max = maxEntryCountSet
-        let maxEntryCount = max?.entryCount ?? 0
-        
-        let groupSpaceWidthHalf = groupSpace / 2.0
-        let barSpaceHalf = barSpace / 2.0
-        let barWidthHalf = self.barWidth / 2.0
-        
-        var fromX = fromX
-        
-        let interval = groupWidth(groupSpace: groupSpace, barSpace: barSpace)
-
-        for i in 0..<maxEntryCount
-        {
-            let start = fromX
-            fromX += groupSpaceWidthHalf
-            
-            (_dataSets as! [BarChartDataSetProtocol]).forEach { set in
-                fromX += barSpaceHalf
-                fromX += barWidthHalf
-                
-                if i < set.entryCount
-                {
-                    if let entry = set.entryForIndex(i)
-                    {
-                        entry.x = fromX
-                    }
-                }
-                
-                fromX += barWidthHalf
-                fromX += barSpaceHalf
-            }
-            
-            fromX += groupSpaceWidthHalf
-            let end = fromX
-            let innerInterval = end - start
-            let diff = interval - innerInterval
-            
-            // correct rounding errors
-            if diff > 0 || diff < 0
-            {
-                fromX += diff
-            }
-        }
-        
-        notifyDataChanged()
-    }
-    
-    /// In case of grouped bars, this method returns the space an individual group of bar needs on the x-axis.
-    ///
-    /// - Parameters:
-    ///   - groupSpace:
-    ///   - barSpace:
-    @objc open func groupWidth(groupSpace: Double, barSpace: Double) -> Double
-    {
-        return Double(count) * (self.barWidth + barSpace) + groupSpace
-    }
-}

+ 0 - 214
Pods/Charts/Source/Charts/Data/Implementations/Standard/BarChartDataEntry.swift

@@ -1,214 +0,0 @@
-//
-//  BarChartDataEntry.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-open class BarChartDataEntry: ChartDataEntry
-{
-    /// the values the stacked barchart holds
-    private var _yVals: [Double]?
-    
-    /// the ranges for the individual stack values - automatically calculated
-    private var _ranges: [Range]?
-    
-    /// the sum of all negative values this entry (if stacked) contains
-    private var _negativeSum: Double = 0.0
-    
-    /// the sum of all positive values this entry (if stacked) contains
-    private var _positiveSum: Double = 0.0
-    
-    public required init()
-    {
-        super.init()
-    }
-    
-    /// Constructor for normal bars (not stacked).
-    public override init(x: Double, y: Double)
-    {
-        super.init(x: x, y: y)
-    }
-    
-    /// Constructor for normal bars (not stacked).
-    public convenience init(x: Double, y: Double, data: Any?)
-    {
-        self.init(x: x, y: y)
-        self.data = data
-    }
-    
-    /// Constructor for normal bars (not stacked).
-    public convenience init(x: Double, y: Double, icon: NSUIImage?)
-    {
-        self.init(x: x, y: y)
-        self.icon = icon
-    }
-    
-    /// Constructor for normal bars (not stacked).
-    public convenience init(x: Double, y: Double, icon: NSUIImage?, data: Any?)
-    {
-        self.init(x: x, y: y)
-        self.icon = icon
-        self.data = data
-    }
-    
-    /// Constructor for stacked bar entries.
-    @objc public init(x: Double, yValues: [Double])
-    {
-        super.init(x: x, y: BarChartDataEntry.calcSum(values: yValues))
-        self._yVals = yValues
-        calcPosNegSum()
-        calcRanges()
-    }
-
-    /// Constructor for stacked bar entries. One data object for whole stack
-    @objc public convenience init(x: Double, yValues: [Double], icon: NSUIImage?)
-    {
-        self.init(x: x, yValues: yValues)
-        self.icon = icon
-    }
-
-    /// Constructor for stacked bar entries. One data object for whole stack
-    @objc public convenience init(x: Double, yValues: [Double], data: Any?)
-    {
-        self.init(x: x, yValues: yValues)
-        self.data = data
-    }
-
-    /// Constructor for stacked bar entries. One data object for whole stack
-    @objc public convenience init(x: Double, yValues: [Double], icon: NSUIImage?, data: Any?)
-    {
-        self.init(x: x, yValues: yValues)
-        self.icon = icon
-        self.data = data
-    }
-    
-    @objc open func sumBelow(stackIndex: Int) -> Double
-    {
-        guard let yVals = _yVals, yVals.indices.contains(stackIndex) else
-        {
-            return 0
-        }
-
-        let remainder = yVals[stackIndex...].reduce(into: 0.0) { $0 += $1 }
-        return remainder
-    }
-    
-    /// The sum of all negative values this entry (if stacked) contains. (this is a positive number)
-    @objc open var negativeSum: Double
-    {
-        return _negativeSum
-    }
-    
-    /// The sum of all positive values this entry (if stacked) contains.
-    @objc open var positiveSum: Double
-    {
-        return _positiveSum
-    }
-
-    var stackSize: Int { yValues?.count ?? 1}
-
-    @objc open func calcPosNegSum()
-    {
-        (_negativeSum, _positiveSum) = _yVals?.reduce(into: (0,0)) { (result, y) in
-            if y < 0
-            {
-                result.0 += -y
-            }
-            else
-            {
-                result.1 += y
-            }
-        } ?? (0,0)
-    }
-    
-    /// Splits up the stack-values of the given bar-entry into Range objects.
-    ///
-    /// - Parameters:
-    ///   - entry:
-    /// - Returns:
-    @objc open func calcRanges()
-    {
-        guard let values = yValues, !values.isEmpty else { return }
-
-        if _ranges == nil
-        {
-            _ranges = [Range]()
-        }
-        else
-        {
-            _ranges!.removeAll()
-        }
-        
-        _ranges!.reserveCapacity(values.count)
-        
-        var negRemain = -negativeSum
-        var posRemain: Double = 0.0
-        
-        for value in values
-        {
-            if value < 0
-            {
-                _ranges!.append(Range(from: negRemain, to: negRemain - value))
-                negRemain -= value
-            }
-            else
-            {
-                _ranges!.append(Range(from: posRemain, to: posRemain + value))
-                posRemain += value
-            }
-        }
-    }
-    
-    // MARK: Accessors
-    
-    /// the values the stacked barchart holds
-    @objc open var isStacked: Bool { return _yVals != nil }
-    
-    /// the values the stacked barchart holds
-    @objc open var yValues: [Double]?
-    {
-        get { return self._yVals }
-        set
-        {
-            self.y = BarChartDataEntry.calcSum(values: newValue ?? [])
-            self._yVals = newValue
-            calcPosNegSum()
-            calcRanges()
-        }
-    }
-    
-    /// The ranges of the individual stack-entries. Will return null if this entry is not stacked.
-    @objc open var ranges: [Range]?
-    {
-        return _ranges
-    }
-    
-    // MARK: NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! BarChartDataEntry
-        copy._yVals = _yVals
-        copy.y = y
-        copy._negativeSum = _negativeSum
-        copy._positiveSum = _positiveSum
-        return copy
-    }
-    
-    /// Calculates the sum across all values of the given stack.
-    ///
-    /// - Parameters:
-    ///   - vals:
-    /// - Returns:
-    private static func calcSum(values: [Double]) -> Double
-    {
-        values.reduce(into: 0, +=)
-    }
-}

+ 0 - 134
Pods/Charts/Source/Charts/Data/Implementations/Standard/BarChartDataSet.swift

@@ -1,134 +0,0 @@
-//
-//  BarChartDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-open class BarChartDataSet: BarLineScatterCandleBubbleChartDataSet, BarChartDataSetProtocol
-{
-    private func initialize()
-    {
-        self.highlightColor = NSUIColor.black
-        
-        self.calcStackSize(entries: entries as! [BarChartDataEntry])
-        self.calcEntryCountIncludingStacks(entries: entries as! [BarChartDataEntry])
-    }
-    
-    public required init()
-    {
-        super.init()
-        initialize()
-    }
-    
-    public override init(entries: [ChartDataEntry], label: String)
-    {
-        super.init(entries: entries, label: label)
-        initialize()
-    }
-
-    // MARK: - Data functions and accessors
-    
-    /// the maximum number of bars that are stacked upon each other, this value
-    /// is calculated from the Entries that are added to the DataSet
-    private var _stackSize = 1
-    
-    /// the overall entry count, including counting each stack-value individually
-    private var _entryCountStacks = 0
-    
-    /// Calculates the total number of entries this DataSet represents, including
-    /// stacks. All values belonging to a stack are calculated separately.
-    private func calcEntryCountIncludingStacks(entries: [BarChartDataEntry])
-    {
-        _entryCountStacks = entries.lazy
-            .map(\.stackSize)
-            .reduce(into: 0, +=)
-    }
-    
-    /// calculates the maximum stacksize that occurs in the Entries array of this DataSet
-    private func calcStackSize(entries: [BarChartDataEntry])
-    {
-        _stackSize = entries.lazy
-            .map(\.stackSize)
-            .max() ?? 1
-    }
-    
-    open override func calcMinMax(entry e: ChartDataEntry)
-    {
-        guard let e = e as? BarChartDataEntry,
-            !e.y.isNaN
-            else { return }
-        
-        if e.yValues == nil
-        {
-            _yMin = Swift.min(e.y, _yMin)
-            _yMax = Swift.max(e.y, _yMax)
-        }
-        else
-        {
-            _yMin = Swift.min(-e.negativeSum, _yMin)
-            _yMax = Swift.max(e.positiveSum, _yMax)
-        }
-
-        calcMinMaxX(entry: e)
-    }
-    
-    /// The maximum number of bars that can be stacked upon another in this DataSet.
-    open var stackSize: Int
-    {
-        return _stackSize
-    }
-    
-    /// `true` if this DataSet is stacked (stacksize > 1) or not.
-    open var isStacked: Bool
-    {
-        return _stackSize > 1
-    }
-    
-    /// The overall entry count, including counting each stack-value individually
-    @objc open var entryCountStacks: Int
-    {
-        return _entryCountStacks
-    }
-    
-    /// array of labels used to describe the different values of the stacked bars
-    open var stackLabels: [String] = []
-    
-    // MARK: - Styling functions and accessors
-    
-    /// the color used for drawing the bar-shadows. The bar shadows is a surface behind the bar that indicates the maximum value
-    open var barShadowColor = NSUIColor(red: 215.0/255.0, green: 215.0/255.0, blue: 215.0/255.0, alpha: 1.0)
-
-    /// the width used for drawing borders around the bars. If borderWidth == 0, no border will be drawn.
-    open var barBorderWidth : CGFloat = 0.0
-
-    /// the color drawing borders around the bars.
-    open var barBorderColor = NSUIColor.black
-
-    /// the alpha value (transparency) that is used for drawing the highlight indicator bar. min = 0.0 (fully transparent), max = 1.0 (fully opaque)
-    open var highlightAlpha = CGFloat(120.0 / 255.0)
-    
-    // MARK: - NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! BarChartDataSet
-        copy._stackSize = _stackSize
-        copy._entryCountStacks = _entryCountStacks
-        copy.stackLabels = stackLabels
-
-        copy.barShadowColor = barShadowColor
-        copy.barBorderWidth = barBorderWidth
-        copy.barBorderColor = barBorderColor
-        copy.highlightAlpha = highlightAlpha
-        return copy
-    }
-}

+ 0 - 30
Pods/Charts/Source/Charts/Data/Implementations/Standard/BarLineScatterCandleBubbleChartData.swift

@@ -1,30 +0,0 @@
-//
-//  BarLineScatterCandleBubbleChartData.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-open class BarLineScatterCandleBubbleChartData: ChartData
-{
-    public required init()
-    {
-        super.init()
-    }
-    
-    public override init(dataSets: [ChartDataSetProtocol])
-    {
-        super.init(dataSets: dataSets)
-    }
-
-    public required init(arrayLiteral elements: ChartDataSetProtocol...)
-    {
-        super.init(dataSets: elements)
-    }
-}

+ 0 - 38
Pods/Charts/Source/Charts/Data/Implementations/Standard/BarLineScatterCandleBubbleChartDataSet.swift

@@ -1,38 +0,0 @@
-//
-//  BarLineScatterCandleBubbleChartDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-open class BarLineScatterCandleBubbleChartDataSet: ChartDataSet, BarLineScatterCandleBubbleChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    open var highlightColor = NSUIColor(red: 255.0/255.0, green: 187.0/255.0, blue: 115.0/255.0, alpha: 1.0)
-    open var highlightLineWidth = CGFloat(0.5)
-    open var highlightLineDashPhase = CGFloat(0.0)
-    open var highlightLineDashLengths: [CGFloat]?
-    
-    // MARK: - NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! BarLineScatterCandleBubbleChartDataSet
-        copy.highlightColor = highlightColor
-        copy.highlightLineWidth = highlightLineWidth
-        copy.highlightLineDashPhase = highlightLineDashPhase
-        copy.highlightLineDashLengths = highlightLineDashLengths
-        return copy
-    }
-}

+ 0 - 37
Pods/Charts/Source/Charts/Data/Implementations/Standard/BubbleChartData.swift

@@ -1,37 +0,0 @@
-//
-//  BubbleChartData.swift
-//  Charts
-//
-//  Bubble chart implementation:
-//    Copyright 2015 Pierre-Marc Airoldi
-//    Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-open class BubbleChartData: BarLineScatterCandleBubbleChartData
-{
-    public required init()
-    {
-        super.init()
-    }
-    
-    public override init(dataSets: [ChartDataSetProtocol])
-    {
-        super.init(dataSets: dataSets)
-    }
-
-    public required init(arrayLiteral elements: ChartDataSetProtocol...)
-    {
-        super.init(dataSets: elements)
-    }
-
-    /// Sets the width of the circle that surrounds the bubble when highlighted for all DataSet objects this data object contains
-    @objc open func setHighlightCircleWidth(_ width: CGFloat)
-    {
-        (_dataSets as? [BubbleChartDataSetProtocol])?.forEach { $0.highlightCircleWidth = width }
-    }
-}

+ 0 - 79
Pods/Charts/Source/Charts/Data/Implementations/Standard/BubbleChartDataEntry.swift

@@ -1,79 +0,0 @@
-//
-//  BubbleDataEntry.swift
-//  Charts
-//
-//  Bubble chart implementation: 
-//    Copyright 2015 Pierre-Marc Airoldi
-//    Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-open class BubbleChartDataEntry: ChartDataEntry
-{
-    /// The size of the bubble.
-    @objc open var size = CGFloat(0.0)
-    
-    public required init()
-    {
-        super.init()
-    }
-    
-    /// - Parameters:
-    ///   - x: The index on the x-axis.
-    ///   - y: The value on the y-axis.
-    ///   - size: The size of the bubble.
-    @objc public init(x: Double, y: Double, size: CGFloat)
-    {
-        super.init(x: x, y: y)
-        
-        self.size = size
-    }
-    
-    /// - Parameters:
-    ///   - x: The index on the x-axis.
-    ///   - y: The value on the y-axis.
-    ///   - size: The size of the bubble.
-    ///   - data: Spot for additional data this Entry represents.
-    @objc public convenience init(x: Double, y: Double, size: CGFloat, data: Any?)
-    {
-        self.init(x: x, y: y, size: size)
-        self.data = data
-    }
-    
-    /// - Parameters:
-    ///   - x: The index on the x-axis.
-    ///   - y: The value on the y-axis.
-    ///   - size: The size of the bubble.
-    ///   - icon: icon image
-    @objc public convenience init(x: Double, y: Double, size: CGFloat, icon: NSUIImage?)
-    {
-        self.init(x: x, y: y, size: size)
-        self.icon = icon
-    }
-    
-    /// - Parameters:
-    ///   - x: The index on the x-axis.
-    ///   - y: The value on the y-axis.
-    ///   - size: The size of the bubble.
-    ///   - icon: icon image
-    ///   - data: Spot for additional data this Entry represents.
-    @objc public convenience init(x: Double, y: Double, size: CGFloat, icon: NSUIImage?, data: Any?)
-    {
-        self.init(x: x, y: y, size: size)
-        self.icon = icon
-        self.data = data
-    }
-    
-    // MARK: NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! BubbleChartDataEntry
-        copy.size = size
-        return copy
-    }
-}

+ 0 - 53
Pods/Charts/Source/Charts/Data/Implementations/Standard/BubbleChartDataSet.swift

@@ -1,53 +0,0 @@
-//
-//  BubbleChartDataSet.swift
-//  Charts
-//
-//  Bubble chart implementation:
-//    Copyright 2015 Pierre-Marc Airoldi
-//    Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-open class BubbleChartDataSet: BarLineScatterCandleBubbleChartDataSet, BubbleChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    internal var _maxSize = CGFloat(0.0)
-    
-    open var maxSize: CGFloat { return _maxSize }
-    @objc open var normalizeSizeEnabled: Bool = true
-    open var isNormalizeSizeEnabled: Bool { return normalizeSizeEnabled }
-    
-    open override func calcMinMax(entry e: ChartDataEntry)
-    {
-        guard let e = e as? BubbleChartDataEntry
-            else { return }
-        
-        super.calcMinMax(entry: e)
-        
-        _maxSize = Swift.max(e.size, maxSize)
-    }
-    
-    // MARK: - Styling functions and accessors
-    
-    /// Sets/gets the width of the circle that surrounds the bubble when highlighted
-    open var highlightCircleWidth: CGFloat = 2.5
-    
-    // MARK: - NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! BubbleChartDataSet
-        copy._xMin = _xMin
-        copy._xMax = _xMax
-        copy._maxSize = _maxSize
-        copy.normalizeSizeEnabled = normalizeSizeEnabled
-        copy.highlightCircleWidth = highlightCircleWidth
-        return copy
-    }
-}

+ 0 - 30
Pods/Charts/Source/Charts/Data/Implementations/Standard/CandleChartData.swift

@@ -1,30 +0,0 @@
-//
-//  CandleChartData.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-open class CandleChartData: BarLineScatterCandleBubbleChartData
-{
-    public required init()
-    {
-        super.init()
-    }
-    
-    public override init(dataSets: [ChartDataSetProtocol])
-    {
-        super.init(dataSets: dataSets)
-    }
-
-    public required init(arrayLiteral elements: ChartDataSetProtocol...)
-    {
-        super.init(dataSets: elements)
-    }
-}

+ 0 - 98
Pods/Charts/Source/Charts/Data/Implementations/Standard/CandleChartDataEntry.swift

@@ -1,98 +0,0 @@
-//
-//  CandleChartDataEntry.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-open class CandleChartDataEntry: ChartDataEntry
-{
-    /// shadow-high value
-    @objc open var high = Double(0.0)
-    
-    /// shadow-low value
-    @objc open var low = Double(0.0)
-    
-    /// close value
-    @objc open var close = Double(0.0)
-    
-    /// open value
-    @objc open var open = Double(0.0)
-    
-    public required init()
-    {
-        super.init()
-    }
-    
-    @objc public init(x: Double, shadowH: Double, shadowL: Double, open: Double, close: Double)
-    {
-        super.init(x: x, y: (shadowH + shadowL) / 2.0)
-        
-        self.high = shadowH
-        self.low = shadowL
-        self.open = open
-        self.close = close
-    }
-
-    @objc public convenience init(x: Double, shadowH: Double, shadowL: Double, open: Double, close: Double, icon: NSUIImage?)
-    {
-        self.init(x: x, shadowH: shadowH, shadowL: shadowL, open: open, close: close)
-        self.icon = icon
-    }
-
-    @objc public convenience init(x: Double, shadowH: Double, shadowL: Double, open: Double, close: Double, data: Any?)
-    {
-        self.init(x: x, shadowH: shadowH, shadowL: shadowL, open: open, close: close)
-        self.data = data
-    }
-
-    @objc public convenience init(x: Double, shadowH: Double, shadowL: Double, open: Double, close: Double, icon: NSUIImage?, data: Any?)
-    {
-        self.init(x: x, shadowH: shadowH, shadowL: shadowL, open: open, close: close)
-        self.icon = icon
-        self.data = data
-    }
-    
-    /// The overall range (difference) between shadow-high and shadow-low.
-    @objc open var shadowRange: Double
-    {
-        return abs(high - low)
-    }
-    
-    /// The body size (difference between open and close).
-    @objc open var bodyRange: Double
-    {
-        return abs(open - close)
-    }
-    
-    /// the center value of the candle. (Middle value between high and low)
-    open override var y: Double
-    {
-        get
-        {
-            return super.y
-        }
-        set
-        {
-            super.y = (high + low) / 2.0
-        }
-    }
-    
-    // MARK: NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! CandleChartDataEntry
-        copy.high = high
-        copy.low = low
-        copy.open = open
-        copy.close = close
-        return copy
-    }
-}

+ 0 - 117
Pods/Charts/Source/Charts/Data/Implementations/Standard/CandleChartDataSet.swift

@@ -1,117 +0,0 @@
-//
-//  CandleChartDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-open class CandleChartDataSet: LineScatterCandleRadarChartDataSet, CandleChartDataSetProtocol
-{
-    
-    public required init()
-    {
-        super.init()
-    }
-    
-    public override init(entries: [ChartDataEntry], label: String)
-    {
-        super.init(entries: entries, label: label)
-    }
-    
-    // MARK: - Data functions and accessors
-    
-    open override func calcMinMax(entry e: ChartDataEntry)
-    {
-        guard let e = e as? CandleChartDataEntry
-            else { return }
-
-        _yMin = Swift.min(e.low, _yMin)
-        _yMax = Swift.max(e.high, _yMax)
-
-        calcMinMaxX(entry: e)
-    }
-    
-    open override func calcMinMaxY(entry e: ChartDataEntry)
-    {
-        guard let e = e as? CandleChartDataEntry
-            else { return }
-
-        _yMin = Swift.min(e.low, _yMin)
-        _yMax = Swift.max(e.high, _yMin)
-
-        _yMin = Swift.min(e.low, _yMax)
-        _yMax = Swift.max(e.high, _yMax)
-    }
-    
-    // MARK: - Styling functions and accessors
-    
-    /// the space between the candle entries
-    ///
-    /// **default**: 0.1 (10%)
-    private var _barSpace: CGFloat = 0.1
-
-    /// the space that is left out on the left and right side of each candle,
-    /// **default**: 0.1 (10%), max 0.45, min 0.0
-    open var barSpace: CGFloat
-    {
-        get
-        {
-            return _barSpace
-        }
-        set
-        {
-            _barSpace = newValue.clamped(to: 0...0.45)
-        }
-    }
-    
-    /// should the candle bars show?
-    /// when false, only "ticks" will show
-    ///
-    /// **default**: true
-    open var showCandleBar: Bool = true
-    
-    /// the width of the candle-shadow-line in pixels.
-    ///
-    /// **default**: 1.5
-    open var shadowWidth = CGFloat(1.5)
-    
-    /// the color of the shadow line
-    open var shadowColor: NSUIColor?
-    
-    /// use candle color for the shadow
-    open var shadowColorSameAsCandle = false
-    
-    /// Is the shadow color same as the candle color?
-    open var isShadowColorSameAsCandle: Bool { return shadowColorSameAsCandle }
-    
-    /// color for open == close
-    open var neutralColor: NSUIColor?
-    
-    /// color for open > close
-    open var increasingColor: NSUIColor?
-    
-    /// color for open < close
-    open var decreasingColor: NSUIColor?
-    
-    /// Are increasing values drawn as filled?
-    /// increasing candlesticks are traditionally hollow
-    open var increasingFilled = false
-    
-    /// Are increasing values drawn as filled?
-    open var isIncreasingFilled: Bool { return increasingFilled }
-    
-    /// Are decreasing values drawn as filled?
-    /// descreasing candlesticks are traditionally filled
-    open var decreasingFilled = true
-    
-    /// Are decreasing values drawn as filled?
-    open var isDecreasingFilled: Bool { return decreasingFilled }
-}

+ 0 - 574
Pods/Charts/Source/Charts/Data/Implementations/Standard/ChartData.swift

@@ -1,574 +0,0 @@
-//
-//  ChartData.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-open class ChartData: NSObject, ExpressibleByArrayLiteral
-{
-
-    @objc public internal(set) var xMax = -Double.greatestFiniteMagnitude
-    @objc public internal(set) var xMin = Double.greatestFiniteMagnitude
-    @objc public internal(set) var yMax = -Double.greatestFiniteMagnitude
-    @objc public internal(set) var yMin = Double.greatestFiniteMagnitude
-    var leftAxisMax = -Double.greatestFiniteMagnitude
-    var leftAxisMin = Double.greatestFiniteMagnitude
-    var rightAxisMax = -Double.greatestFiniteMagnitude
-    var rightAxisMin = Double.greatestFiniteMagnitude
-
-    // MARK: - Accessibility
-    
-    /// When the data entry labels are generated identifiers, set this property to prepend a string before each identifier
-    ///
-    /// For example, if a label is "#3", settings this property to "Item" allows it to be spoken as "Item #3"
-    @objc open var accessibilityEntryLabelPrefix: String?
-    
-    /// When the data entry value requires a unit, use this property to append the string representation of the unit to the value
-    ///
-    /// For example, if a value is "44.1", setting this property to "m" allows it to be spoken as "44.1 m"
-    @objc open var accessibilityEntryLabelSuffix: String?
-    
-    /// If the data entry value is a count, set this to true to allow plurals and other grammatical changes
-    /// **default**: false
-    @objc open var accessibilityEntryLabelSuffixIsCount: Bool = false
-    
-    var _dataSets = [Element]()
-    
-    public override required init()
-    {
-        super.init()
-    }
-
-    public required init(arrayLiteral elements: Element...)
-    {
-        super.init()
-        self.dataSets = elements
-    }
-
-    @objc public init(dataSets: [Element])
-    {
-        super.init()
-        self.dataSets = dataSets
-    }
-    
-    @objc public convenience init(dataSet: Element)
-    {
-        self.init(dataSets: [dataSet])
-    }
-
-    /// Call this method to let the ChartData know that the underlying data has changed.
-    /// Calling this performs all necessary recalculations needed when the contained data has changed.
-    @objc open func notifyDataChanged()
-    {
-        calcMinMax()
-    }
-    
-    @objc open func calcMinMaxY(fromX: Double, toX: Double)
-    {
-        forEach { $0.calcMinMaxY(fromX: fromX, toX: toX) }
-        
-        // apply the new data
-        calcMinMax()
-    }
-    
-    /// calc minimum and maximum y value over all datasets
-    @objc open func calcMinMax()
-    {
-        leftAxisMax = -.greatestFiniteMagnitude
-        leftAxisMin = .greatestFiniteMagnitude
-        rightAxisMax = -.greatestFiniteMagnitude
-        rightAxisMin = .greatestFiniteMagnitude
-        yMax = -.greatestFiniteMagnitude
-        yMin = .greatestFiniteMagnitude
-        xMax = -.greatestFiniteMagnitude
-        xMin = .greatestFiniteMagnitude
-
-        forEach { calcMinMax(dataSet: $0) }
-
-        // left axis
-        let firstLeft = getFirstLeft(dataSets: dataSets)
-        
-        if firstLeft !== nil
-        {
-            leftAxisMax = firstLeft!.yMax
-            leftAxisMin = firstLeft!.yMin
-
-            for dataSet in _dataSets where dataSet.axisDependency == .left
-            {
-                if dataSet.yMin < leftAxisMin
-                {
-                    leftAxisMin = dataSet.yMin
-                }
-
-                if dataSet.yMax > leftAxisMax
-                {
-                    leftAxisMax = dataSet.yMax
-                }
-            }
-        }
-        
-        // right axis
-        let firstRight = getFirstRight(dataSets: dataSets)
-        
-        if firstRight !== nil
-        {
-            rightAxisMax = firstRight!.yMax
-            rightAxisMin = firstRight!.yMin
-            
-            for dataSet in _dataSets where dataSet.axisDependency == .right
-            {
-                if dataSet.yMin < rightAxisMin
-                {
-                    rightAxisMin = dataSet.yMin
-                }
-
-                if dataSet.yMax > rightAxisMax
-                {
-                    rightAxisMax = dataSet.yMax
-                }
-            }
-        }
-    }
-
-    /// Adjusts the current minimum and maximum values based on the provided Entry object.
-    @objc open func calcMinMax(entry e: ChartDataEntry, axis: YAxis.AxisDependency)
-    {
-        xMax = Swift.max(xMax, e.x)
-        xMin = Swift.min(xMin, e.x)
-        yMax = Swift.max(yMax, e.y)
-        yMin = Swift.min(yMin, e.y)
-
-        switch axis
-        {
-        case .left:
-            leftAxisMax = Swift.max(leftAxisMax, e.y)
-            leftAxisMin = Swift.min(leftAxisMin, e.y)
-
-        case .right:
-            rightAxisMax = Swift.max(rightAxisMax, e.y)
-            rightAxisMin = Swift.min(rightAxisMin, e.y)
-        }
-    }
-    
-    /// Adjusts the minimum and maximum values based on the given DataSet.
-    @objc open func calcMinMax(dataSet d: Element)
-    {
-        xMax = Swift.max(xMax, d.xMax)
-        xMin = Swift.min(xMin, d.xMin)
-        yMax = Swift.max(yMax, d.yMax)
-        yMin = Swift.min(yMin, d.yMin)
-
-        switch d.axisDependency
-        {
-        case .left:
-            leftAxisMax = Swift.max(leftAxisMax, d.yMax)
-            leftAxisMin = Swift.min(leftAxisMin, d.yMin)
-
-        case .right:
-            rightAxisMax = Swift.max(rightAxisMax, d.yMax)
-            rightAxisMin = Swift.min(rightAxisMin, d.yMin)
-        }
-    }
-    
-    /// The number of LineDataSets this object contains
-    // exists only for objc compatibility
-    @objc open var dataSetCount: Int
-    {
-        return dataSets.count
-    }
-
-    @objc open func getYMin(axis: YAxis.AxisDependency) -> Double
-    {
-        // TODO: Why does it make sense to return the other axisMin if there is none for the one requested?
-        switch axis
-        {
-        case .left:
-            if leftAxisMin == .greatestFiniteMagnitude
-            {
-                return rightAxisMin
-            }
-            else
-            {
-                return leftAxisMin
-            }
-
-        case .right:
-            if rightAxisMin == .greatestFiniteMagnitude
-            {
-                return leftAxisMin
-            }
-            else
-            {
-                return rightAxisMin
-            }
-        }
-    }
-    
-    @objc open func getYMax(axis: YAxis.AxisDependency) -> Double
-    {
-        if axis == .left
-        {
-            if leftAxisMax == -.greatestFiniteMagnitude
-            {
-                return rightAxisMax
-            }
-            else
-            {
-                return leftAxisMax
-            }
-        }
-        else
-        {
-            if rightAxisMax == -.greatestFiniteMagnitude
-            {
-                return leftAxisMax
-            }
-            else
-            {
-                return rightAxisMax
-            }
-        }
-    }
-    
-    /// All DataSet objects this ChartData object holds.
-    @objc open var dataSets: [Element]
-    {
-        get
-        {
-            return _dataSets
-        }
-        set
-        {
-            _dataSets = newValue
-            notifyDataChanged()
-        }
-    }
-
-    /// Get the Entry for a corresponding highlight object
-    ///
-    /// - Parameters:
-    ///   - highlight:
-    /// - Returns: The entry that is highlighted
-    @objc open func entry(for highlight: Highlight) -> ChartDataEntry?
-    {
-        guard highlight.dataSetIndex < dataSets.endIndex else { return nil }
-        return self[highlight.dataSetIndex].entryForXValue(highlight.x, closestToY: highlight.y)
-    }
-    
-    /// **IMPORTANT: This method does calculations at runtime. Use with care in performance critical situations.**
-    ///
-    /// - Parameters:
-    ///   - label:
-    ///   - ignorecase:
-    /// - Returns: The DataSet Object with the given label. Sensitive or not.
-    @objc open func dataSet(forLabel label: String, ignorecase: Bool) -> Element?
-    {
-        guard let index = index(forLabel: label, ignoreCase: ignorecase) else { return nil }
-        return self[index]
-    }
-    
-    @objc(dataSetAtIndex:)
-    open func dataSet(at index: Index) -> Element?
-    {
-        guard dataSets.indices.contains(index) else { return nil }
-        return self[index]
-    }
-
-    /// Removes the given DataSet from this data object.
-    /// Also recalculates all minimum and maximum values.
-    ///
-    /// - Returns: `true` if a DataSet was removed, `false` ifno DataSet could be removed.
-    @objc @discardableResult open func removeDataSet(_ dataSet: Element) -> Element?
-    {
-        guard let index = firstIndex(where: { $0 === dataSet }) else { return nil }
-        return remove(at: index)
-    }
-
-    /// Adds an Entry to the DataSet at the specified index. Entries are added to the end of the list.
-    @objc(addEntry:dataSetIndex:)
-    open func appendEntry(_ e: ChartDataEntry, toDataSet dataSetIndex: Index)
-    {
-        guard dataSets.indices.contains(dataSetIndex) else {
-            return print("ChartData.addEntry() - Cannot add Entry because dataSetIndex too high or too low.", terminator: "\n")
-        }
-
-        let set = self[dataSetIndex]
-        if !set.addEntry(e) { return }
-        calcMinMax(entry: e, axis: set.axisDependency)
-    }
-
-    /// Removes the given Entry object from the DataSet at the specified index.
-    @objc @discardableResult open func removeEntry(_ entry: ChartDataEntry, dataSetIndex: Index) -> Bool
-    {
-        guard dataSets.indices.contains(dataSetIndex) else { return false }
-
-        // remove the entry from the dataset
-        let removed = self[dataSetIndex].removeEntry(entry)
-        
-        if removed
-        {
-            calcMinMax()
-        }
-        
-        return removed
-    }
-    
-    /// Removes the Entry object closest to the given xIndex from the ChartDataSet at the
-    /// specified index. 
-    ///
-    /// - Returns: `true` if an entry was removed, `false` ifno Entry was found that meets the specified requirements.
-    @objc @discardableResult open func removeEntry(xValue: Double, dataSetIndex: Index) -> Bool
-    {
-        guard
-            dataSets.indices.contains(dataSetIndex),
-            let entry = self[dataSetIndex].entryForXValue(xValue, closestToY: .nan)
-            else { return false }
-
-        return removeEntry(entry, dataSetIndex: dataSetIndex)
-    }
-    
-    /// - Returns: The DataSet that contains the provided Entry, or null, if no DataSet contains this entry.
-    @objc open func getDataSetForEntry(_ e: ChartDataEntry) -> Element?
-    {
-        return first { $0.entryForXValue(e.x, closestToY: e.y) === e }
-    }
-
-    /// - Returns: The index of the provided DataSet in the DataSet array of this data object, or -1 if it does not exist.
-    @objc open func index(of dataSet: Element) -> Index
-    {
-        // TODO: Return nil instead of -1
-        return firstIndex(where: { $0 === dataSet }) ?? -1
-    }
-    
-    /// - Returns: The first DataSet from the datasets-array that has it's dependency on the left axis. Returns null if no DataSet with left dependency could be found.
-    @objc open func getFirstLeft(dataSets: [Element]) -> Element?
-    {
-        return first { $0.axisDependency == .left }
-    }
-    
-    /// - Returns: The first DataSet from the datasets-array that has it's dependency on the right axis. Returns null if no DataSet with right dependency could be found.
-    @objc open func getFirstRight(dataSets: [Element]) -> Element?
-    {
-        return first { $0.axisDependency == .right }
-    }
-    
-    /// - Returns: All colors used across all DataSet objects this object represents.
-    @objc open var colors: [NSUIColor]
-    {
-        // TODO: Don't return nil
-        return reduce(into: []) { $0 += $1.colors }
-    }
-    
-    /// Sets a custom ValueFormatter for all DataSets this data object contains.
-    @objc open func setValueFormatter(_ formatter: ValueFormatter)
-    {
-        forEach { $0.valueFormatter = formatter }
-    }
-    
-    /// Sets the color of the value-text (color in which the value-labels are drawn) for all DataSets this data object contains.
-    @objc open func setValueTextColor(_ color: NSUIColor)
-    {
-        forEach { $0.valueTextColor = color }
-    }
-    
-    /// Sets the font for all value-labels for all DataSets this data object contains.
-    @objc open func setValueFont(_ font: NSUIFont)
-    {
-        forEach { $0.valueFont = font }
-    }
-
-    /// Enables / disables drawing values (value-text) for all DataSets this data object contains.
-    @objc open func setDrawValues(_ enabled: Bool)
-    {
-        forEach { $0.drawValuesEnabled = enabled }
-    }
-    
-    /// Enables / disables highlighting values for all DataSets this data object contains.
-    /// If set to true, this means that values can be highlighted programmatically or by touch gesture.
-    @objc open var isHighlightEnabled: Bool
-    {
-        get { return allSatisfy { $0.isHighlightEnabled } }
-        set { forEach { $0.highlightEnabled = newValue } }
-    }
-
-    /// Clears this data object from all DataSets and removes all Entries.
-    /// Don't forget to invalidate the chart after this.
-    @objc open func clearValues()
-    {
-        removeAll(keepingCapacity: false)
-    }
-    
-    /// Checks if this data object contains the specified DataSet. 
-    ///
-    /// - Returns: `true` if so, `false` ifnot.
-    @objc open func contains(dataSet: Element) -> Bool
-    {
-        return contains { $0 === dataSet }
-    }
-    
-    /// The total entry count across all DataSet objects this data object contains.
-    @objc open var entryCount: Int
-    {
-        return reduce(0) { return $0 + $1.entryCount }
-    }
-
-    /// The DataSet object with the maximum number of entries or null if there are no DataSets.
-    @objc open var maxEntryCountSet: Element?
-    {
-        return self.max { $0.entryCount < $1.entryCount }
-    }
-}
-
-// MARK: MutableCollection
-extension ChartData: MutableCollection
-{
-    public typealias Index = Int
-    public typealias Element = ChartDataSetProtocol
-
-    public var startIndex: Index
-    {
-        return dataSets.startIndex
-    }
-
-    public var endIndex: Index
-    {
-        return dataSets.endIndex
-    }
-
-    public func index(after: Index) -> Index
-    {
-        return dataSets.index(after: after)
-    }
-
-    public subscript(position: Index) -> Element
-    {
-        get { return dataSets[position] }
-        set { self._dataSets[position] = newValue }
-    }
-}
-
-// MARK: RandomAccessCollection
-extension ChartData: RandomAccessCollection
-{
-    public func index(before: Index) -> Index
-    {
-        return dataSets.index(before: before)
-    }
-}
-
-// TODO: Conform when dropping Objective-C support
-// MARK: RangeReplaceableCollection
-extension ChartData//: RangeReplaceableCollection
-{
-    @objc(addDataSet:)
-    public func append(_ newElement: Element)
-    {
-        _dataSets.append(newElement)
-        calcMinMax(dataSet: newElement)
-    }
-
-    @objc(removeDataSetByIndex:)
-    public func remove(at position: Index) -> Element
-    {
-        let element = _dataSets.remove(at: position)
-        calcMinMax()
-        return element
-    }
-
-    public func removeFirst() -> Element
-    {
-        assert(!(self is CombinedChartData), "\(#function) not supported for CombinedData")
-
-        let element = _dataSets.removeFirst()
-        notifyDataChanged()
-        return element
-    }
-
-    public func removeFirst(_ n: Int)
-    {
-        assert(!(self is CombinedChartData), "\(#function) not supported for CombinedData")
-
-        _dataSets.removeFirst(n)
-        notifyDataChanged()
-    }
-
-    public func removeLast() -> Element
-    {
-        assert(!(self is CombinedChartData), "\(#function) not supported for CombinedData")
-
-        let element = _dataSets.removeLast()
-        notifyDataChanged()
-        return element
-    }
-
-    public func removeLast(_ n: Int)
-    {
-        assert(!(self is CombinedChartData), "\(#function) not supported for CombinedData")
-
-        _dataSets.removeLast(n)
-        notifyDataChanged()
-    }
-
-    public func removeSubrange<R>(_ bounds: R) where R : RangeExpression, Index == R.Bound
-    {
-        assert(!(self is CombinedChartData), "\(#function) not supported for CombinedData")
-
-        _dataSets.removeSubrange(bounds)
-        notifyDataChanged()
-    }
-
-    public func removeAll(keepingCapacity keepCapacity: Bool)
-    {
-        assert(!(self is CombinedChartData), "\(#function) not supported for CombinedData")
-
-        _dataSets.removeAll(keepingCapacity: keepCapacity)
-        notifyDataChanged()
-    }
-
-    public func replaceSubrange<C>(_ subrange: Swift.Range<Index>, with newElements: C) where C : Collection, Element == C.Element
-    {
-        assert(!(self is CombinedChartData), "\(#function) not supported for CombinedData")
-
-        _dataSets.replaceSubrange(subrange, with: newElements)
-        newElements.forEach { self.calcMinMax(dataSet: $0) }
-    }
-}
-
-// MARK: Swift Accessors
-extension ChartData
-{
-    /// Retrieve the index of a ChartDataSet with a specific label from the ChartData. Search can be case sensitive or not.
-    /// **IMPORTANT: This method does calculations at runtime, do not over-use in performance critical situations.**
-    ///
-    /// - Parameters:
-    ///   - label: The label to search for
-    ///   - ignoreCase: if true, the search is not case-sensitive
-    /// - Returns: The index of the DataSet Object with the given label. `nil` if not found
-    public func index(forLabel label: String, ignoreCase: Bool) -> Index?
-    {
-        return ignoreCase
-            ? firstIndex { $0.label?.caseInsensitiveCompare(label) == .orderedSame }
-            : firstIndex { $0.label == label }
-    }
-
-    public subscript(label label: String, ignoreCase ignoreCase: Bool) -> Element?
-    {
-        guard let index = index(forLabel: label, ignoreCase: ignoreCase) else { return nil }
-        return self[index]
-    }
-
-    public subscript(entry entry: ChartDataEntry) -> Element?
-    {
-        assert(!(self is CombinedChartData), "\(#function) not supported for CombinedData")
-
-        guard let index = firstIndex(where: { $0.entryForXValue(entry.x, closestToY: entry.y) === entry }) else { return nil }
-        return self[index]
-    }
-}

+ 0 - 110
Pods/Charts/Source/Charts/Data/Implementations/Standard/ChartDataEntry.swift

@@ -1,110 +0,0 @@
-//
-//  ChartDataEntry.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-open class ChartDataEntry: ChartDataEntryBase, NSCopying
-{
-    /// the x value
-    @objc open var x = 0.0
-    
-    public required init()
-    {
-        super.init()
-    }
-    
-    /// An Entry represents one single entry in the chart.
-    ///
-    /// - Parameters:
-    ///   - x: the x value
-    ///   - y: the y value (the actual value of the entry)
-    @objc public init(x: Double, y: Double)
-    {
-        super.init(y: y)
-        self.x = x
-    }
-    
-    /// An Entry represents one single entry in the chart.
-    ///
-    /// - Parameters:
-    ///   - x: the x value
-    ///   - y: the y value (the actual value of the entry)
-    ///   - data: Space for additional data this Entry represents.
-    
-    @objc public convenience init(x: Double, y: Double, data: Any?)
-    {
-        self.init(x: x, y: y)
-        self.data = data
-    }
-    
-    /// An Entry represents one single entry in the chart.
-    ///
-    /// - Parameters:
-    ///   - x: the x value
-    ///   - y: the y value (the actual value of the entry)
-    ///   - icon: icon image
-    
-    @objc public convenience init(x: Double, y: Double, icon: NSUIImage?)
-    {
-        self.init(x: x, y: y)
-        self.icon = icon
-    }
-    
-    /// An Entry represents one single entry in the chart.
-    ///
-    /// - Parameters:
-    ///   - x: the x value
-    ///   - y: the y value (the actual value of the entry)
-    ///   - icon: icon image
-    ///   - data: Space for additional data this Entry represents.
-    
-    @objc public convenience init(x: Double, y: Double, icon: NSUIImage?, data: Any?)
-    {
-        self.init(x: x, y: y)
-        self.icon = icon
-        self.data = data
-    }
-        
-    // MARK: NSObject
-    
-    open override var description: String
-    {
-        return "ChartDataEntry, x: \(x), y \(y)"
-    }
-    
-    // MARK: NSCopying
-    
-    open func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = type(of: self).init()
-        
-        copy.x = x
-        copy.y = y
-        copy.data = data
-        
-        return copy
-    }
-}
-
-// MARK: Equatable
-extension ChartDataEntry/*: Equatable*/ {
-    open override func isEqual(_ object: Any?) -> Bool {
-        guard let object = object as? ChartDataEntry else { return false }
-
-        if self === object
-        {
-            return true
-        }
-
-        return y == object.y
-            && x == object.x
-    }
-}

+ 0 - 96
Pods/Charts/Source/Charts/Data/Implementations/Standard/ChartDataEntryBase.swift

@@ -1,96 +0,0 @@
-//
-//  ChartDataEntryBase.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-open class ChartDataEntryBase: NSObject
-{
-    /// the y value
-    @objc open var y = 0.0
-    
-    /// optional spot for additional data this Entry represents
-    @objc open var data: Any?
-    
-    /// optional icon image
-    @objc open var icon: NSUIImage?
-    
-    public override required init()
-    {
-        super.init()
-    }
-    
-    /// An Entry represents one single entry in the chart.
-    ///
-    /// - Parameters:
-    ///   - y: the y value (the actual value of the entry)
-    @objc public init(y: Double)
-    {
-        super.init()
-        
-        self.y = y
-    }
-    
-    /// - Parameters:
-    ///   - y: the y value (the actual value of the entry)
-    ///   - data: Space for additional data this Entry represents.
-    
-    @objc public convenience init(y: Double, data: Any?)
-    {
-        self.init(y: y)
-        
-        self.data = data
-    }
-    
-    /// - Parameters:
-    ///   - y: the y value (the actual value of the entry)
-    ///   - icon: icon image
-    
-    @objc public convenience init(y: Double, icon: NSUIImage?)
-    {
-        self.init(y: y)
-
-        self.icon = icon
-    }
-    
-    /// - Parameters:
-    ///   - y: the y value (the actual value of the entry)
-    ///   - icon: icon image
-    ///   - data: Space for additional data this Entry represents.
-    
-    @objc public convenience init(y: Double, icon: NSUIImage?, data: Any?)
-    {
-        self.init(y: y)
-
-        self.icon = icon
-        self.data = data
-    }
-
-    // MARK: NSObject
-    
-    open override var description: String
-    {
-        return "ChartDataEntryBase, y \(y)"
-    }
-}
-
-// MARK: Equatable
-extension ChartDataEntryBase/*: Equatable*/ {
-    open override func isEqual(_ object: Any?) -> Bool {
-        guard let object = object as? ChartDataEntryBase else { return false }
-
-        if self === object
-        {
-            return true
-        }
-
-        return y == object.y
-    }
-}

+ 0 - 489
Pods/Charts/Source/Charts/Data/Implementations/Standard/ChartDataSet.swift

@@ -1,489 +0,0 @@
-//
-//  ChartDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Algorithms
-import Foundation
-
-/// Determines how to round DataSet index values for `ChartDataSet.entryIndex(x, rounding)` when an exact x-value is not found.
-@objc
-public enum ChartDataSetRounding: Int
-{
-    case up = 0
-    case down = 1
-    case closest = 2
-}
-
-/// The DataSet class represents one group or type of entries (Entry) in the Chart that belong together.
-/// It is designed to logically separate different groups of values inside the Chart (e.g. the values for a specific line in the LineChart, or the values of a specific group of bars in the BarChart).
-open class ChartDataSet: ChartBaseDataSet
-{
-    public required init()
-    {
-        entries = []
-        
-        super.init()
-    }
-    
-    public override convenience init(label: String)
-    {
-        self.init(entries: [], label: label)
-    }
-    
-    @objc public init(entries: [ChartDataEntry], label: String)
-    {
-        self.entries = entries 
-
-        super.init(label: label)
-
-        self.calcMinMax()
-    }
-    
-    @objc public convenience init(entries: [ChartDataEntry])
-    {
-        self.init(entries: entries, label: "DataSet")
-    }
-    
-    // MARK: - Data functions and accessors
-
-    /// - Note: Calls `notifyDataSetChanged()` after setting a new value.
-    /// - Returns: The array of y-values that this DataSet represents.
-    /// the entries that this dataset represents / holds together
-    @objc
-    open private(set) var entries: [ChartDataEntry]
-
-    /// Used to replace all entries of a data set while retaining styling properties.
-    /// This is a separate method from a setter on `entries` to encourage usage
-    /// of `Collection` conformances.
-    ///
-    /// - Parameter entries: new entries to replace existing entries in the dataset
-    @objc
-    public func replaceEntries(_ entries: [ChartDataEntry]) {
-        self.entries = entries
-        notifyDataSetChanged()
-    }
-
-    /// maximum y-value in the value array
-    internal var _yMax: Double = -Double.greatestFiniteMagnitude
-    
-    /// minimum y-value in the value array
-    internal var _yMin: Double = Double.greatestFiniteMagnitude
-    
-    /// maximum x-value in the value array
-    internal var _xMax: Double = -Double.greatestFiniteMagnitude
-    
-    /// minimum x-value in the value array
-    internal var _xMin: Double = Double.greatestFiniteMagnitude
-    
-    open override func calcMinMax()
-    {
-        _yMax = -Double.greatestFiniteMagnitude
-        _yMin = Double.greatestFiniteMagnitude
-        _xMax = -Double.greatestFiniteMagnitude
-        _xMin = Double.greatestFiniteMagnitude
-
-        guard !isEmpty else { return }
-
-        forEach(calcMinMax)
-    }
-    
-    open override func calcMinMaxY(fromX: Double, toX: Double)
-    {
-        _yMax = -Double.greatestFiniteMagnitude
-        _yMin = Double.greatestFiniteMagnitude
-
-        guard !isEmpty else { return }
-        
-        let indexFrom = entryIndex(x: fromX, closestToY: .nan, rounding: .closest)
-        var indexTo = entryIndex(x: toX, closestToY: .nan, rounding: .up)
-        if indexTo == -1 { indexTo = entryIndex(x: toX, closestToY: .nan, rounding: .closest) }
-        
-        guard indexTo >= indexFrom else { return }
-        // only recalculate y
-        self[indexFrom...indexTo].forEach(calcMinMaxY)
-    }
-    
-    @objc open func calcMinMaxX(entry e: ChartDataEntry)
-    {
-        _xMin = Swift.min(e.x, _xMin)
-        _xMax = Swift.max(e.x, _xMax)
-    }
-    
-    @objc open func calcMinMaxY(entry e: ChartDataEntry)
-    {
-        _yMin = Swift.min(e.y, _yMin)
-        _yMax = Swift.max(e.y, _yMax)
-    }
-    
-    /// Updates the min and max x and y value of this DataSet based on the given Entry.
-    ///
-    /// - Parameters:
-    ///   - e:
-    internal func calcMinMax(entry e: ChartDataEntry)
-    {
-        calcMinMaxX(entry: e)
-        calcMinMaxY(entry: e)
-    }
-    
-    /// The minimum y-value this DataSet holds
-    @objc open override var yMin: Double { return _yMin }
-    
-    /// The maximum y-value this DataSet holds
-    @objc open override var yMax: Double { return _yMax }
-    
-    /// The minimum x-value this DataSet holds
-    @objc open override var xMin: Double { return _xMin }
-    
-    /// The maximum x-value this DataSet holds
-    @objc open override var xMax: Double { return _xMax }
-    
-    /// The number of y-values this DataSet represents
-    @available(*, deprecated, message: "Use `count` instead")
-    open override var entryCount: Int { return count }
-    
-    /// - Throws: out of bounds
-    /// if `i` is out of bounds, it may throw an out-of-bounds exception
-    /// - Returns: The entry object found at the given index (not x-value!)
-    @available(*, deprecated, message: "Use `subscript(index:)` instead.")
-    open override func entryForIndex(_ i: Int) -> ChartDataEntry?
-    {
-        guard indices.contains(i) else {
-            return nil
-        }
-        return self[i]
-    }
-    
-    /// - Parameters:
-    ///   - xValue: the x-value
-    ///   - closestToY: If there are multiple y-values for the specified x-value,
-    ///   - rounding: determine whether to round up/down/closest if there is no Entry matching the provided x-value
-    /// - Returns: The first Entry object found at the given x-value with binary search.
-    /// If the no Entry at the specified x-value is found, this method returns the Entry at the closest x-value according to the rounding.
-    /// nil if no Entry object at that x-value.
-    open override func entryForXValue(
-        _ xValue: Double,
-        closestToY yValue: Double,
-        rounding: ChartDataSetRounding) -> ChartDataEntry?
-    {
-        let index = entryIndex(x: xValue, closestToY: yValue, rounding: rounding)
-        if index > -1
-        {
-            return self[index]
-        }
-        return nil
-    }
-    
-    /// - Parameters:
-    ///   - xValue: the x-value
-    ///   - closestToY: If there are multiple y-values for the specified x-value,
-    /// - Returns: The first Entry object found at the given x-value with binary search.
-    /// If the no Entry at the specified x-value is found, this method returns the Entry at the closest x-value.
-    /// nil if no Entry object at that x-value.
-    open override func entryForXValue(
-        _ xValue: Double,
-        closestToY yValue: Double) -> ChartDataEntry?
-    {
-        return entryForXValue(xValue, closestToY: yValue, rounding: .closest)
-    }
-    
-    /// - Returns: All Entry objects found at the given xIndex with binary search.
-    /// An empty array if no Entry object at that index.
-    open override func entriesForXValue(_ xValue: Double) -> [ChartDataEntry]
-    {
-        let match: (ChartDataEntry) -> Bool = { $0.x == xValue }
-        var partitioned = self.entries
-        _ = partitioned.partition(by: match)
-        let i = partitioned.partitioningIndex(where: match)
-        guard i < endIndex else { return [] }
-        return partitioned[i...].prefix(while: match)
-    }
-    
-    /// - Parameters:
-    ///   - xValue: x-value of the entry to search for
-    ///   - closestToY: If there are multiple y-values for the specified x-value,
-    ///   - rounding: Rounding method if exact value was not found
-    /// - Returns: The array-index of the specified entry.
-    /// If the no Entry at the specified x-value is found, this method returns the index of the Entry at the closest x-value according to the rounding.
-    open override func entryIndex(
-        x xValue: Double,
-        closestToY yValue: Double,
-        rounding: ChartDataSetRounding) -> Int
-    {
-        var closest = partitioningIndex { $0.x >= xValue }
-        guard closest < endIndex else { return index(before: endIndex) }
-
-        var closestXValue = self[closest].x
-
-        switch rounding {
-        case .up:
-            // If rounding up, and found x-value is lower than specified x, and we can go upper...
-            if closestXValue < xValue && closest < index(before: endIndex)
-            {
-                formIndex(after: &closest)
-            }
-
-        case .down:
-            // If rounding down, and found x-value is upper than specified x, and we can go lower...
-            if closestXValue > xValue && closest > startIndex
-            {
-                formIndex(before: &closest)
-            }
-
-        case .closest:
-            // The closest value in the beginning of this function
-            // `var closest = partitioningIndex { $0.x >= xValue }`
-            // doesn't guarantee closest rounding method
-            if closest > startIndex {
-                let distanceAfter = abs(self[closest].x - xValue)
-                let distanceBefore = abs(self[index(before: closest)].x - xValue)
-                if distanceBefore < distanceAfter
-                {
-                    closest = index(before: closest)
-                }
-                closestXValue = self[closest].x
-            }
-        }
-
-        // Search by closest to y-value
-        if !yValue.isNaN
-        {
-            while closest > startIndex && self[index(before: closest)].x == closestXValue
-            {
-                formIndex(before: &closest)
-            }
-
-            var closestYValue = self[closest].y
-            var closestYIndex = closest
-
-            while closest < index(before: endIndex)
-            {
-                formIndex(after: &closest)
-                let value = self[closest]
-
-                if value.x != closestXValue { break }
-                if abs(value.y - yValue) <= abs(closestYValue - yValue)
-                {
-                    closestYValue = yValue
-                    closestYIndex = closest
-                }
-            }
-
-            closest = closestYIndex
-        }
-        
-        return closest
-    }
-    
-    /// - Parameters:
-    ///   - e: the entry to search for
-    /// - Returns: The array-index of the specified entry
-    // TODO: Should be returning `nil` to follow Swift convention
-    @available(*, deprecated, message: "Use `firstIndex(of:)` or `lastIndex(of:)`")
-    open override func entryIndex(entry e: ChartDataEntry) -> Int
-    {
-        return firstIndex(of: e) ?? -1
-    }
-    
-    /// Adds an Entry to the DataSet dynamically.
-    /// Entries are added to the end of the list.
-    /// This will also recalculate the current minimum and maximum values of the DataSet and the value-sum.
-    ///
-    /// - Parameters:
-    ///   - e: the entry to add
-    /// - Returns: True
-    // TODO: This should return `Void` to follow Swift convention
-    @available(*, deprecated, message: "Use `append(_:)` instead", renamed: "append(_:)")
-    open override func addEntry(_ e: ChartDataEntry) -> Bool
-    {
-        append(e)
-        return true
-    }
-    
-    /// Adds an Entry to the DataSet dynamically.
-    /// Entries are added to their appropriate index respective to it's x-index.
-    /// This will also recalculate the current minimum and maximum values of the DataSet and the value-sum.
-    ///
-    /// - Parameters:
-    ///   - e: the entry to add
-    /// - Returns: True
-    // TODO: This should return `Void` to follow Swift convention
-    open override func addEntryOrdered(_ e: ChartDataEntry) -> Bool
-    {
-        if let last = last, last.x > e.x
-        {
-            let startIndex = entryIndex(x: e.x, closestToY: e.y, rounding: .up)
-            let closestIndex = self[startIndex...].lastIndex { $0.x < e.x }
-                ?? startIndex
-            calcMinMax(entry: e)
-            entries.insert(e, at: closestIndex)
-        }
-        else
-        {
-            append(e)
-        }
-        
-        return true
-    }
-    
-    @available(*, renamed: "remove(_:)")
-    open override func removeEntry(_ entry: ChartDataEntry) -> Bool
-    {
-        remove(entry)
-    }
-
-    /// Removes an Entry from the DataSet dynamically.
-    /// This will also recalculate the current minimum and maximum values of the DataSet and the value-sum.
-    ///
-    /// - Parameters:
-    ///   - entry: the entry to remove
-    /// - Returns: `true` if the entry was removed successfully, else if the entry does not exist
-    open func remove(_ entry: ChartDataEntry) -> Bool
-    {
-        guard let index = firstIndex(of: entry) else { return false }
-        _ = remove(at: index)
-        return true
-    }
-
-    /// Removes the first Entry (at index 0) of this DataSet from the entries array.
-    ///
-    /// - Returns: `true` if successful, `false` if not.
-    // TODO: This should return the removed entry to follow Swift convention.
-    @available(*, deprecated, message: "Use `func removeFirst() -> ChartDataEntry` instead.")
-    open override func removeFirst() -> Bool
-    {
-        let entry: ChartDataEntry? = isEmpty ? nil : removeFirst()
-        return entry != nil
-    }
-    
-    /// Removes the last Entry (at index size-1) of this DataSet from the entries array.
-    ///
-    /// - Returns: `true` if successful, `false` if not.
-    // TODO: This should return the removed entry to follow Swift convention.
-    @available(*, deprecated, message: "Use `func removeLast() -> ChartDataEntry` instead.")
-    open override func removeLast() -> Bool
-    {
-        let entry: ChartDataEntry? = isEmpty ? nil : removeLast()
-        return entry != nil
-    }
-
-    /// Removes all values from this DataSet and recalculates min and max value.
-    @available(*, deprecated, message: "Use `removeAll(keepingCapacity:)` instead.")
-    open override func clear()
-    {
-        removeAll(keepingCapacity: true)
-    }
-    
-    // MARK: - Data functions and accessors
-    
-    // MARK: - NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! ChartDataSet
-        
-        copy.entries = entries
-        copy._yMax = _yMax
-        copy._yMin = _yMin
-        copy._xMax = _xMax
-        copy._xMin = _xMin
-
-        return copy
-    }
-}
-
-// MARK: MutableCollection
-extension ChartDataSet: MutableCollection {
-    public typealias Index = Int
-    public typealias Element = ChartDataEntry
-
-    public var startIndex: Index {
-        return entries.startIndex
-    }
-
-    public var endIndex: Index {
-        return entries.endIndex
-    }
-
-    public func index(after: Index) -> Index {
-        return entries.index(after: after)
-    }
-
-    @objc
-    public subscript(position: Index) -> Element {
-        get {
-            // This is intentionally not a safe subscript to mirror
-            // the behaviour of the built in Swift Collection Types
-            return entries[position]
-        }
-        set {
-            calcMinMax(entry: newValue)
-            entries[position] = newValue
-        }
-    }
-}
-
-// MARK: RandomAccessCollection
-extension ChartDataSet: RandomAccessCollection {
-    public func index(before: Index) -> Index {
-        return entries.index(before: before)
-    }
-}
-
-// MARK: RangeReplaceableCollection
-extension ChartDataSet: RangeReplaceableCollection {
-    public func replaceSubrange<C>(_ subrange: Swift.Range<Index>, with newElements: C) where C : Collection, Element == C.Element {
-        entries.replaceSubrange(subrange, with: newElements)
-        notifyDataSetChanged()
-    }
-    
-    public func append(_ newElement: Element) {
-        calcMinMax(entry: newElement)
-        entries.append(newElement)
-    }
-
-    public func remove(at position: Index) -> Element {
-        let element = entries.remove(at: position)
-        notifyDataSetChanged()
-        return element
-    }
-
-    public func removeFirst() -> Element {
-        let element = entries.removeFirst()
-        notifyDataSetChanged()
-        return element
-    }
-
-    public func removeFirst(_ n: Int) {
-        entries.removeFirst(n)
-        notifyDataSetChanged()
-    }
-
-    public func removeLast() -> Element {
-        let element = entries.removeLast()
-        notifyDataSetChanged()
-        return element
-    }
-
-    public func removeLast(_ n: Int) {
-        entries.removeLast(n)
-        notifyDataSetChanged()
-    }
-
-    public func removeSubrange<R>(_ bounds: R) where R : RangeExpression, Index == R.Bound {
-        entries.removeSubrange(bounds)
-        notifyDataSetChanged()
-    }
-
-    @objc
-    public func removeAll(keepingCapacity keepCapacity: Bool) {
-        entries.removeAll(keepingCapacity: keepCapacity)
-        notifyDataSetChanged()
-    }
-}

+ 0 - 292
Pods/Charts/Source/Charts/Data/Implementations/Standard/CombinedChartData.swift

@@ -1,292 +0,0 @@
-//
-//  CombinedChartData.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-open class CombinedChartData: BarLineScatterCandleBubbleChartData
-{
-    private var _lineData: LineChartData!
-    private var _barData: BarChartData!
-    private var _scatterData: ScatterChartData!
-    private var _candleData: CandleChartData!
-    private var _bubbleData: BubbleChartData!
-    
-    public required init()
-    {
-        super.init()
-    }
-    
-    public override init(dataSets: [ChartDataSetProtocol])
-    {
-        super.init(dataSets: dataSets)
-    }
-
-    public required init(arrayLiteral elements: ChartDataSetProtocol...)
-    {
-        super.init(dataSets: elements)
-    }
-    
-    @objc open var lineData: LineChartData!
-    {
-        get
-        {
-            return _lineData
-        }
-        set
-        {
-            _lineData = newValue
-            notifyDataChanged()
-        }
-    }
-    
-    @objc open var barData: BarChartData!
-    {
-        get
-        {
-            return _barData
-        }
-        set
-        {
-            _barData = newValue
-            notifyDataChanged()
-        }
-    }
-    
-    @objc open var scatterData: ScatterChartData!
-    {
-        get
-        {
-            return _scatterData
-        }
-        set
-        {
-            _scatterData = newValue
-            notifyDataChanged()
-        }
-    }
-    
-    @objc open var candleData: CandleChartData!
-    {
-        get
-        {
-            return _candleData
-        }
-        set
-        {
-            _candleData = newValue
-            notifyDataChanged()
-        }
-    }
-    
-    @objc open var bubbleData: BubbleChartData!
-    {
-        get
-        {
-            return _bubbleData
-        }
-        set
-        {
-            _bubbleData = newValue
-            notifyDataChanged()
-        }
-    }
-    
-    open override func calcMinMax()
-    {
-        _dataSets.removeAll()
-        
-        yMax = -Double.greatestFiniteMagnitude
-        yMin = Double.greatestFiniteMagnitude
-        xMax = -Double.greatestFiniteMagnitude
-        xMin = Double.greatestFiniteMagnitude
-        
-        leftAxisMax = -Double.greatestFiniteMagnitude
-        leftAxisMin = Double.greatestFiniteMagnitude
-        rightAxisMax = -Double.greatestFiniteMagnitude
-        rightAxisMin = Double.greatestFiniteMagnitude
-        
-        let allData = self.allData
-        
-        for data in allData
-        {
-            data.calcMinMax()
-            
-            _dataSets.append(contentsOf: data)
-            
-            if data.yMax > yMax
-            {
-                yMax = data.yMax
-            }
-            
-            if data.yMin < yMin
-            {
-                yMin = data.yMin
-            }
-            
-            if data.xMax > xMax
-            {
-                xMax = data.xMax
-            }
-            
-            if data.xMin < xMin
-            {
-                xMin = data.xMin
-            }
-
-            for set in data
-            {
-                if set.axisDependency == .left
-                {
-                    if set.yMax > leftAxisMax
-                    {
-                        leftAxisMax = set.yMax
-                    }
-                    if set.yMin < leftAxisMin
-                    {
-                        leftAxisMin = set.yMin
-                    }
-                }
-                else
-                {
-                    if set.yMax > rightAxisMax
-                    {
-                        rightAxisMax = set.yMax
-                    }
-                    if set.yMin < rightAxisMin
-                    {
-                        rightAxisMin = set.yMin
-                    }
-                }
-            }
-        }
-    }
-    
-    /// All data objects in row: line-bar-scatter-candle-bubble if not null.
-    @objc open var allData: [ChartData]
-    {
-        var data = [ChartData]()
-        
-        if lineData !== nil
-        {
-            data.append(lineData)
-        }
-        if barData !== nil
-        {
-            data.append(barData)
-        }
-        if scatterData !== nil
-        {
-            data.append(scatterData)
-        }
-        if candleData !== nil
-        {
-            data.append(candleData)
-        }
-        if bubbleData !== nil
-        {
-            data.append(bubbleData)
-        }
-        
-        return data
-    }
-    
-    @objc open func dataByIndex(_ index: Int) -> ChartData
-    {
-        return allData[index]
-    }
-    
-    open func dataIndex(_ data: ChartData) -> Int?
-    {
-        return allData.firstIndex(of: data)
-    }
-    
-    open override func removeDataSet(_ dataSet: ChartDataSetProtocol) -> Element?
-    {
-        for data in allData
-        {
-            if let e = data.removeDataSet(dataSet)
-            {
-                return e
-            }
-        }
-        
-        return nil
-    }
-
-    open override func removeEntry(_ entry: ChartDataEntry, dataSetIndex: Int) -> Bool
-    {
-        print("removeEntry(entry, dataSetIndex) not supported for CombinedData", terminator: "\n")
-        return false
-    }
-    
-    open override func removeEntry(xValue: Double, dataSetIndex: Int) -> Bool
-    {
-        print("removeEntry(xValue, dataSetIndex) not supported for CombinedData", terminator: "\n")
-        return false
-    }
-    
-    open override func notifyDataChanged()
-    {
-        _lineData?.notifyDataChanged()
-        _barData?.notifyDataChanged()
-        _scatterData?.notifyDataChanged()
-        _candleData?.notifyDataChanged()
-        _bubbleData?.notifyDataChanged()
-
-        super.notifyDataChanged() // recalculate everything
-    }
-    
-    /// Get the Entry for a corresponding highlight object
-    ///
-    /// - Parameters:
-    ///   - highlight:
-    /// - Returns: The entry that is highlighted
-    @objc override open func entry(for highlight: Highlight) -> ChartDataEntry?
-    {
-        // The value of the highlighted entry could be NaN - if we are not interested in highlighting a specific value.
-        getDataSetByHighlight(highlight)?
-            .entriesForXValue(highlight.x)
-            .first { $0.y == highlight.y || highlight.y.isNaN }
-    }
-    
-    /// Get dataset for highlight
-    ///
-    /// - Parameters:
-    ///   - highlight: current highlight
-    /// - Returns: dataset related to highlight
-    @objc open func getDataSetByHighlight(_ highlight: Highlight) -> ChartDataSetProtocol!
-    {
-        guard allData.indices.contains(highlight.dataIndex) else
-        {
-            return nil
-        }
-
-        let data = dataByIndex(highlight.dataIndex)
-
-        guard data.indices.contains(highlight.dataSetIndex) else
-        {
-            return nil
-        }
-
-        // The value of the highlighted entry could be NaN - if we are not interested in highlighting a specific value.
-        return data[highlight.dataSetIndex]
-    }
-
-    // MARK: Unsupported Collection Methods
-
-    public override func append(_ newElement: ChartData.Element) {
-        fatalError("append(_:) not supported for CombinedData")
-    }
-
-    public override func remove(at i: Int) -> ChartDataSetProtocol {
-        fatalError("remove(at:) not supported for CombinedData")
-    }
-}

+ 0 - 31
Pods/Charts/Source/Charts/Data/Implementations/Standard/LineChartData.swift

@@ -1,31 +0,0 @@
-//
-//  LineChartData.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-/// Data object that encapsulates all data associated with a LineChart.
-open class LineChartData: ChartData
-{
-    public required init()
-    {
-        super.init()
-    }
-    
-    public override init(dataSets: [ChartDataSetProtocol])
-    {
-        super.init(dataSets: dataSets)
-    }
-
-    public required init(arrayLiteral elements: ChartDataSetProtocol...)
-    {
-        super.init(dataSets: elements)
-    }
-}

+ 0 - 177
Pods/Charts/Source/Charts/Data/Implementations/Standard/LineChartDataSet.swift

@@ -1,177 +0,0 @@
-//
-//  LineChartDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-open class LineChartDataSet: LineRadarChartDataSet, LineChartDataSetProtocol
-{
-    @objc(LineChartMode)
-    public enum Mode: Int
-    {
-        case linear
-        case stepped
-        case cubicBezier
-        case horizontalBezier
-    }
-    
-    private func initialize()
-    {
-        // default color
-        circleColors.append(NSUIColor(red: 140.0/255.0, green: 234.0/255.0, blue: 255.0/255.0, alpha: 1.0))
-    }
-    
-    public required init()
-    {
-        super.init()
-        initialize()
-    }
-    
-    public override init(entries: [ChartDataEntry], label: String)
-    {
-        super.init(entries: entries, label: label)
-        initialize()
-    }
-    
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// The drawing mode for this line dataset
-    ///
-    /// **default**: Linear
-    open var mode: Mode = Mode.linear
-    
-    private var _cubicIntensity = CGFloat(0.2)
-    
-    /// Intensity for cubic lines (min = 0.05, max = 1)
-    ///
-    /// **default**: 0.2
-    open var cubicIntensity: CGFloat
-    {
-        get
-        {
-            return _cubicIntensity
-        }
-        set
-        {
-            _cubicIntensity = newValue.clamped(to: 0.05...1)
-        }
-    }
-
-    open var isDrawLineWithGradientEnabled = false
-
-    open var gradientPositions: [CGFloat]?
-    
-    /// The radius of the drawn circles.
-    open var circleRadius = CGFloat(8.0)
-    
-    /// The hole radius of the drawn circles
-    open var circleHoleRadius = CGFloat(4.0)
-    
-    open var circleColors = [NSUIColor]()
-    
-    /// - Returns: The color at the given index of the DataSet's circle-color array.
-    /// Performs a IndexOutOfBounds check by modulus.
-    open func getCircleColor(atIndex index: Int) -> NSUIColor?
-    {
-        let size = circleColors.count
-        let index = index % size
-        if index >= size
-        {
-            return nil
-        }
-        return circleColors[index]
-    }
-    
-    /// Sets the one and ONLY color that should be used for this DataSet.
-    /// Internally, this recreates the colors array and adds the specified color.
-    open func setCircleColor(_ color: NSUIColor)
-    {
-        circleColors.removeAll(keepingCapacity: false)
-        circleColors.append(color)
-    }
-    
-    open func setCircleColors(_ colors: NSUIColor...)
-    {
-        circleColors.removeAll(keepingCapacity: false)
-        circleColors.append(contentsOf: colors)
-    }
-    
-    /// Resets the circle-colors array and creates a new one
-    open func resetCircleColors(_ index: Int)
-    {
-        circleColors.removeAll(keepingCapacity: false)
-    }
-    
-    /// If true, drawing circles is enabled
-    open var drawCirclesEnabled = true
-    
-    /// `true` if drawing circles for this DataSet is enabled, `false` ifnot
-    open var isDrawCirclesEnabled: Bool { return drawCirclesEnabled }
-    
-    /// The color of the inner circle (the circle-hole).
-    open var circleHoleColor: NSUIColor? = NSUIColor.white
-    
-    /// `true` if drawing circles for this DataSet is enabled, `false` ifnot
-    open var drawCircleHoleEnabled = true
-    
-    /// `true` if drawing the circle-holes is enabled, `false` ifnot.
-    open var isDrawCircleHoleEnabled: Bool { return drawCircleHoleEnabled }
-    
-    /// This is how much (in pixels) into the dash pattern are we starting from.
-    open var lineDashPhase = CGFloat(0.0)
-    
-    /// This is the actual dash pattern.
-    /// I.e. [2, 3] will paint [--   --   ]
-    /// [1, 3, 4, 2] will paint [-   ----  -   ----  ]
-    open var lineDashLengths: [CGFloat]?
-    
-    /// Line cap type, default is CGLineCap.Butt
-    open var lineCapType = CGLineCap.butt
-    
-    /// formatter for customizing the position of the fill-line
-    private var _fillFormatter: FillFormatter = DefaultFillFormatter()
-    
-    /// Sets a custom FillFormatterProtocol to the chart that handles the position of the filled-line for each DataSet. Set this to null to use the default logic.
-    open var fillFormatter: FillFormatter?
-    {
-        get
-        {
-            return _fillFormatter
-        }
-        set
-        {
-            _fillFormatter = newValue ?? DefaultFillFormatter()
-        }
-    }
-    
-    // MARK: NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! LineChartDataSet
-        copy.circleColors = circleColors
-        copy.circleHoleColor = circleHoleColor
-        copy.circleRadius = circleRadius
-        copy.circleHoleRadius = circleHoleRadius
-        copy.cubicIntensity = cubicIntensity
-        copy.lineDashPhase = lineDashPhase
-        copy.lineDashLengths = lineDashLengths
-        copy.lineCapType = lineCapType
-        copy.drawCirclesEnabled = drawCirclesEnabled
-        copy.drawCircleHoleEnabled = drawCircleHoleEnabled
-        copy.mode = mode
-        copy._fillFormatter = _fillFormatter
-        return copy
-    }
-}

+ 0 - 85
Pods/Charts/Source/Charts/Data/Implementations/Standard/LineRadarChartDataSet.swift

@@ -1,85 +0,0 @@
-//
-//  LineRadarChartDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-open class LineRadarChartDataSet: LineScatterCandleRadarChartDataSet, LineRadarChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// The color that is used for filling the line surface area.
-    private var _fillColor = NSUIColor(red: 140.0/255.0, green: 234.0/255.0, blue: 255.0/255.0, alpha: 1.0)
-    
-    /// The color that is used for filling the line surface area.
-    open var fillColor: NSUIColor
-    {
-        get { return _fillColor }
-        set
-        {
-            _fillColor = newValue
-            fill = nil
-        }
-    }
-    
-    /// The object that is used for filling the area below the line.
-    /// **default**: nil
-    open var fill: Fill?
-    
-    /// The alpha value that is used for filling the line surface,
-    /// **default**: 0.33
-    open var fillAlpha = CGFloat(0.33)
-    
-    private var _lineWidth = CGFloat(1.0)
-    
-    /// line width of the chart (min = 0.0, max = 10)
-    ///
-    /// **default**: 1
-    open var lineWidth: CGFloat
-    {
-        get
-        {
-            return _lineWidth
-        }
-        set
-        {
-            _lineWidth = newValue.clamped(to: 0...10)
-        }
-    }
-    
-    /// Set to `true` if the DataSet should be drawn filled (surface), and not just as a line.
-    /// Disabling this will give great performance boost.
-    /// Please note that this method uses the path clipping for drawing the filled area (with images, gradients and layers).
-    open var drawFilledEnabled = false
-    
-    /// `true` if filled drawing is enabled, `false` ifnot
-    open var isDrawFilledEnabled: Bool
-    {
-        return drawFilledEnabled
-    }
-    
-    // MARK: NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! LineRadarChartDataSet
-        copy.fill = fill
-        copy.fillAlpha = fillAlpha
-        copy._fillColor = _fillColor
-        copy._lineWidth = _lineWidth
-        copy.drawFilledEnabled = drawFilledEnabled
-        return copy
-    }
-    
-}

+ 0 - 51
Pods/Charts/Source/Charts/Data/Implementations/Standard/LineScatterCandleRadarChartDataSet.swift

@@ -1,51 +0,0 @@
-//
-//  LineScatterCandleRadarChartDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-
-open class LineScatterCandleRadarChartDataSet: BarLineScatterCandleBubbleChartDataSet, LineScatterCandleRadarChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// Enables / disables the horizontal highlight-indicator. If disabled, the indicator is not drawn.
-    open var drawHorizontalHighlightIndicatorEnabled = true
-    
-    /// Enables / disables the vertical highlight-indicator. If disabled, the indicator is not drawn.
-    open var drawVerticalHighlightIndicatorEnabled = true
-    
-    /// `true` if horizontal highlight indicator lines are enabled (drawn)
-    open var isHorizontalHighlightIndicatorEnabled: Bool { return drawHorizontalHighlightIndicatorEnabled }
-    
-    /// `true` if vertical highlight indicator lines are enabled (drawn)
-    open var isVerticalHighlightIndicatorEnabled: Bool { return drawVerticalHighlightIndicatorEnabled }
-    
-    /// Enables / disables both vertical and horizontal highlight-indicators.
-    /// :param: enabled
-    open func setDrawHighlightIndicators(_ enabled: Bool)
-    {
-        drawHorizontalHighlightIndicatorEnabled = enabled
-        drawVerticalHighlightIndicatorEnabled = enabled
-    }
-    
-    // MARK: NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! LineScatterCandleRadarChartDataSet
-        copy.drawHorizontalHighlightIndicatorEnabled = drawHorizontalHighlightIndicatorEnabled
-        copy.drawVerticalHighlightIndicatorEnabled = drawVerticalHighlightIndicatorEnabled
-        return copy
-    }
-    
-}

+ 0 - 107
Pods/Charts/Source/Charts/Data/Implementations/Standard/PieChartData.swift

@@ -1,107 +0,0 @@
-//
-//  PieData.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-open class PieChartData: ChartData
-{
-    public required init()
-    {
-        super.init()
-    }
-    
-    public override init(dataSets: [ChartDataSetProtocol])
-    {
-        super.init(dataSets: dataSets)
-    }
-
-    public required init(arrayLiteral elements: ChartDataSetProtocol...)
-    {
-        super.init(dataSets: elements)
-    }
-
-    @objc public var dataSet: PieChartDataSetProtocol?
-    {
-        get
-        {
-            return dataSets.first as? PieChartDataSetProtocol
-        }
-        set
-        {
-            if let set = newValue
-            {
-                dataSets = [set]
-            }
-            else
-            {
-                dataSets = []
-            }
-        }
-    }
-
-    /// - returns: All up to one dataSet object this ChartData object holds.
-    @objc open override var dataSets: [ChartDataSetProtocol]
-    {
-        get
-        {
-            assert(super.dataSets.count <= 1, "Found multiple data sets while pie chart only allows one")
-            return super.dataSets
-        }
-        set
-        {
-            super.dataSets = newValue
-        }
-    }
-    
-    open override func dataSet(at index: ChartData.Index) -> ChartData.Element?
-    {
-        guard index == 0 else { return nil }
-        return self[index]
-    }
-    
-    open override func dataSet(forLabel label: String, ignorecase: Bool) -> ChartDataSetProtocol?
-    {
-        if dataSets.first?.label == nil
-        {
-            return nil
-        }
-        
-        if ignorecase
-        {
-            if let label = dataSets[0].label, label.caseInsensitiveCompare(label) == .orderedSame
-            {
-                return dataSets[0]
-            }
-        }
-        else
-        {
-            if label == dataSets[0].label
-            {
-                return dataSets[0]
-            }
-        }
-        return nil
-    }
-    
-    @objc override open func entry(for highlight: Highlight) -> ChartDataEntry?
-    {
-        return dataSet?.entryForIndex(Int(highlight.x))
-    }
-    
-    /// The total y-value sum across all DataSet objects the this object represents.
-    @objc open var yValueSum: Double
-    {
-        guard let dataSet = dataSet else { return 0.0 }
-        return (0..<dataSet.entryCount).reduce(into: 0) {
-            $0 += dataSet.entryForIndex($1)?.y ?? 0
-        }
-    }
-}

+ 0 - 119
Pods/Charts/Source/Charts/Data/Implementations/Standard/PieChartDataEntry.swift

@@ -1,119 +0,0 @@
-//
-//  PieChartDataEntry.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-open class PieChartDataEntry: ChartDataEntry
-{
-    public required init()
-    {
-        super.init()
-    }
-    
-
-    /// - Parameters:
-    ///   - value: The value on the y-axis
-    @objc public init(value: Double)
-    {
-        super.init(x: .nan, y: value)
-    }
-
-    /// - Parameters:
-    ///   - value: The value on the y-axis
-    ///   - label: The label for the x-axis
-    @objc public convenience init(value: Double, label: String?)
-    {
-        self.init(value: value)
-        self.label = label
-    }
-    
-    /// - Parameters:
-    ///   - value: The value on the y-axis
-    ///   - label: The label for the x-axis
-    ///   - data: Spot for additional data this Entry represents
-    @objc public convenience init(value: Double, label: String?, data: Any?)
-    {
-        self.init(value: value, label: label, icon: nil, data: data)
-    }
-    
-    /// - Parameters:
-    ///   - value: The value on the y-axis
-    ///   - label: The label for the x-axis
-    ///   - icon: icon image
-    @objc public convenience init(value: Double, label: String?, icon: NSUIImage?)
-    {
-        self.init(value: value)
-        self.label = label
-        self.icon = icon
-    }
-    
-    /// - Parameters:
-    ///   - value: The value on the y-axis
-    ///   - label: The label for the x-axis
-    ///   - icon: icon image
-    ///   - data: Spot for additional data this Entry represents
-    @objc public convenience init(value: Double, label: String?, icon: NSUIImage?, data: Any?)
-    {
-        self.init(value: value)
-        self.label = label
-        self.icon = icon
-        self.data = data
-    }
-
-    /// - Parameters:
-    ///   - value: The value on the y-axis
-    ///   - data: Spot for additional data this Entry represents
-    @objc public convenience init(value: Double, data: Any?)
-    {
-        self.init(value: value)
-        self.data = data
-    }
-    
-    /// - Parameters:
-    ///   - value: The value on the y-axis
-    ///   - icon: icon image
-    @objc public convenience init(value: Double, icon: NSUIImage?)
-    {
-        self.init(value: value)
-        self.icon = icon
-    }
-    
-    /// - Parameters:
-    ///   - value: The value on the y-axis
-    ///   - icon: icon image
-    ///   - data: Spot for additional data this Entry represents
-    @objc public convenience init(value: Double, icon: NSUIImage?, data: Any?)
-    {
-        self.init(value: value)
-        self.icon = icon
-        self.data = data
-    }
-    
-    // MARK: Data property accessors
-    
-    @objc open var label: String?
-    
-    @objc open var value: Double
-    {
-        get { return y }
-        set { y = newValue }
-    }
-        
-    // MARK: NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! PieChartDataEntry
-        copy.label = label
-        return copy
-    }
-}

+ 0 - 130
Pods/Charts/Source/Charts/Data/Implementations/Standard/PieChartDataSet.swift

@@ -1,130 +0,0 @@
-//
-//  PieChartDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-open class PieChartDataSet: ChartDataSet, PieChartDataSetProtocol
-{
-    @objc(PieChartValuePosition)
-    public enum ValuePosition: Int
-    {
-        case insideSlice
-        case outsideSlice
-    }
-
-    private func initialize()
-    {
-        self.valueTextColor = NSUIColor.white
-        self.valueFont = NSUIFont.systemFont(ofSize: 13.0)
-    }
-
-    public required init()
-    {
-        super.init()
-        initialize()
-    }
-
-    public override init(entries: [ChartDataEntry], label: String)
-    {
-        super.init(entries: entries, label: label)
-        initialize()
-    }
-
-    internal override func calcMinMax(entry e: ChartDataEntry)
-    {
-        calcMinMaxY(entry: e)
-    }
-
-    // MARK: - Styling functions and accessors
-
-    private var _sliceSpace = CGFloat(0.0)
-
-    /// the space in pixels between the pie-slices
-    /// **default**: 0
-    /// **maximum**: 20
-    open var sliceSpace: CGFloat
-    {
-        get
-        {
-            return _sliceSpace
-        }
-        set
-        {
-            switch newValue {
-            case ..<0.0: _sliceSpace = 0.0
-            case 20.0...: _sliceSpace = 20.0
-            default: _sliceSpace = newValue
-            }
-        }
-    }
-
-    /// When enabled, slice spacing will be 0.0 when the smallest value is going to be smaller than the slice spacing itself.
-    open var automaticallyDisableSliceSpacing: Bool = false
-
-    /// indicates the selection distance of a pie slice
-    open var selectionShift = CGFloat(18.0)
-
-    open var xValuePosition: ValuePosition = .insideSlice
-    open var yValuePosition: ValuePosition = .insideSlice
-
-    /// When valuePosition is OutsideSlice, indicates line color
-    open var valueLineColor: NSUIColor? = NSUIColor.black
-
-    /// When valuePosition is OutsideSlice and enabled, line will have the same color as the slice
-    open var useValueColorForLine: Bool = false
-
-    /// When valuePosition is OutsideSlice, indicates line width
-    open var valueLineWidth: CGFloat = 1.0
-
-    /// When valuePosition is OutsideSlice, indicates offset as percentage out of the slice size
-    open var valueLinePart1OffsetPercentage: CGFloat = 0.75
-
-    /// When valuePosition is OutsideSlice, indicates length of first half of the line
-    open var valueLinePart1Length: CGFloat = 0.3
-
-    /// When valuePosition is OutsideSlice, indicates length of second half of the line
-    open var valueLinePart2Length: CGFloat = 0.4
-
-    /// When valuePosition is OutsideSlice, this allows variable line length
-    open var valueLineVariableLength: Bool = true
-
-    /// the font for the slice-text labels
-    open var entryLabelFont: NSUIFont? = nil
-
-    /// the color for the slice-text labels
-    open var entryLabelColor: NSUIColor? = nil
-
-    /// the color for the highlighted sector
-    open var highlightColor: NSUIColor? = nil
-
-    // MARK: - NSCopying
-
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! PieChartDataSet
-        copy._sliceSpace = _sliceSpace
-        copy.automaticallyDisableSliceSpacing = automaticallyDisableSliceSpacing
-        copy.selectionShift = selectionShift
-        copy.xValuePosition = xValuePosition
-        copy.yValuePosition = yValuePosition
-        copy.valueLineColor = valueLineColor
-        copy.valueLineWidth = valueLineWidth
-        copy.valueLinePart1OffsetPercentage = valueLinePart1OffsetPercentage
-        copy.valueLinePart1Length = valueLinePart1Length
-        copy.valueLinePart2Length = valueLinePart2Length
-        copy.valueLineVariableLength = valueLineVariableLength
-        copy.entryLabelFont = entryLabelFont
-        copy.entryLabelColor = entryLabelColor
-        copy.highlightColor = highlightColor
-        return copy
-    }
-}

+ 0 - 51
Pods/Charts/Source/Charts/Data/Implementations/Standard/RadarChartData.swift

@@ -1,51 +0,0 @@
-//
-//  RadarChartData.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-open class RadarChartData: ChartData
-{
-    @objc open var highlightColor = NSUIColor(red: 255.0/255.0, green: 187.0/255.0, blue: 115.0/255.0, alpha: 1.0)
-    @objc open var highlightLineWidth = CGFloat(1.0)
-    @objc open var highlightLineDashPhase = CGFloat(0.0)
-    @objc open var highlightLineDashLengths: [CGFloat]?
-    
-    /// Sets labels that should be drawn around the RadarChart at the end of each web line.
-    @objc open var labels = [String]()
-    
-    /// Sets the labels that should be drawn around the RadarChart at the end of each web line.
-    open func setLabels(_ labels: String...)
-    {
-        self.labels = labels
-    }
-    
-    public required init()
-    {
-        super.init()
-    }
-    
-    public override init(dataSets: [ChartDataSetProtocol])
-    {
-        super.init(dataSets: dataSets)
-    }
-
-    public required init(arrayLiteral elements: ChartDataSetProtocol...)
-    {
-        super.init(dataSets: elements)
-    }
-
-    @objc open override func entry(for highlight: Highlight) -> ChartDataEntry?
-    {
-        return self[highlight.dataSetIndex].entryForIndex(Int(highlight.x))
-    }
-}

+ 0 - 54
Pods/Charts/Source/Charts/Data/Implementations/Standard/RadarChartDataEntry.swift

@@ -1,54 +0,0 @@
-//
-//  RadarChartDataEntry.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-open class RadarChartDataEntry: ChartDataEntry
-{
-    public required init()
-    {
-        super.init()
-    }
-
-    /// - Parameters:
-    ///   - value: The value on the y-axis.
-    @objc public init(value: Double)
-    {
-        super.init(x: .nan, y: value)
-    }
-
-    /// - Parameters:
-    ///   - value: The value on the y-axis.
-    ///   - data: Spot for additional data this Entry represents.
-    @objc public convenience init(value: Double, data: Any?)
-    {
-        self.init(value: value)
-        self.data = data
-    }
-    
-    // MARK: Data property accessors
-    
-    @objc open var value: Double
-    {
-        get { return y }
-        set { y = newValue }
-    }
-    
-    // MARK: NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! RadarChartDataEntry
-        
-        return copy
-    }
-}

+ 0 - 59
Pods/Charts/Source/Charts/Data/Implementations/Standard/RadarChartDataSet.swift

@@ -1,59 +0,0 @@
-//
-//  RadarChartDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-open class RadarChartDataSet: LineRadarChartDataSet, RadarChartDataSetProtocol
-{
-    private func initialize()
-    {
-        self.valueFont = NSUIFont.systemFont(ofSize: 13.0)
-    }
-    
-    public required init()
-    {
-        super.init()
-        initialize()
-    }
-    
-    public required override init(entries: [ChartDataEntry], label: String)
-    {
-        super.init(entries: entries, label: label)
-        initialize()
-    }
-    
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// flag indicating whether highlight circle should be drawn or not
-    /// **default**: false
-    open var drawHighlightCircleEnabled: Bool = false
-    
-    /// `true` if highlight circle should be drawn, `false` ifnot
-    open var isDrawHighlightCircleEnabled: Bool { return drawHighlightCircleEnabled }
-    
-    open var highlightCircleFillColor: NSUIColor? = NSUIColor.white
-    
-    /// The stroke color for highlight circle.
-    /// If `nil`, the color of the dataset is taken.
-    open var highlightCircleStrokeColor: NSUIColor?
-    
-    open var highlightCircleStrokeAlpha: CGFloat = 0.3
-    
-    open var highlightCircleInnerRadius: CGFloat = 3.0
-    
-    open var highlightCircleOuterRadius: CGFloat = 4.0
-    
-    open var highlightCircleStrokeWidth: CGFloat = 2.0
-}

+ 0 - 39
Pods/Charts/Source/Charts/Data/Implementations/Standard/ScatterChartData.swift

@@ -1,39 +0,0 @@
-//
-//  ScatterChartData.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-open class ScatterChartData: BarLineScatterCandleBubbleChartData
-{
-    public required init()
-    {
-        super.init()
-    }
-    
-    public override init(dataSets: [ChartDataSetProtocol])
-    {
-        super.init(dataSets: dataSets)
-    }
-
-    public required init(arrayLiteral elements: ChartDataSetProtocol...)
-    {
-        super.init(dataSets: elements)
-    }
-    
-    /// - Returns: The maximum shape-size across all DataSets.
-    @objc open func getGreatestShapeSize() -> CGFloat
-    {
-        return (_dataSets as? [ScatterChartDataSetProtocol])?
-            .max { $0.scatterShapeSize < $1.scatterShapeSize }?
-            .scatterShapeSize ?? 0
-    }
-}

+ 0 - 78
Pods/Charts/Source/Charts/Data/Implementations/Standard/ScatterChartDataSet.swift

@@ -1,78 +0,0 @@
-//
-//  ScatterChartDataSet.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-open class ScatterChartDataSet: LineScatterCandleRadarChartDataSet, ScatterChartDataSetProtocol
-{
-    
-    @objc(ScatterShape)
-    public enum Shape: Int
-    {
-        case square
-        case circle
-        case triangle
-        case cross
-        case x
-        case chevronUp
-        case chevronDown
-    }
-    
-    /// The size the scatter shape will have
-    open var scatterShapeSize = CGFloat(10.0)
-    
-    /// The radius of the hole in the shape (applies to Square, Circle and Triangle)
-    /// **default**: 0.0
-    open var scatterShapeHoleRadius: CGFloat = 0.0
-    
-    /// Color for the hole in the shape. Setting to `nil` will behave as transparent.
-    /// **default**: nil
-    open var scatterShapeHoleColor: NSUIColor? = nil
-    
-    /// Sets the ScatterShape this DataSet should be drawn with.
-    /// This will search for an available ShapeRenderer and set this renderer for the DataSet
-    @objc open func setScatterShape(_ shape: Shape)
-    {
-        self.shapeRenderer = ScatterChartDataSet.renderer(forShape: shape)
-    }
-    
-    /// The IShapeRenderer responsible for rendering this DataSet.
-    /// This can also be used to set a custom IShapeRenderer aside from the default ones.
-    /// **default**: `SquareShapeRenderer`
-    open var shapeRenderer: ShapeRenderer? = SquareShapeRenderer()
-    
-    @objc open class func renderer(forShape shape: Shape) -> ShapeRenderer
-    {
-        switch shape
-        {
-        case .square: return SquareShapeRenderer()
-        case .circle: return CircleShapeRenderer()
-        case .triangle: return TriangleShapeRenderer()
-        case .cross: return CrossShapeRenderer()
-        case .x: return XShapeRenderer()
-        case .chevronUp: return ChevronUpShapeRenderer()
-        case .chevronDown: return ChevronDownShapeRenderer()
-        }
-    }
-    
-    // MARK: NSCopying
-    
-    open override func copy(with zone: NSZone? = nil) -> Any
-    {
-        let copy = super.copy(with: zone) as! ScatterChartDataSet
-        copy.scatterShapeSize = scatterShapeSize
-        copy.scatterShapeHoleRadius = scatterShapeHoleRadius
-        copy.scatterShapeHoleColor = scatterShapeHoleColor
-        copy.shapeRenderer = shapeRenderer
-        return copy
-    }
-}

+ 0 - 42
Pods/Charts/Source/Charts/Data/Interfaces/BarChartDataSetProtocol.swift

@@ -1,42 +0,0 @@
-//
-//  BarChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc
-public protocol BarChartDataSetProtocol: BarLineScatterCandleBubbleChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// `true` if this DataSet is stacked (stacksize > 1) or not.
-    var isStacked: Bool { get }
-    
-    /// The maximum number of bars that can be stacked upon another in this DataSet.
-    var stackSize: Int { get }
-    
-    /// the color used for drawing the bar-shadows. The bar shadows is a surface behind the bar that indicates the maximum value
-    var barShadowColor: NSUIColor { get set }
-    
-    /// the width used for drawing borders around the bars. If borderWidth == 0, no border will be drawn.
-    var barBorderWidth : CGFloat { get set }
-
-    /// the color drawing borders around the bars.
-    var barBorderColor: NSUIColor { get set }
-
-    /// the alpha value (transparency) that is used for drawing the highlight indicator bar. min = 0.0 (fully transparent), max = 1.0 (fully opaque)
-    var highlightAlpha: CGFloat { get set }
-    
-    /// array of labels used to describe the different values of the stacked bars
-    var stackLabels: [String] { get set }
-}

+ 0 - 26
Pods/Charts/Source/Charts/Data/Interfaces/BarLineScatterCandleBubbleChartDataSetProtocol.swift

@@ -1,26 +0,0 @@
-//
-//  BarLineScatterCandleBubbleChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc
-public protocol BarLineScatterCandleBubbleChartDataSetProtocol: ChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    var highlightColor: NSUIColor { get set }
-    var highlightLineWidth: CGFloat { get set }
-    var highlightLineDashPhase: CGFloat { get set }
-    var highlightLineDashLengths: [CGFloat]? { get set }
-}

+ 0 - 27
Pods/Charts/Source/Charts/Data/Interfaces/BubbleChartDataSetProtocol.swift

@@ -1,27 +0,0 @@
-//
-//  BubbleChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc
-public protocol BubbleChartDataSetProtocol: BarLineScatterCandleBubbleChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    var maxSize: CGFloat { get }
-    var isNormalizeSizeEnabled: Bool { get }
-    
-    // MARK: - Styling functions and accessors
-    
-    /// Sets/gets the width of the circle that surrounds the bubble when highlighted
-    var highlightCircleWidth: CGFloat { get set }
-}

+ 0 - 66
Pods/Charts/Source/Charts/Data/Interfaces/CandleChartDataSetProtocol.swift

@@ -1,66 +0,0 @@
-//
-//  CandleChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc
-public protocol CandleChartDataSetProtocol: LineScatterCandleRadarChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// the space that is left out on the left and right side of each candle,
-    /// **default**: 0.1 (10%), max 0.45, min 0.0
-    var barSpace: CGFloat { get set }
-    
-    /// should the candle bars show?
-    /// when false, only "ticks" will show
-    ///
-    /// **default**: true
-    var showCandleBar: Bool { get set }
-    
-    /// the width of the candle-shadow-line in pixels.
-    ///
-    /// **default**: 3.0
-    var shadowWidth: CGFloat { get set }
-    
-    /// the color of the shadow line
-    var shadowColor: NSUIColor? { get set }
-    
-    /// use candle color for the shadow
-    var shadowColorSameAsCandle: Bool { get set }
-    
-    /// Is the shadow color same as the candle color?
-    var isShadowColorSameAsCandle: Bool { get }
-    
-    /// color for open == close
-    var neutralColor: NSUIColor? { get set }
-    
-    /// color for open > close
-    var increasingColor: NSUIColor? { get set }
-    
-    /// color for open < close
-    var decreasingColor: NSUIColor? { get set }
-    
-    /// Are increasing values drawn as filled?
-    var increasingFilled: Bool { get set }
-    
-    /// Are increasing values drawn as filled?
-    var isIncreasingFilled: Bool { get }
-    
-    /// Are decreasing values drawn as filled?
-    var decreasingFilled: Bool { get set }
-    
-    /// Are decreasing values drawn as filled?
-    var isDecreasingFilled: Bool { get }
-}

+ 0 - 270
Pods/Charts/Source/Charts/Data/Interfaces/ChartDataSetProtocol.swift

@@ -1,270 +0,0 @@
-//
-//  ChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc
-public protocol ChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    /// Use this method to tell the data set that the underlying data has changed
-    func notifyDataSetChanged()
-    
-    /// Calculates the minimum and maximum x and y values (xMin, xMax, yMin, yMax).
-    func calcMinMax()
-    
-    /// Calculates the min and max y-values from the Entry closest to the given fromX to the Entry closest to the given toX value.
-    /// This is only needed for the autoScaleMinMax feature.
-    func calcMinMaxY(fromX: Double, toX: Double)
-    
-    /// The minimum y-value this DataSet holds
-    var yMin: Double { get }
-    
-    /// The maximum y-value this DataSet holds
-    var yMax: Double { get }
-    
-    /// The minimum x-value this DataSet holds
-    var xMin: Double { get }
-    
-    /// The maximum x-value this DataSet holds
-    var xMax: Double { get }
-    
-    /// The number of y-values this DataSet represents
-    var entryCount: Int { get }
-    
-    /// - Throws: out of bounds
-    /// if `i` is out of bounds, it may throw an out-of-bounds exception
-    /// - Returns: The entry object found at the given index (not x-value!)
-    func entryForIndex(_ i: Int) -> ChartDataEntry?
-    
-    /// - Parameters:
-    ///   - xValue: the x-value
-    ///   - closestToY: If there are multiple y-values for the specified x-value,
-    ///   - rounding: determine whether to round up/down/closest if there is no Entry matching the provided x-value
-    /// - Returns: The first Entry object found at the given x-value with binary search.
-    /// If the no Entry at the specified x-value is found, this method returns the Entry at the closest x-value according to the rounding.
-    /// nil if no Entry object at that x-value.
-    func entryForXValue(
-        _ xValue: Double,
-        closestToY yValue: Double,
-        rounding: ChartDataSetRounding) -> ChartDataEntry?
-    
-    /// - Parameters:
-    ///   - xValue: the x-value
-    ///   - closestToY: If there are multiple y-values for the specified x-value,
-    /// - Returns: The first Entry object found at the given x-value with binary search.
-    /// If the no Entry at the specified x-value is found, this method returns the Entry at the closest x-value.
-    /// nil if no Entry object at that x-value.
-    func entryForXValue(
-        _ xValue: Double,
-        closestToY yValue: Double) -> ChartDataEntry?
-    
-    /// - Returns: All Entry objects found at the given x-value with binary search.
-    /// An empty array if no Entry object at that x-value.
-    func entriesForXValue(_ xValue: Double) -> [ChartDataEntry]
-    
-    /// - Parameters:
-    ///   - xValue: x-value of the entry to search for
-    ///   - closestToY: If there are multiple y-values for the specified x-value,
-    ///   - rounding: Rounding method if exact value was not found
-    /// - Returns: The array-index of the specified entry.
-    /// If the no Entry at the specified x-value is found, this method returns the index of the Entry at the closest x-value according to the rounding.
-    func entryIndex(
-        x xValue: Double,
-        closestToY yValue: Double,
-        rounding: ChartDataSetRounding) -> Int
-    
-    /// - Parameters:
-    ///   - e: the entry to search for
-    /// - Returns: The array-index of the specified entry
-    func entryIndex(entry e: ChartDataEntry) -> Int
-    
-    /// Adds an Entry to the DataSet dynamically.
-    ///
-    /// *optional feature, can return `false` ifnot implemented*
-    ///
-    /// Entries are added to the end of the list.
-    ///
-    /// - Parameters:
-    ///   - e: the entry to add
-    /// - Returns: `true` if the entry was added successfully, `false` ifthis feature is not supported
-    func addEntry(_ e: ChartDataEntry) -> Bool
-    
-    /// Adds an Entry to the DataSet dynamically.
-    /// Entries are added to their appropriate index in the values array respective to their x-position.
-    /// This will also recalculate the current minimum and maximum values of the DataSet and the value-sum.
-    ///
-    /// *optional feature, can return `false` ifnot implemented*
-    ///
-    /// Entries are added to the end of the list.
-    ///
-    /// - Parameters:
-    ///   - e: the entry to add
-    /// - Returns: `true` if the entry was added successfully, `false` ifthis feature is not supported
-    func addEntryOrdered(_ e: ChartDataEntry) -> Bool
-    
-    /// Removes an Entry from the DataSet dynamically.
-    ///
-    /// *optional feature, can return `false` ifnot implemented*
-    ///
-    /// - Parameters:
-    ///   - entry: the entry to remove
-    /// - Returns: `true` if the entry was removed successfully, `false` ifthe entry does not exist or if this feature is not supported
-    func removeEntry(_ entry: ChartDataEntry) -> Bool
-    
-    /// Removes the Entry object at the given index in the values array from the DataSet.
-    ///
-    /// *optional feature, can return `false` ifnot implemented*
-    ///
-    /// - Parameters:
-    ///   - index: the index of the entry to remove
-    /// - Returns: `true` if the entry was removed successfully, `false` ifthe entry does not exist or if this feature is not supported
-    func removeEntry(index: Int) -> Bool
-    
-    /// Removes the Entry object closest to the given x-value from the DataSet.
-    ///
-    /// *optional feature, can return `false` ifnot implemented*
-    ///
-    /// - Parameters:
-    ///   - x: the x-value to remove
-    /// - Returns: `true` if the entry was removed successfully, `false` ifthe entry does not exist or if this feature is not supported
-    func removeEntry(x: Double) -> Bool
-    
-    /// Removes the first Entry (at index 0) of this DataSet from the entries array.
-    ///
-    /// *optional feature, can return `false` ifnot implemented*
-    ///
-    /// - Returns: `true` if the entry was removed successfully, `false` ifthe entry does not exist or if this feature is not supported
-    func removeFirst() -> Bool
-    
-    /// Removes the last Entry (at index 0) of this DataSet from the entries array.
-    ///
-    /// *optional feature, can return `false` ifnot implemented*
-    ///
-    /// - Returns: `true` if the entry was removed successfully, `false` ifthe entry does not exist or if this feature is not supported
-    func removeLast() -> Bool
-    
-    /// Checks if this DataSet contains the specified Entry.
-    ///
-    /// - Returns: `true` if contains the entry, `false` ifnot.
-    func contains(_ e: ChartDataEntry) -> Bool
-    
-    /// Removes all values from this DataSet and does all necessary recalculations.
-    ///
-    /// *optional feature, could throw if not implemented*
-    func clear()
-    
-    // MARK: - Styling functions and accessors
-    
-    /// The label string that describes the DataSet.
-    var label: String? { get }
-    
-    /// The axis this DataSet should be plotted against.
-    var axisDependency: YAxis.AxisDependency { get }
-    
-    /// List representing all colors that are used for drawing the actual values for this DataSet
-    var valueColors: [NSUIColor] { get }
-    
-    /// All the colors that are used for this DataSet.
-    /// Colors are reused as soon as the number of Entries the DataSet represents is higher than the size of the colors array.
-    var colors: [NSUIColor] { get }
-    
-    /// - Returns: The color at the given index of the DataSet's color array.
-    /// This prevents out-of-bounds by performing a modulus on the color index, so colours will repeat themselves.
-    func color(atIndex: Int) -> NSUIColor
-    
-    func resetColors()
-    
-    func addColor(_ color: NSUIColor)
-    
-    func setColor(_ color: NSUIColor)
-    
-    /// if true, value highlighting is enabled
-    var highlightEnabled: Bool { get set }
-    
-    /// `true` if value highlighting is enabled for this dataset
-    var isHighlightEnabled: Bool { get }
-    
-    /// Custom formatter that is used instead of the auto-formatter if set
-    var valueFormatter: ValueFormatter { get set }
-    
-    /// Sets/get a single color for value text.
-    /// Setting the color clears the colors array and adds a single color.
-    /// Getting will return the first color in the array.
-    var valueTextColor: NSUIColor { get set }
-    
-    /// - Returns: The color at the specified index that is used for drawing the values inside the chart. Uses modulus internally.
-    func valueTextColorAt(_ index: Int) -> NSUIColor
-    
-    /// the font for the value-text labels
-    var valueFont: NSUIFont { get set }
-    
-    /// The rotation angle (in degrees) for value-text labels
-    var valueLabelAngle: CGFloat { get set }
-    
-    /// The form to draw for this dataset in the legend.
-    ///
-    /// Return `.Default` to use the default legend form.
-    var form: Legend.Form { get }
-    
-    /// The form size to draw for this dataset in the legend.
-    ///
-    /// Return `NaN` to use the default legend form size.
-    var formSize: CGFloat { get }
-    
-    /// The line width for drawing the form of this dataset in the legend
-    ///
-    /// Return `NaN` to use the default legend form line width.
-    var formLineWidth: CGFloat { get }
-    
-    /// Line dash configuration for legend shapes that consist of lines.
-    ///
-    /// This is how much (in pixels) into the dash pattern are we starting from.
-    var formLineDashPhase: CGFloat { get }
-    
-    /// Line dash configuration for legend shapes that consist of lines.
-    ///
-    /// This is the actual dash pattern.
-    /// I.e. [2, 3] will paint [--   --   ]
-    /// [1, 3, 4, 2] will paint [-   ----  -   ----  ]
-    var formLineDashLengths: [CGFloat]? { get }
-    
-    /// Set this to true to draw y-values on the chart.
-    ///
-    /// - Note: For bar and line charts: if `maxVisibleCount` is reached, no values will be drawn even if this is enabled.
-    var drawValuesEnabled: Bool { get set }
-    
-    /// `true` if y-value drawing is enabled, `false` ifnot
-    var isDrawValuesEnabled: Bool { get }
-    
-    /// Set this to true to draw y-icons on the chart
-    ///
-    /// - Note: For bar and line charts: if `maxVisibleCount` is reached, no icons will be drawn even if this is enabled.
-    var drawIconsEnabled: Bool { get set }
-    
-    /// Returns true if y-icon drawing is enabled, false if not
-    var isDrawIconsEnabled: Bool { get }
-    
-    /// Offset of icons drawn on the chart.
-    ///
-    /// For all charts except Pie and Radar it will be ordinary (x offset, y offset).
-    ///
-    /// For Pie and Radar chart it will be (y offset, distance from center offset); so if you want icon to be rendered under value, you should increase X component of CGPoint, and if you want icon to be rendered closet to center, you should decrease height component of CGPoint.
-    var iconsOffset: CGPoint { get set }
-    
-    /// Set the visibility of this DataSet. If not visible, the DataSet will not be drawn to the chart upon refreshing it.
-    var visible: Bool { get set }
-    
-    /// `true` if this DataSet is visible inside the chart, or `false` ifit is currently hidden.
-    var isVisible: Bool { get }
-}

+ 0 - 86
Pods/Charts/Source/Charts/Data/Interfaces/LineChartDataSetProtocol.swift

@@ -1,86 +0,0 @@
-//
-//  LineChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-
-@objc
-public protocol LineChartDataSetProtocol: LineRadarChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// The drawing mode for this line dataset
-    ///
-    /// **default**: Linear
-    var mode: LineChartDataSet.Mode { get set }
-    
-    /// Intensity for cubic lines (min = 0.05, max = 1)
-    ///
-    /// **default**: 0.2
-    var cubicIntensity: CGFloat { get set }
-
-    /// If true, gradient lines are drawn instead of solid
-    var isDrawLineWithGradientEnabled: Bool { get set }
-
-    /// The points where gradient should change color
-    var gradientPositions: [CGFloat]? { get set }
-
-    /// The radius of the drawn circles.
-    var circleRadius: CGFloat { get set }
-    
-    /// The hole radius of the drawn circles.
-    var circleHoleRadius: CGFloat { get set }
-    
-    var circleColors: [NSUIColor] { get set }
-    
-    /// - Returns: The color at the given index of the DataSet's circle-color array.
-    /// Performs a IndexOutOfBounds check by modulus.
-    func getCircleColor(atIndex: Int) -> NSUIColor?
-    
-    /// Sets the one and ONLY color that should be used for this DataSet.
-    /// Internally, this recreates the colors array and adds the specified color.
-    func setCircleColor(_ color: NSUIColor)
-    
-    /// Resets the circle-colors array and creates a new one
-    func resetCircleColors(_ index: Int)
-    
-    /// If true, drawing circles is enabled
-    var drawCirclesEnabled: Bool { get set }
-    
-    /// `true` if drawing circles for this DataSet is enabled, `false` ifnot
-    var isDrawCirclesEnabled: Bool { get }
-    
-    /// The color of the inner circle (the circle-hole).
-    var circleHoleColor: NSUIColor? { get set }
-    
-    /// `true` if drawing circles for this DataSet is enabled, `false` ifnot
-    var drawCircleHoleEnabled: Bool { get set }
-    
-    /// `true` if drawing the circle-holes is enabled, `false` ifnot.
-    var isDrawCircleHoleEnabled: Bool { get }
-    
-    /// This is how much (in pixels) into the dash pattern are we starting from.
-    var lineDashPhase: CGFloat { get }
-    
-    /// This is the actual dash pattern.
-    /// I.e. [2, 3] will paint [--   --   ]
-    /// [1, 3, 4, 2] will paint [-   ----  -   ----  ]
-    var lineDashLengths: [CGFloat]? { get set }
-    
-    /// Line cap type, default is CGLineCap.Butt
-    var lineCapType: CGLineCap { get set }
-    
-    /// Sets a custom FillFormatterProtocol to the chart that handles the position of the filled-line for each DataSet. Set this to null to use the default logic.
-    var fillFormatter: FillFormatter? { get set }
-}

+ 0 - 45
Pods/Charts/Source/Charts/Data/Interfaces/LineRadarChartDataSetProtocol.swift

@@ -1,45 +0,0 @@
-//
-//  LineRadarChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc
-public protocol LineRadarChartDataSetProtocol: LineScatterCandleRadarChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// The color that is used for filling the line surface area.
-    var fillColor: NSUIColor { get set }
-
-    /// - Returns: The object that is used for filling the area below the line.
-    /// **default**: nil
-    var fill: Fill? { get set }
-    
-    /// The alpha value that is used for filling the line surface.
-    /// **default**: 0.33
-    var fillAlpha: CGFloat { get set }
-    
-    /// line width of the chart (min = 0.0, max = 10)
-    ///
-    /// **default**: 1
-    var lineWidth: CGFloat { get set }
-    
-    /// Set to `true` if the DataSet should be drawn filled (surface), and not just as a line.
-    /// Disabling this will give great performance boost.
-    /// Please note that this method uses the path clipping for drawing the filled area (with images, gradients and layers).
-    var drawFilledEnabled: Bool { get set }
-    
-    /// `true` if filled drawing is enabled, `false` if not
-    var isDrawFilledEnabled: Bool { get }
-}

+ 0 - 36
Pods/Charts/Source/Charts/Data/Interfaces/LineScatterCandleRadarChartDataSetProtocol.swift

@@ -1,36 +0,0 @@
-//
-//  LineScatterCandleRadarChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-@objc
-public protocol LineScatterCandleRadarChartDataSetProtocol: BarLineScatterCandleBubbleChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// Enables / disables the horizontal highlight-indicator. If disabled, the indicator is not drawn.
-    var drawHorizontalHighlightIndicatorEnabled: Bool { get set }
-    
-    /// Enables / disables the vertical highlight-indicator. If disabled, the indicator is not drawn.
-    var drawVerticalHighlightIndicatorEnabled: Bool { get set }
-    
-    /// `true` if horizontal highlight indicator lines are enabled (drawn)
-    var isHorizontalHighlightIndicatorEnabled: Bool { get }
-    
-    /// `true` if vertical highlight indicator lines are enabled (drawn)
-    var isVerticalHighlightIndicatorEnabled: Bool { get }
-    
-    /// Enables / disables both vertical and horizontal highlight-indicators.
-    /// :param: enabled
-    func setDrawHighlightIndicators(_ enabled: Bool)
-}

+ 0 - 64
Pods/Charts/Source/Charts/Data/Interfaces/PieChartDataSetProtocol.swift

@@ -1,64 +0,0 @@
-//
-//  PieChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc
-public protocol PieChartDataSetProtocol: ChartDataSetProtocol
-{
-    // MARK: - Styling functions and accessors
-
-    /// the space in pixels between the pie-slices
-    /// **default**: 0
-    /// **maximum**: 20
-    var sliceSpace: CGFloat { get set }
-
-    /// When enabled, slice spacing will be 0.0 when the smallest value is going to be smaller than the slice spacing itself.
-    var automaticallyDisableSliceSpacing: Bool { get set }
-
-    /// indicates the selection distance of a pie slice
-    var selectionShift: CGFloat { get set }
-
-    var xValuePosition: PieChartDataSet.ValuePosition { get set }
-    var yValuePosition: PieChartDataSet.ValuePosition { get set }
-
-    /// When valuePosition is OutsideSlice, indicates line color
-    var valueLineColor: NSUIColor? { get set }
-
-    /// When valuePosition is OutsideSlice and enabled, line will have the same color as the slice
-    var useValueColorForLine: Bool { get set }
-
-    /// When valuePosition is OutsideSlice, indicates line width
-    var valueLineWidth: CGFloat { get set }
-
-    /// When valuePosition is OutsideSlice, indicates offset as percentage out of the slice size
-    var valueLinePart1OffsetPercentage: CGFloat { get set }
-
-    /// When valuePosition is OutsideSlice, indicates length of first half of the line
-    var valueLinePart1Length: CGFloat { get set }
-
-    /// When valuePosition is OutsideSlice, indicates length of second half of the line
-    var valueLinePart2Length: CGFloat { get set }
-
-    /// When valuePosition is OutsideSlice, this allows variable line length
-    var valueLineVariableLength: Bool { get set }
-
-    /// the font for the slice-text labels
-    var entryLabelFont: NSUIFont? { get set }
-
-    /// the color for the slice-text labels
-    var entryLabelColor: NSUIColor? { get set }
-
-    /// get/sets the color for the highlighted sector
-    var highlightColor: NSUIColor? { get set }
-
-}

+ 0 - 40
Pods/Charts/Source/Charts/Data/Interfaces/RadarChartDataSetProtocol.swift

@@ -1,40 +0,0 @@
-//
-//  RadarChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc
-public protocol RadarChartDataSetProtocol: LineRadarChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// flag indicating whether highlight circle should be drawn or not
-    var drawHighlightCircleEnabled: Bool { get set }
-    
-    var isDrawHighlightCircleEnabled: Bool { get }
-    
-    var highlightCircleFillColor: NSUIColor? { get set }
-    
-    /// The stroke color for highlight circle.
-    /// If `nil`, the color of the dataset is taken.
-    var highlightCircleStrokeColor: NSUIColor? { get set }
-    
-    var highlightCircleStrokeAlpha: CGFloat { get set }
-    
-    var highlightCircleInnerRadius: CGFloat { get set }
-    
-    var highlightCircleOuterRadius: CGFloat { get set }
-    
-    var highlightCircleStrokeWidth: CGFloat { get set }
-}

+ 0 - 36
Pods/Charts/Source/Charts/Data/Interfaces/ScatterChartDataSetProtocol.swift

@@ -1,36 +0,0 @@
-//
-//  ScatterChartDataSetProtocol.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc
-public protocol ScatterChartDataSetProtocol: LineScatterCandleRadarChartDataSetProtocol
-{
-    // MARK: - Data functions and accessors
-    
-    // MARK: - Styling functions and accessors
-    
-    /// - Returns: The size the scatter shape will have
-    var scatterShapeSize: CGFloat { get }
-    
-    /// - Returns: The radius of the hole in the shape (applies to Square, Circle and Triangle)
-    /// Set this to <= 0 to remove holes.
-    /// **default**: 0.0
-    var scatterShapeHoleRadius: CGFloat { get }
-    
-    /// - Returns: Color for the hole in the shape. Setting to `nil` will behave as transparent.
-    /// **default**: nil
-    var scatterShapeHoleColor: NSUIColor? { get }
-    
-    /// - Returns: The ShapeRenderer responsible for rendering this DataSet.
-    var shapeRenderer: ShapeRenderer? { get }
-}

+ 0 - 153
Pods/Charts/Source/Charts/Filters/DataApproximator+N.swift

@@ -1,153 +0,0 @@
-//
-//  DataApproximator+N.swift
-//  Charts
-//
-//  Created by M Ivaniushchenko on 9/6/17.
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-extension CGPoint {
-    fileprivate func distanceToLine(from linePoint1: CGPoint, to linePoint2: CGPoint) -> CGFloat {
-        let dx = linePoint2.x - linePoint1.x
-        let dy = linePoint2.y - linePoint1.y
-        
-        let dividend = abs(dy * self.x - dx * self.y - linePoint1.x * linePoint2.y + linePoint2.x * linePoint1.y)
-        let divisor = sqrt(dx * dx + dy * dy)
-        
-        return dividend / divisor
-    }
-}
-
-private struct LineAlt {
-    let start: Int
-    let end: Int
-    
-    var distance: CGFloat = 0
-    var index: Int = 0
-    
-    init(start: Int, end: Int, points: [CGPoint]) {
-        self.start = start
-        self.end = end
-        
-        let startPoint = points[start]
-        let endPoint = points[end]
-        
-        guard (end > start + 1) else {
-            return
-        }
-        
-        for i in start + 1 ..< end {
-            let currentPoint = points[i]
-            
-            let distance = currentPoint.distanceToLine(from: startPoint, to: endPoint)
-            
-            if distance > self.distance {
-                self.index = i
-                self.distance = distance
-            }
-        }
-    }
-}
-
-extension LineAlt: Comparable {
-    static func ==(lhs: LineAlt, rhs: LineAlt) -> Bool {
-        return (lhs.start == rhs.start) && (lhs.end == rhs.end) && (lhs.index == rhs.index)
-    }
-    
-    static func <(lhs: LineAlt, rhs: LineAlt) -> Bool {
-        return lhs.distance < rhs.distance
-    }
-}
-
-
-extension DataApproximator {
-    /// uses the douglas peuker algorithm to reduce the given arraylist of entries to given number of points
-    /// More algorithm details here - http://psimpl.sourceforge.net/douglas-peucker.html
-    @objc open class func reduceWithDouglasPeukerN(_ points: [CGPoint], resultCount: Int) -> [CGPoint]
-    {
-        // if a shape has 2 or less points it cannot be reduced
-        if resultCount <= 2 || resultCount >= points.count
-        {
-            return points
-        }
-        var keep = [Bool](repeating: false, count: points.count)
-        
-        // first and last always stay
-        keep[points.startIndex] = true
-        keep[points.endIndex - 1] = true
-        var currentStoredPoints = 2
-        
-        var queue = [LineAlt]()
-        let line = LineAlt(start: points.startIndex, end: points.endIndex - 1, points: points)
-        queue.append(line)
-        
-        repeat {
-            let line = queue.popLast()!
-            
-            // store the key
-            keep[line.index] = true
-            
-            // check point count tolerance
-            currentStoredPoints += 1
-            
-            if (currentStoredPoints == resultCount) {
-                break;
-            }
-            
-            // split the polyline at the key and recurse
-            let left = LineAlt(start: line.start, end: line.index, points: points)
-            if (left.index > 0) {
-                self.insertLine(left, into: &queue)
-            }
-            
-            let right = LineAlt(start: line.index, end: line.end, points: points)
-            if (right.index > 0) {
-                self.insertLine(right, into: &queue)
-            }
-            
-        } while !queue.isEmpty
-        
-        // create a new array with series, only take the kept ones
-        let reducedEntries = points.enumerated().compactMap { (index: Int, point: CGPoint) -> CGPoint? in
-            return keep[index] ? point : nil
-        }
-        
-        return reducedEntries
-    }
-    
-    // Keeps array sorted
-    private static func insertLine(_ line: LineAlt, into array: inout [LineAlt]) {
-        let insertionIndex = self.insertionIndex(for: line, into: &array)
-        array.insert(line, at: insertionIndex)
-    }
-    
-    private static func insertionIndex(for line: LineAlt, into array: inout [LineAlt]) -> Int {
-        var indices = array.indices
-        
-        while !indices.isEmpty {
-            let midIndex = indices.lowerBound.advanced(by: indices.count / 2)
-            let midLine = array[midIndex]
-            
-            if midLine == line {
-                return midIndex
-            }
-            else if (line < midLine) {
-                // perform search in left half
-                indices = indices.lowerBound..<midIndex
-            }
-            else {
-                // perform search in right half
-                indices = (midIndex + 1)..<indices.upperBound
-            }
-        }
-        
-        return indices.lowerBound
-    }
-}
-
-

+ 0 - 115
Pods/Charts/Source/Charts/Filters/DataApproximator.swift

@@ -1,115 +0,0 @@
-//
-//  DataApproximator.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-@objc(ChartDataApproximator)
-open class DataApproximator: NSObject
-{
-    /// uses the douglas peuker algorithm to reduce the given arraylist of entries
-    @objc open class func reduceWithDouglasPeuker(_ points: [CGPoint], tolerance: CGFloat) -> [CGPoint]
-    {
-        // if a shape has 2 or less points it cannot be reduced
-        if tolerance <= 0 || points.count < 3
-        {
-            return points
-        }
-        
-        var keep = [Bool](repeating: false, count: points.count)
-        
-        // first and last always stay
-        keep[points.startIndex] = true
-        keep[points.endIndex - 1] = true
-        
-        // first and last entry are entry point to recursion
-        reduceWithDouglasPeuker(points: points,
-                                tolerance: tolerance,
-                                start: points.startIndex,
-                                end: points.endIndex - 1,
-                                keep: &keep)
-        
-        // create a new array with series, only take the kept ones
-        return zip(keep, points).compactMap { $0 ? nil : $1 }
-    }
-
-    /// apply the Douglas-Peucker-Reduction to an array of `CGPoint`s with a given tolerance
-    ///
-    /// - Parameters:
-    ///   - points:
-    ///   - tolerance:
-    ///   - start:
-    ///   - end:
-    open class func reduceWithDouglasPeuker(
-        points: [CGPoint],
-        tolerance: CGFloat,
-        start: Int,
-        end: Int,
-        keep: inout [Bool])
-    {
-        if end <= start + 1
-        {
-            // recursion finished
-            return
-        }
-        
-        var greatestIndex = Int(0)
-        var greatestDistance = CGFloat(0.0)
-        
-        let line = Line(pt1: points[start], pt2: points[end])
-        
-        for i in start + 1 ..< end
-        {
-            let distance = line.distance(toPoint: points[i])
-            
-            if distance > greatestDistance
-            {
-                greatestDistance = distance
-                greatestIndex = i
-            }
-        }
-        
-        if greatestDistance > tolerance
-        {
-            // keep max dist point
-            keep[greatestIndex] = true
-            
-            // recursive call
-            reduceWithDouglasPeuker(points: points, tolerance: tolerance, start: start, end: greatestIndex, keep: &keep)
-            reduceWithDouglasPeuker(points: points, tolerance: tolerance, start: greatestIndex, end: end, keep: &keep)
-        } // else don't keep the point...
-    }
-    
-    private class Line
-    {
-        var sxey: CGFloat
-        var exsy: CGFloat
-        
-        var dx: CGFloat
-        var dy: CGFloat
-        
-        var length: CGFloat
-        
-        init(pt1: CGPoint, pt2: CGPoint)
-        {
-            dx = pt1.x - pt2.x
-            dy = pt1.y - pt2.y
-            sxey = pt1.x * pt2.y
-            exsy = pt2.x * pt1.y
-            length = sqrt(dx * dx + dy * dy)
-        }
-        
-        func distance(toPoint pt: CGPoint) -> CGFloat
-        {
-            return abs(dy * pt.x - dx * pt.y + sxey - exsy) / length
-        }
-    }
-}

+ 0 - 30
Pods/Charts/Source/Charts/Formatters/AxisValueFormatter.swift

@@ -1,30 +0,0 @@
-//
-//  AxisValueFormatter.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-/// An interface for providing custom axis Strings.
-@objc(ChartAxisValueFormatter)
-public protocol AxisValueFormatter: AnyObject
-{
-    
-    /// Called when a value from an axis is formatted before being drawn.
-    ///
-    /// For performance reasons, avoid excessive calculations and memory allocations inside this method.
-    ///
-    /// - Parameters:
-    ///   - value:           the value that is currently being drawn
-    ///   - axis:            the axis that the value belongs to
-    /// - Returns: The customized label that is drawn on the x-axis.
-    func stringForValue(_ value: Double,
-                        axis: AxisBase?) -> String
-    
-}

+ 0 - 100
Pods/Charts/Source/Charts/Formatters/DefaultAxisValueFormatter.swift

@@ -1,100 +0,0 @@
-//
-//  DefaultAxisValueFormatter.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-@objc(ChartDefaultAxisValueFormatter)
-open class DefaultAxisValueFormatter: NSObject, AxisValueFormatter
-{
-    public typealias Block = (
-        _ value: Double,
-        _ axis: AxisBase?) -> String
-    
-    @objc open var block: Block?
-    
-    @objc open var hasAutoDecimals: Bool = false
-    
-    private var _formatter: NumberFormatter?
-    @objc open var formatter: NumberFormatter?
-    {
-        get { return _formatter }
-        set
-        {
-            hasAutoDecimals = false
-            _formatter = newValue
-        }
-    }
-
-    // TODO: Documentation. Especially the nil case
-    private var _decimals: Int?
-    open var decimals: Int?
-    {
-        get { return _decimals }
-        set
-        {
-            _decimals = newValue
-            
-            if let digits = newValue
-            {
-                self.formatter?.minimumFractionDigits = digits
-                self.formatter?.maximumFractionDigits = digits
-                self.formatter?.usesGroupingSeparator = true
-            }
-        }
-    }
-    
-    public override init()
-    {
-        super.init()
-        
-        self.formatter = NumberFormatter()
-        hasAutoDecimals = true
-    }
-    
-    @objc public init(formatter: NumberFormatter)
-    {
-        super.init()
-        
-        self.formatter = formatter
-    }
-    
-    @objc public init(decimals: Int)
-    {
-        super.init()
-        
-        self.formatter = NumberFormatter()
-        self.formatter?.usesGroupingSeparator = true
-        self.decimals = decimals
-        hasAutoDecimals = true
-    }
-    
-    @objc public init(block: @escaping Block)
-    {
-        super.init()
-        
-        self.block = block
-    }
-    
-    @objc public static func with(block: @escaping Block) -> DefaultAxisValueFormatter?
-    {
-        return DefaultAxisValueFormatter(block: block)
-    }
-    
-    open func stringForValue(_ value: Double,
-                               axis: AxisBase?) -> String
-    {
-        if let block = block {
-            return block(value, axis)
-        } else {
-            return formatter?.string(from: NSNumber(floatLiteral: value)) ?? ""
-        }
-    }
-}

+ 0 - 58
Pods/Charts/Source/Charts/Formatters/DefaultFillFormatter.swift

@@ -1,58 +0,0 @@
-//
-//  DefaultFillFormatter.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-import CoreGraphics
-
-/// Default formatter that calculates the position of the filled line.
-@objc(ChartDefaultFillFormatter)
-open class DefaultFillFormatter: NSObject, FillFormatter
-{
-    public typealias Block = (
-        _ dataSet: LineChartDataSetProtocol,
-        _ dataProvider: LineChartDataProvider) -> CGFloat
-    
-    @objc open var block: Block?
-    
-    public override init() { }
-    
-    @objc public init(block: @escaping Block)
-    {
-        self.block = block
-    }
-    
-    @objc public static func with(block: @escaping Block) -> DefaultFillFormatter?
-    {
-        return DefaultFillFormatter(block: block)
-    }
-    
-    open func getFillLinePosition(
-        dataSet: LineChartDataSetProtocol,
-        dataProvider: LineChartDataProvider) -> CGFloat
-    {
-        guard block == nil else { return block!(dataSet, dataProvider) }
-        var fillMin: CGFloat = 0.0
-
-        if dataSet.yMax > 0.0 && dataSet.yMin < 0.0
-        {
-            fillMin = 0.0
-        }
-        else if let data = dataProvider.data
-        {
-            let max = data.yMax > 0.0 ? 0.0 : dataProvider.chartYMax
-            let min = data.yMin < 0.0 ? 0.0 : dataProvider.chartYMin
-
-            fillMin = CGFloat(dataSet.yMin >= 0.0 ? min : max)
-        }
-
-        return fillMin
-    }
-}

+ 0 - 111
Pods/Charts/Source/Charts/Formatters/DefaultValueFormatter.swift

@@ -1,111 +0,0 @@
-//
-//  DefaultValueFormatter.swift
-//  Charts
-//
-//  Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
-//  A port of MPAndroidChart for iOS
-//  Licensed under Apache License 2.0
-//
-//  https://github.com/danielgindi/Charts
-//
-
-import Foundation
-
-/// The default value formatter used for all chart components that needs a default
-@objc(ChartDefaultValueFormatter)
-open class DefaultValueFormatter: NSObject, ValueFormatter
-{
-    public typealias Block = (
-        _ value: Double,
-        _ entry: ChartDataEntry,
-        _ dataSetIndex: Int,
-        _ viewPortHandler: ViewPortHandler?) -> String
-    
-    @objc open var block: Block?
-    
-    @objc open var hasAutoDecimals: Bool
-    
-    @objc open var formatter: NumberFormatter?
-    {
-        willSet
-        {
-            hasAutoDecimals = false
-        }
-    }
-    
-    open var decimals: Int?
-    {
-        didSet
-        {
-            setupDecimals(decimals: decimals)
-        }
-    }
-
-    private func setupDecimals(decimals: Int?)
-    {
-        if let digits = decimals
-        {
-            formatter?.minimumFractionDigits = digits
-            formatter?.maximumFractionDigits = digits
-            formatter?.usesGroupingSeparator = true
-        }
-    }
-    
-    public override init()
-    {
-        formatter = NumberFormatter()
-        formatter?.usesGroupingSeparator = true
-        decimals = 1
-        hasAutoDecimals = true
-
-        super.init()
-        setupDecimals(decimals: decimals)
-    }
-    
-    @objc public init(formatter: NumberFormatter)
-    {
-        self.formatter = formatter
-        hasAutoDecimals = false
-
-        super.init()
-    }
-    
-    @objc public init(decimals: Int)
-    {
-        formatter = NumberFormatter()
-        formatter?.usesGroupingSeparator = true
-        self.decimals = decimals
-        hasAutoDecimals = true
-
-        super.init()
-        setupDecimals(decimals: decimals)
-    }
-    
-    @objc public init(block: @escaping Block)
-    {
-        self.block = block
-        hasAutoDecimals = false
-
-        super.init()
-    }
-
-    /// This function is deprecated - Use `init(block:)` instead.
-    // DEC 11, 2017
-    @available(*, deprecated, message: "Use `init(block:)` instead.")
-    @objc public static func with(block: @escaping Block) -> DefaultValueFormatter
-    {
-        return DefaultValueFormatter(block: block)
-    }
-    
-    open func stringForValue(_ value: Double,
-                             entry: ChartDataEntry,
-                             dataSetIndex: Int,
-                             viewPortHandler: ViewPortHandler?) -> String
-    {
-        if let block = block {
-            return block(value, entry, dataSetIndex, viewPortHandler)
-        } else {
-            return formatter?.string(from: NSNumber(floatLiteral: value)) ?? ""
-        }
-    }
-}

+ 0 - 0
Pods/Charts/Source/Charts/Formatters/FillFormatter.swift


Некоторые файлы не были показаны из-за большого количества измененных файлов