Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: charted/lib/core/scales/log_scale.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « charted/lib/core/scales/linear_scale.dart ('k') | charted/lib/core/scales/ordinal_scale.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //
2 // Copyright 2014 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 //
8 part of charted.core.scales;
9
10 /// Log scale is similar to linear scale, except there's a logarithmic
11 /// transform that is applied to the input domain value before the output
12 /// range value is computed.
13 ///
14 /// The mapping to the output range value y can be expressed as a function
15 /// of the input domain value x: y = m log(x) + b.
16 ///
17 /// As log(0) is negative infinity, a log scale must have either an
18 /// exclusively-positive or exclusively-negative domain; the domain must not
19 /// include or cross zero.
20 class LogScale implements Scale {
21 static const defaultBase = 10;
22 static const defaultDomain = const [1, 10];
23 static final negativeNumbersRoundFunctionsPair =
24 new RoundingFunctions(
25 (x) => -((-x).floor()),
26 (x) => -((-x).ceil()));
27
28 final LinearScale _linear;
29
30 bool _nice = false;
31 int _base = defaultBase;
32 int _ticksCount = 10;
33 bool _positive = true;
34 List _domain = defaultDomain;
35
36 LogScale() : _linear = new LinearScale();
37
38 LogScale._clone(LogScale source)
39 : _linear = source._linear.clone(),
40 _domain = source._domain.toList(),
41 _positive = source._positive,
42 _base = source._base,
43 _nice = source._nice,
44 _ticksCount = source._ticksCount;
45
46 num _log(x) => (_positive ?
47 math.log(x < 0 ? 0 : x) : -math.log(x > 0 ? 0 : -x)) / math.log(base);
48
49 num _pow(x) => _positive ? math.pow(base, x) : -math.pow(base, -x);
50
51 set base(int value) {
52 if (_base != value) {
53 _base = value;
54 _reset();
55 }
56 }
57
58 get base => _base;
59
60 @override
61 num scale(x) => _linear.scale(_log(x));
62
63 @override
64 num invert(x) => _pow(_linear.invert(x));
65
66 @override
67 set domain(Iterable values) {
68 _positive = values.first >= 0;
69 _domain = values;
70 _reset();
71 }
72
73 @override
74 Iterable get domain => _domain;
75
76 @override
77 set range(Iterable newRange) {
78 _linear.range = newRange;
79 }
80
81 @override
82 Iterable get range => _linear.range;
83
84 @override
85 set rounded(bool value) {
86 _linear.rounded = value;
87 }
88
89 @override
90 bool get rounded => _linear.rounded;
91
92 @override
93 set nice(bool value) {
94 if (_nice != value) {
95 _nice = value;
96 _reset();
97 }
98 }
99
100 @override
101 bool get nice => _nice;
102
103 @override
104 set ticksCount(int value) {
105 if (_ticksCount != value) {
106 _ticksCount = value;
107 _reset();
108 }
109 }
110
111 @override
112 int get ticksCount => _ticksCount;
113
114 @override
115 set clamp(bool value) {
116 _linear.clamp = value;
117 }
118
119 @override
120 bool get clamp => _linear.clamp;
121
122 @override
123 Extent get rangeExtent => _linear.rangeExtent;
124
125 _reset() {
126 if (_nice) {
127 var niced = _domain.map((e) => _log(e)).toList();
128 var roundFunctions = _positive
129 ? new RoundingFunctions.defaults()
130 : negativeNumbersRoundFunctionsPair;
131
132 _linear.domain = ScaleUtils.nice(niced, roundFunctions);
133 _domain = niced.map((e) => _pow(e)).toList();
134 } else {
135 _linear.domain = _domain.map((e) => _log(e)).toList();
136 }
137 }
138
139 Iterable get ticks {
140 var extent = ScaleUtils.extent(_domain),
141 ticks = [],
142 u = extent.min,
143 v = extent.max,
144 i = (_log(u)).floor(),
145 j = (_log(v)).ceil(),
146 n = (_base % 1 > 0) ? 2 : _base;
147
148 if ((j - i).isFinite) {
149 if (_positive) {
150 for (; i < j; i++) for (var k = 1; k < n; k++) ticks.add(_pow(i) * k);
151 ticks.add(_pow(i));
152 } else {
153 ticks.add(_pow(i));
154 for (; i++ < j;) for (var k = n - 1; k > 0; k--) ticks.add(_pow(i) * k);
155 }
156 for (i = 0; ticks[i] < u; i++) {} // strip small values
157 for (j = ticks.length; ticks[j - 1] > v; j--) {} // strip big values
158 ticks = ticks.sublist(i, j);
159 }
160 return ticks;
161 }
162
163 FormatFunction createTickFormatter([String formatStr]) {
164 NumberFormat formatter = new NumberFormat(new EnUsLocale());
165 FormatFunction logFormatFunction =
166 formatter.format(formatStr != null ? formatStr : ".0E");
167 var k = math.max(.1, ticksCount / this.ticks.length),
168 e = _positive ? 1e-12 : -1e-12;
169 return (d) {
170 if (_positive) {
171 return d / _pow((_log(d) + e).ceil()) <= k ? logFormatFunction(d) : '';
172 } else {
173 return d / _pow((_log(d) + e).floor()) <= k ? logFormatFunction(d) : '';
174 }
175 };
176 }
177
178 @override
179 LogScale clone() => new LogScale._clone(this);
180 }
OLDNEW
« no previous file with comments | « charted/lib/core/scales/linear_scale.dart ('k') | charted/lib/core/scales/ordinal_scale.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698