| OLD | NEW |
| 1 // | 1 // |
| 2 // Copyright 2014 Google Inc. All rights reserved. | 2 // Copyright 2014 Google Inc. All rights reserved. |
| 3 // | 3 // |
| 4 // Use of this source code is governed by a BSD-style | 4 // Use of this source code is governed by a BSD-style |
| 5 // license that can be found in the LICENSE file or at | 5 // license that can be found in the LICENSE file or at |
| 6 // https://developers.google.com/open-source/licenses/bsd | 6 // https://developers.google.com/open-source/licenses/bsd |
| 7 // | 7 // |
| 8 | 8 |
| 9 /// Collection of scales for use by charts. The role of scales is to map the | 9 /// Collection of scales for use by charts. The role of scales is to map the |
| 10 /// input domain to an output range. | 10 /// input domain to an output range. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 /// Maps each value on the domain to a band in the output range. When a | 99 /// Maps each value on the domain to a band in the output range. When a |
| 100 /// non-zero value is specified, [padding] space is left between each bands | 100 /// non-zero value is specified, [padding] space is left between each bands |
| 101 /// and [outerPadding] space is left unused at both ends of the range. | 101 /// and [outerPadding] space is left unused at both ends of the range. |
| 102 void rangeBands(Iterable range, [double padding, double outerPadding]); | 102 void rangeBands(Iterable range, [double padding, double outerPadding]); |
| 103 | 103 |
| 104 /// Similar to [rangeBands] but ensures that each band starts and ends on a | 104 /// Similar to [rangeBands] but ensures that each band starts and ends on a |
| 105 /// pixel boundary - helps avoid anti-aliasing artifacts. | 105 /// pixel boundary - helps avoid anti-aliasing artifacts. |
| 106 void rangeRoundBands(Iterable range, [double padding, double outerPadding]); | 106 void rangeRoundBands(Iterable range, [double padding, double outerPadding]); |
| 107 } | 107 } |
| 108 | 108 |
| 109 class RoundingFunctions extends Pair<RoundFunction,RoundFunction> { | 109 class RoundingFunctions extends Pair<RoundFunction, RoundFunction> { |
| 110 RoundingFunctions(RoundFunction floor, RoundFunction ceil) | 110 RoundingFunctions(RoundFunction floor, RoundFunction ceil) |
| 111 : super(floor, ceil); | 111 : super(floor, ceil); |
| 112 | 112 |
| 113 factory RoundingFunctions.defaults() => | 113 factory RoundingFunctions.defaults() => |
| 114 new RoundingFunctions((x) => x.floor(), (x) => x.ceil()); | 114 new RoundingFunctions((x) => x.floor(), (x) => x.ceil()); |
| 115 | 115 |
| 116 factory RoundingFunctions.identity() => | 116 factory RoundingFunctions.identity() => |
| 117 new RoundingFunctions(identityFunction, identityFunction); | 117 new RoundingFunctions(identityFunction, identityFunction); |
| 118 | 118 |
| 119 RoundFunction get floor => super.first; | 119 RoundFunction get floor => super.first; |
| 120 RoundFunction get ceil => super.last; | 120 RoundFunction get ceil => super.last; |
| 121 } | 121 } |
| 122 | 122 |
| 123 /// Namespacing container for utilities used by scales. | 123 /// Namespacing container for utilities used by scales. |
| 124 abstract class ScaleUtils { | 124 abstract class ScaleUtils { |
| 125 /// Utility to return extent of sorted [values]. | 125 /// Utility to return extent of sorted [values]. |
| 126 static Extent extent(Iterable values) => | 126 static Extent extent(Iterable values) => values.first < values.last |
| 127 values.first < values.last | 127 ? new Extent(values.first, values.last) |
| 128 ? new Extent(values.first, values.last) | 128 : new Extent(values.last, values.first); |
| 129 : new Extent(values.last, values.first); | |
| 130 | 129 |
| 131 /// Extends [values] to round numbers based on the given pair of | 130 /// Extends [values] to round numbers based on the given pair of |
| 132 /// floor and ceil functions. [functions] is a pair of rounding function | 131 /// floor and ceil functions. [functions] is a pair of rounding function |
| 133 /// among which the first is used to compute floor of a number and the | 132 /// among which the first is used to compute floor of a number and the |
| 134 /// second for ceil of the number. | 133 /// second for ceil of the number. |
| 135 static List nice(List values, RoundingFunctions functions) { | 134 static List nice(List values, RoundingFunctions functions) { |
| 136 if (values.last >= values.first) { | 135 if (values.last >= values.first) { |
| 137 values[0] = functions.floor(values.first); | 136 values[0] = functions.floor(values.first); |
| 138 values[values.length - 1] = functions.ceil(values.last); | 137 values[values.length - 1] = functions.ceil(values.last); |
| 139 } else { | 138 } else { |
| 140 values[values.length - 1] = functions.floor(values.last); | 139 values[values.length - 1] = functions.floor(values.last); |
| 141 values[0] = functions.ceil(values.first); | 140 values[0] = functions.ceil(values.first); |
| 142 } | 141 } |
| 143 return values; | 142 return values; |
| 144 } | 143 } |
| 145 | 144 |
| 146 static RoundingFunctions niceStep(num step) => (step > 0) | 145 static RoundingFunctions niceStep(num step) => (step > 0) |
| 147 ? new RoundingFunctions( | 146 ? new RoundingFunctions( |
| 148 (x) => (x < step) ? x.floor() : (x / step).floor() * step, | 147 (x) => (x < step) ? x.floor() : (x / step).floor() * step, |
| 149 (x) => (x < step) ? x.ceil() : (x / step).ceil() * step) | 148 (x) => (x < step) ? x.ceil() : (x / step).ceil() * step) |
| 150 : new RoundingFunctions.identity(); | 149 : new RoundingFunctions.identity(); |
| 151 | 150 |
| 152 /// Returns a Function that given a value x on the domain, returns the | 151 /// Returns a Function that given a value x on the domain, returns the |
| 153 /// corresponding value on the range on a bilinear scale. | 152 /// corresponding value on the range on a bilinear scale. |
| 154 /// | 153 /// |
| 155 /// @param domain The domain of the scale. | 154 /// @param domain The domain of the scale. |
| 156 /// @param range The range of the scale. | 155 /// @param range The range of the scale. |
| 157 /// @param uninterpolator The uninterpolator for domain values. | 156 /// @param uninterpolator The uninterpolator for domain values. |
| 158 /// @param interpolator The interpolator for range values. | 157 /// @param interpolator The interpolator for range values. |
| 159 static Function bilinearScale(List domain, List range, | 158 static Function bilinearScale( |
| 160 Function uninterpolator, Function interpolator) { | 159 List domain, List range, Function uninterpolator, Function interpolator) { |
| 161 var u = uninterpolator(domain[0], domain[1]), | 160 var u = uninterpolator(domain[0], domain[1]), |
| 162 i = interpolator(range[0], range[1]); | 161 i = interpolator(range[0], range[1]); |
| 163 return (x) => i(u(x)); | 162 return (x) => i(u(x)); |
| 164 } | 163 } |
| 165 | 164 |
| 166 /// Returns a Function that given a value x on the domain, returns the | 165 /// Returns a Function that given a value x on the domain, returns the |
| 167 /// corresponding value on the range on a polylinear scale. | 166 /// corresponding value on the range on a polylinear scale. |
| 168 /// | 167 /// |
| 169 /// @param domain The domain of the scale. | 168 /// @param domain The domain of the scale. |
| 170 /// @param range The range of the scale. | 169 /// @param range The range of the scale. |
| 171 /// @param uninterpolator The uninterpolator for domain values. | 170 /// @param uninterpolator The uninterpolator for domain values. |
| 172 /// @param interpolator The interpolator for range values. | 171 /// @param interpolator The interpolator for range values. |
| 173 static Function polylinearScale(List domain, List range, | 172 static Function polylinearScale( |
| 174 Function uninterpolator, Function interpolator) { | 173 List domain, List range, Function uninterpolator, Function interpolator) { |
| 175 var u = [], | 174 var u = [], i = [], j = 0, k = math.min(domain.length, range.length) - 1; |
| 176 i = [], | |
| 177 j = 0, | |
| 178 k = math.min(domain.length, range.length) - 1; | |
| 179 | 175 |
| 180 // Handle descending domains. | 176 // Handle descending domains. |
| 181 if (domain[k] < domain[0]) { | 177 if (domain[k] < domain[0]) { |
| 182 domain = domain.reversed.toList(); | 178 domain = domain.reversed.toList(); |
| 183 range = range.reversed.toList(); | 179 range = range.reversed.toList(); |
| 184 } | 180 } |
| 185 | 181 |
| 186 while (++j <= k) { | 182 while (++j <= k) { |
| 187 u.add(uninterpolator(domain[j - 1], domain[j])); | 183 u.add(uninterpolator(domain[j - 1], domain[j])); |
| 188 i.add(interpolator(range[j - 1], range[j])); | 184 i.add(interpolator(range[j - 1], range[j])); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 hi = mid; | 221 hi = mid; |
| 226 } else { | 222 } else { |
| 227 lo = mid + 1; | 223 lo = mid + 1; |
| 228 } | 224 } |
| 229 } | 225 } |
| 230 return lo; | 226 return lo; |
| 231 } | 227 } |
| 232 | 228 |
| 233 static Function bisect = bisectRight; | 229 static Function bisect = bisectRight; |
| 234 } | 230 } |
| OLD | NEW |