-
-
Notifications
You must be signed in to change notification settings - Fork 6k
/
Copy pathChartYAxis.swift
244 lines (195 loc) · 7.35 KB
/
ChartYAxis.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
//
// ChartYAxis.swift
// Charts
//
// Created by Daniel Cohen Gindi on 23/2/15.
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/ios-charts
//
import Foundation
import UIKit
/// 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.
public class ChartYAxis: ChartAxisBase
{
@objc
public enum YAxisLabelPosition: 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
}
public var entries = [Double]()
public var entryCount: Int { return entries.count; }
/// the number of y-label entries the y-labels should have, default 6
private var _labelCount = Int(6)
/// indicates if the top y-label entry is drawn or not
public var drawTopYLabelEntryEnabled = true
/// if true, the y-labels show only the minimum and maximum value
public var showOnlyMinMaxEnabled = false
/// flag that indicates if the axis is inverted or not
public var inverted = false
/// if true, the y-label entries will always start at zero
public var startAtZeroEnabled = true
/// if true, the set number of y-labels will be forced
public var forceLabelsEnabled = true
/// the formatter used to customly format the y-labels
public var valueFormatter: NSNumberFormatter?
/// the formatter used to customly format the y-labels
internal var _defaultValueFormatter = NSNumberFormatter()
/// A custom minimum value for this axis.
/// If set, this value will not be calculated automatically depending on the provided data.
/// Use resetCustomAxisMin() to undo this.
/// Do not forget to set startAtZeroEnabled = false if you use this method.
/// Otherwise, the axis-minimum value will still be forced to 0.
public var customAxisMin = Double.NaN
/// Set a custom maximum value for this axis.
/// If set, this value will not be calculated automatically depending on the provided data.
/// Use resetCustomAxisMax() to undo this.
public var customAxisMax = Double.NaN
/// axis space from the largest value to the top in percent of the total axis range
public var spaceTop = CGFloat(0.1)
/// axis space from the smallest value to the bottom in percent of the total axis range
public var spaceBottom = CGFloat(0.1)
public var axisMaximum = Double(0)
public var axisMinimum = Double(0)
/// the total range of values this axis covers
public var axisRange = Double(0)
/// the position of the y-labels relative to the chart
public var labelPosition = YAxisLabelPosition.OutsideChart
/// the side this axis object represents
private var _axisDependency = AxisDependency.Left
/// the minimum width that the axis should take
/// :default 0.0
public var minWidth = CGFloat(0)
/// the maximum width that the axis can take.
/// use zero for disabling the maximum
/// :default 0.0 (no maximum specified)
public var maxWidth = CGFloat(0)
public override init()
{
super.init()
_defaultValueFormatter.minimumIntegerDigits = 1
_defaultValueFormatter.maximumFractionDigits = 1
_defaultValueFormatter.minimumFractionDigits = 1
_defaultValueFormatter.usesGroupingSeparator = true
self.yOffset = 0.0
}
public init(position: AxisDependency)
{
super.init()
_axisDependency = position
_defaultValueFormatter.minimumIntegerDigits = 1
_defaultValueFormatter.maximumFractionDigits = 1
_defaultValueFormatter.minimumFractionDigits = 1
_defaultValueFormatter.usesGroupingSeparator = true
self.yOffset = 0.0
}
public var axisDependency: AxisDependency
{
return _axisDependency
}
public func setLabelCount(count: Int, force: Bool)
{
_labelCount = count
if (_labelCount > 25)
{
_labelCount = 25
}
if (_labelCount < 2)
{
_labelCount = 2
}
forceLabelsEnabled = force
}
/// the number of label entries the y-axis should have
/// max = 25,
/// min = 2,
/// default = 6,
/// be aware that this number is not fixed and can only be approximated
public var labelCount: Int
{
get
{
return _labelCount
}
set
{
setLabelCount(newValue, force: false);
}
}
/// By calling this method, any custom minimum value that has been previously set is reseted, and the calculation is done automatically.
public func resetCustomAxisMin()
{
customAxisMin = Double.NaN
}
/// By calling this method, any custom maximum value that has been previously set is reseted, and the calculation is done automatically.
public func resetCustomAxisMax()
{
customAxisMax = Double.NaN
}
public func requiredSize() -> CGSize
{
var label = getLongestLabel() as NSString
var size = label.sizeWithAttributes([NSFontAttributeName: 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
}
public func getRequiredHeightSpace() -> CGFloat
{
return requiredSize().height + 2.5 * 2.0 + yOffset
}
public override func getLongestLabel() -> String
{
var longest = ""
for (var i = 0; i < entries.count; i++)
{
var text = getFormattedLabel(i)
if (count(longest) < count(text))
{
longest = text
}
}
return longest
}
/// Returns the formatted y-label at the specified index. This will either use the auto-formatter or the custom formatter (if one is set).
public func getFormattedLabel(index: Int) -> String
{
if (index < 0 || index >= entries.count)
{
return ""
}
return (valueFormatter ?? _defaultValueFormatter).stringFromNumber(entries[index])!
}
/// Returns true if this axis needs horizontal offset, false if no offset is needed.
public var needsOffset: Bool
{
if (isEnabled && isDrawLabelsEnabled && labelPosition == .OutsideChart)
{
return true
}
else
{
return false
}
}
public var isInverted: Bool { return inverted; }
public var isStartAtZeroEnabled: Bool { return startAtZeroEnabled; }
/// :returns: true if focing the y-label count is enabled. Default: false
public var isForceLabelsEnabled: Bool { return forceLabelsEnabled }
public var isShowOnlyMinMaxEnabled: Bool { return showOnlyMinMaxEnabled; }
public var isDrawTopYLabelEntryEnabled: Bool { return drawTopYLabelEntryEnabled; }
}