@@ -5,17 +5,36 @@ import Numerics
55/// A collection of linear scales.
66public enum LinearScale {
77 /// A linear scale is created using a continuous input of type double converting to an output of type float.
8- public struct DoubleScale : Scale {
8+ public struct DoubleScale : TickScale {
9+ /// The type used for the scale's domain.
910 public typealias InputType = Double
11+ /// The type used for the scale's range.
1012 public typealias OutputType = Float
1113
12- public let domainLower : Double
13- public let domainHigher : Double
14- public let domainExtent : Double
15-
14+ /// The lower bound of the input domain.
15+ public let domainLower : InputType
16+ /// The upper bound of the input domain.
17+ public let domainHigher : InputType
18+ /// The distance or length between the upper and lower bounds of the input domain.
19+ public let domainExtent : InputType
20+
21+ /// A boolean value that indicates whether the output vales are constrained to the min and max of the output range.
22+ ///
23+ /// If `true`, values processed by the scale are constrained to the output range, and values processed backwards through the scale
24+ /// are constrained to the input domain.
1625 public var transformType : DomainDataTransform
26+
27+ /// The number of ticks desired when creating the scale.
28+ ///
29+ /// This number may not match the number of ticks returned by ``TickScale/ticks(_:from:to:)``
1730 public let desiredTicks : Int
1831
32+ /// Creates a new linear scale for the upper and lower bounds of the domain you provide.
33+ /// - Parameters:
34+ /// - lower: The lower bound of the scale's domain.
35+ /// - higher: The upper bound of the scale's domain.
36+ /// - transform: The transform constraint to apply when values fall outside the domain of the scale.
37+ /// - desiredTicks: The desired number of ticks when visually representing the scale.
1938 public init ( from lower: InputType , to higher: InputType , transform: DomainDataTransform = . none, desiredTicks: Int = 10 ) {
2039 precondition ( lower < higher)
2140 transformType = transform
@@ -27,6 +46,12 @@ public enum LinearScale {
2746
2847 // MARK: - Double
2948
49+ /// Transforms the input value using a linear function to the resulting value into the range you provide.
50+ ///
51+ /// - Parameter domainValue: A value in the domain of the scale.
52+ /// - Parameter lower: The lower bound to the range to map to.
53+ /// - Parameter higher: The upper bound of the range to map to.
54+ /// - Returns: A value mapped to the range you provide.
3055 public func scale( _ domainValue: Double , from lower: Float , to higher: Float ) -> Float ? {
3156 if let domainValue = transformAgainstDomain ( domainValue) {
3257 let normalizedInput = normalize ( domainValue, lower: domainLower, higher: domainHigher)
@@ -36,6 +61,12 @@ public enum LinearScale {
3661 return nil
3762 }
3863
64+ /// Transforms a value within the range into the associated domain value.
65+ /// - Parameters:
66+ /// - rangeValue: A value in the range of the scale.
67+ /// - lower: The lower bound to the range to map from.
68+ /// - higher: The upper bound to the range to map from.
69+ /// - Returns: A value linearly mapped from the range back into the domain.
3970 public func invert( _ rangeValue: Float , from lower: Float , to higher: Float ) -> Double ? {
4071 // inverts the scale, taking a value in the output range and returning the relevant value from the input domain
4172 let normalizedRangeValue = normalize ( Double ( rangeValue) , lower: Double ( lower) , higher: Double ( higher) )
@@ -45,17 +76,36 @@ public enum LinearScale {
4576 }
4677
4778 /// A linear scale is created using a continuous input of type float converting to an output of type float.
48- public struct FloatScale : Scale {
79+ public struct FloatScale : TickScale {
80+ /// The type used for the scale's domain.
4981 public typealias InputType = Float
82+ /// The type used for the scale's range.
5083 public typealias OutputType = Float
5184
52- public let domainLower : Float
53- public let domainHigher : Float
54- public let domainExtent : Float
55-
85+ /// The lower bound of the input domain.
86+ public let domainLower : InputType
87+ /// The upper bound of the input domain.
88+ public let domainHigher : InputType
89+ /// The distance or length between the upper and lower bounds of the input domain.
90+ public let domainExtent : InputType
91+
92+ /// A boolean value that indicates whether the output vales are constrained to the min and max of the output range.
93+ ///
94+ /// If `true`, values processed by the scale are constrained to the output range, and values processed backwards through the scale
95+ /// are constrained to the input domain.
5696 public var transformType : DomainDataTransform
97+
98+ /// The number of ticks desired when creating the scale.
99+ ///
100+ /// This number may not match the number of ticks returned by ``TickScale/ticks(_:from:to:)``
57101 public let desiredTicks : Int
58102
103+ /// Creates a new linear scale for the upper and lower bounds of the domain you provide.
104+ /// - Parameters:
105+ /// - lower: The lower bound of the scale's domain.
106+ /// - higher: The upper bound of the scale's domain.
107+ /// - transform: The transform constraint to apply when values fall outside the domain of the scale.
108+ /// - desiredTicks: The desired number of ticks when visually representing the scale.
59109 public init ( from lower: InputType , to higher: InputType , transform: DomainDataTransform = . none, desiredTicks: Int = 10 ) {
60110 precondition ( lower < higher)
61111 transformType = transform
@@ -67,6 +117,12 @@ public enum LinearScale {
67117
68118 // MARK: - Float
69119
120+ /// Transforms the input value using a linear function to the resulting value into the range you provide.
121+ ///
122+ /// - Parameter domainValue: A value in the domain of the scale.
123+ /// - Parameter lower: The lower bound to the range to map to.
124+ /// - Parameter higher: The upper bound of the range to map to.
125+ /// - Returns: A value mapped to the range you provide.
70126 public func scale( _ domainValue: Float , from lower: Float , to higher: Float ) -> Float ? {
71127 if let domainValue = transformAgainstDomain ( domainValue) {
72128 let normalizedInput = normalize ( domainValue, lower: domainLower, higher: domainHigher)
@@ -76,6 +132,12 @@ public enum LinearScale {
76132 return nil
77133 }
78134
135+ /// Transforms a value within the range into the associated domain value.
136+ /// - Parameters:
137+ /// - rangeValue: A value in the range of the scale.
138+ /// - lower: The lower bound to the range to map from.
139+ /// - higher: The upper bound to the range to map from.
140+ /// - Returns: A value linearly mapped from the range back into the domain.
79141 public func invert( _ rangeValue: Float , from lower: Float , to higher: Float ) -> Float ? {
80142 // inverts the scale, taking a value in the output range and returning the relevant value from the input domain
81143 let normalizedRangeValue = normalize ( rangeValue, lower: lower, higher: higher)
@@ -85,17 +147,36 @@ public enum LinearScale {
85147 }
86148
87149 /// A linear scale is created using a continuous input of type int converting to an output of type float.
88- public struct IntScale : Scale {
150+ public struct IntScale : TickScale {
151+ /// The type used for the scale's domain.
89152 public typealias InputType = Int
153+ /// The type used for the scale's range.
90154 public typealias OutputType = Float
91155
92- public let domainLower : Int
93- public let domainHigher : Int
94- public let domainExtent : Int
95-
156+ /// The lower bound of the input domain.
157+ public let domainLower : InputType
158+ /// The upper bound of the input domain.
159+ public let domainHigher : InputType
160+ /// The distance or length between the upper and lower bounds of the input domain.
161+ public let domainExtent : InputType
162+
163+ /// A boolean value that indicates whether the output vales are constrained to the min and max of the output range.
164+ ///
165+ /// If `true`, values processed by the scale are constrained to the output range, and values processed backwards through the scale
166+ /// are constrained to the input domain.
96167 public var transformType : DomainDataTransform
168+
169+ /// The number of ticks desired when creating the scale.
170+ ///
171+ /// This number may not match the number of ticks returned by ``TickScale/ticks(_:from:to:)``
97172 public let desiredTicks : Int
98173
174+ /// Creates a new linear scale for the upper and lower bounds of the domain you provide.
175+ /// - Parameters:
176+ /// - lower: The lower bound of the scale's domain.
177+ /// - higher: The upper bound of the scale's domain.
178+ /// - transform: The transform constraint to apply when values fall outside the domain of the scale.
179+ /// - desiredTicks: The desired number of ticks when visually representing the scale.
99180 public init ( from lower: InputType , to higher: InputType , transform: DomainDataTransform = . none, desiredTicks: Int = 10 ) {
100181 precondition ( lower < higher)
101182 transformType = transform
@@ -107,6 +188,12 @@ public enum LinearScale {
107188
108189 // MARK: - Int
109190
191+ /// Transforms the input value using a linear function to the resulting value into the range you provide.
192+ ///
193+ /// - Parameter domainValue: A value in the domain of the scale.
194+ /// - Parameter lower: The lower bound to the range to map to.
195+ /// - Parameter higher: The upper bound of the range to map to.
196+ /// - Returns: A value mapped to the range you provide.
110197 public func scale( _ domainValue: Int , from lower: Float , to higher: Float ) -> Float ? {
111198 if let domainValue = transformAgainstDomain ( domainValue) {
112199 let convertedDomain = Float ( domainValue)
@@ -119,18 +206,24 @@ public enum LinearScale {
119206 return nil
120207 }
121208
209+ /// Transforms a value within the range into the associated domain value.
210+ /// - Parameters:
211+ /// - rangeValue: A value in the range of the scale.
212+ /// - lower: The lower bound to the range to map from.
213+ /// - higher: The upper bound to the range to map from.
214+ /// - Returns: A value linearly mapped from the range back into the domain.
122215 public func invert( _ rangeValue: Float , from lower: Float , to higher: Float ) -> Int ? {
123216 // inverts the scale, taking a value in the output range and returning the relevant value from the input domain
124217 let normalizedRangeValue = normalize ( Double ( rangeValue) , lower: Double ( lower) , higher: Double ( higher) )
125218 let mappedToDomain = interpolate ( normalizedRangeValue, lower: Double ( domainLower) , higher: Double ( domainHigher) )
126219 return transformAgainstDomain ( Int ( mappedToDomain) )
127220 }
128221 }
129-
222+
130223 // MARK: - Factory (convenience) Methods
131-
224+
132225 // Double
133-
226+
134227 /// Creates a linear scale that maps values between the lower and upper bounds you provide.
135228 /// - Parameters:
136229 /// - low: The lower bounds of the domain.
@@ -144,21 +237,21 @@ public enum LinearScale {
144237 public static func create( _ range: ClosedRange < Double > ) -> LinearScale . DoubleScale {
145238 LinearScale . DoubleScale ( from: range. lowerBound, to: range. upperBound)
146239 }
147-
240+
148241 /// Creates a linear scale that maps values from 0 to the upper bound you provide.
149242 /// - Parameter high: The upper bounds of the domain.
150243 public static func create( _ high: Double ) -> LinearScale . DoubleScale {
151244 LinearScale . DoubleScale ( from: 0 , to: high)
152245 }
153-
246+
154247 /// Creates a linear scale for dates that maps values between the lower and upper bounds you provide.
155248 /// - Parameters:
156249 /// - low: The lower bounds of the domain.
157250 /// - high: The upper bounds of the domain.
158251 public static func create( _ low: Date , _ high: Date ) -> LinearScale . DoubleScale {
159252 LinearScale . DoubleScale ( from: low. timeIntervalSince1970, to: high. timeIntervalSince1970)
160253 }
161-
254+
162255 /// Creates a linear scale for dates that maps values within the range you provide.
163256 /// - Parameter range: The range of the domain.
164257 public static func create( _ range: ClosedRange < Date > ) -> LinearScale . DoubleScale {
@@ -208,6 +301,4 @@ public enum LinearScale {
208301 public static func create( _ range: ClosedRange < Int > ) -> LinearScale . IntScale {
209302 LinearScale . IntScale ( from: range. lowerBound, to: range. upperBound)
210303 }
211-
212-
213304}
0 commit comments