OLD | NEW |
| (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 class _OrdinalScale implements OrdinalScale { | |
11 final _index = new Map<dynamic, int>(); | |
12 | |
13 List _domain = []; | |
14 List _range = []; | |
15 num _rangeBand = 0; | |
16 Extent _rangeExtent; | |
17 Function _reset; | |
18 | |
19 _OrdinalScale(); | |
20 | |
21 _OrdinalScale._clone(_OrdinalScale source) | |
22 : _domain = source._domain, | |
23 _range = source._range, | |
24 _reset = source._reset, | |
25 _rangeExtent = source._rangeExtent, | |
26 _rangeBand = source._rangeBand { | |
27 _index.addAll(source._index); | |
28 } | |
29 | |
30 @override | |
31 scale(dynamic value) { | |
32 if (!_index.containsKey(value)) { | |
33 _index[value] = domain.length; | |
34 _domain.add(value); | |
35 } | |
36 return _range.isNotEmpty | |
37 ? _range.elementAt(_index[value] % _range.length) | |
38 : 0; | |
39 } | |
40 | |
41 @override | |
42 dynamic invert(num value) { | |
43 int position = _range.indexOf(value); | |
44 return position > -1 && position < _domain.length | |
45 ? _domain[position] | |
46 : null; | |
47 } | |
48 | |
49 @override | |
50 set domain(Iterable values) { | |
51 _domain = []; | |
52 _index.clear(); | |
53 | |
54 for (var i = 0; i < values.length; i++) { | |
55 var value = values.elementAt(i); | |
56 if (_index[value] == null) { | |
57 _index[value] = _domain.length; | |
58 _domain.add(value); | |
59 } | |
60 } | |
61 | |
62 if (_reset != null) _reset(this); | |
63 } | |
64 | |
65 @override | |
66 Iterable get domain => _domain; | |
67 | |
68 @override | |
69 set range(Iterable values) => _setRange(this, values); | |
70 | |
71 @override | |
72 Iterable get range => _range; | |
73 | |
74 @override | |
75 Extent get rangeExtent => _rangeExtent; | |
76 | |
77 @override | |
78 void rangePoints(Iterable range, [double padding = 0.0]) => | |
79 _setRangePoints(this, range, padding); | |
80 | |
81 @override | |
82 void rangeBands(Iterable range, | |
83 [double padding = 0.0, double outerPadding]) => | |
84 _setRangeBands(this, range, padding, | |
85 outerPadding == null ? padding : outerPadding); | |
86 | |
87 @override | |
88 void rangeRoundBands(Iterable range, | |
89 [double padding = 0.0, double outerPadding]) => | |
90 _setRangeRoundBands(this, range, padding, | |
91 outerPadding == null ? padding : outerPadding); | |
92 | |
93 @override | |
94 num get rangeBand => _rangeBand; | |
95 | |
96 @override | |
97 FormatFunction createTickFormatter([String format]) => identityFunction; | |
98 | |
99 @override | |
100 Iterable get ticks => _domain; | |
101 | |
102 @override | |
103 OrdinalScale clone() => new _OrdinalScale._clone(this); | |
104 | |
105 List _steps(start, step) => | |
106 new Range(domain.length).map((num i) => start + step * i).toList(); | |
107 | |
108 static void _setRange(_OrdinalScale scale, Iterable values) { | |
109 scale._reset = (_OrdinalScale s) { | |
110 s._range = values; | |
111 s._rangeBand = 0; | |
112 s._rangeExtent = null; | |
113 }; | |
114 scale._reset(scale); | |
115 } | |
116 | |
117 static void _setRangePoints( | |
118 _OrdinalScale scale, Iterable range, double padding) { | |
119 scale._reset = (_OrdinalScale s) { | |
120 var start = range.first, | |
121 stop = range.last, | |
122 step = (stop - start) / (s.domain.length - 1 + padding); | |
123 | |
124 s._range = s._steps(s.domain.length < 2 | |
125 ? (start + stop) / 2 | |
126 : start + step * padding / 2, step); | |
127 s._rangeBand = 0; | |
128 s._rangeExtent = new Extent(start, stop); | |
129 }; | |
130 if (scale.domain.isNotEmpty) { | |
131 scale._reset(scale); | |
132 } | |
133 } | |
134 | |
135 static void _setRangeBands(_OrdinalScale scale, | |
136 Iterable range, double padding, double outerPadding) { | |
137 scale._reset = (_OrdinalScale s) { | |
138 var start = range.first, | |
139 stop = range.last, | |
140 step = (stop - start) / s.domain.length - padding + 2 * outerPadding; | |
141 | |
142 s._range = s._steps(start + step * outerPadding, step); | |
143 s._rangeBand = step * (1 - padding); | |
144 s._rangeExtent = new Extent(start, stop); | |
145 }; | |
146 if (scale.domain.isNotEmpty){ | |
147 scale._reset(scale); | |
148 } | |
149 } | |
150 | |
151 static void _setRangeRoundBands(_OrdinalScale scale, | |
152 Iterable range, double padding, double outerPadding) { | |
153 scale._reset = (_OrdinalScale s) { | |
154 var start = range.first, | |
155 stop = range.last, | |
156 step = ((stop - start) / | |
157 (s.domain.length - padding + 2 * outerPadding)).floor(), | |
158 error = stop - start - (s.domain.length - padding) * step; | |
159 | |
160 s._range = s._steps(start + (error / 2).round(), step); | |
161 s._rangeBand = (step * (1 - padding)).round(); | |
162 s._rangeExtent = new Extent(start, stop); | |
163 }; | |
164 if (scale.domain.isNotEmpty) { | |
165 scale._reset(scale); | |
166 } | |
167 } | |
168 | |
169 // | |
170 // Properties that are valid only on quantitative scales. | |
171 // | |
172 | |
173 bool clamp; | |
174 bool nice; | |
175 bool rounded; | |
176 int ticksCount; | |
177 } | |
OLD | NEW |