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 | |
9 library charted.locale.format; | |
10 | |
11 import 'dart:math' as math; | |
12 import 'package:intl/intl.dart'; | |
13 import 'package:charted/locale/locale.dart'; | |
14 import 'package:charted/core/utils.dart'; | |
15 | |
16 part 'format/number_format.dart'; | |
17 part 'format/time_format.dart'; | |
18 | |
19 typedef String NumberFormatFunction(num x, [int precision]); | |
20 | |
21 /** | |
22 * Returns a new format function with the given string specifier. | |
23 * The format specifier is modeled after Python 3.1's built-in format | |
24 * specification mini-language. | |
25 * | |
26 * The general form of a specifier is: | |
27 * [[fill]align][sign][symbol][0][width][,][.precision][type] | |
28 * | |
29 * @see <a href="http://docs.python.org/release/3.1.3/library/string.html#format
spec">Python format specification mini-language</a> | |
30 */ | |
31 FormatFunction format(String specifier, [Locale locale = null]) { | |
32 if (locale == null) { | |
33 locale = new EnUsLocale(); | |
34 } | |
35 return locale.numberFormat.format(specifier); | |
36 } | |
37 | |
38 | |
39 /* | |
40 * Class for computing the SI format prefix for the given value. | |
41 */ | |
42 class FormatPrefix { | |
43 // SI scale units in increments of 1000. | |
44 static const List unitPrefixes = const | |
45 ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; | |
46 | |
47 Function _scale; | |
48 String _symbol; | |
49 | |
50 FormatPrefix(num value, [int precision = 0]) { | |
51 var i = 0; | |
52 if (value < 0) { | |
53 value *= -1; | |
54 } | |
55 if (precision > 0) { | |
56 value = _roundToPrecision(value, _formatPrecision(value, precision)); | |
57 } | |
58 | |
59 // Determining SI scale of the value in increment of 1000. | |
60 i = 1 + (1e-12 + math.log(value) / math.LN10).floor(); | |
61 i = math.max(-24, math.min(24, | |
62 ((i - 1) / 3).floor() * 3)); | |
63 i = 8 + (i / 3).floor(); | |
64 | |
65 // Sets the scale and symbol of the value. | |
66 var k = math.pow(10, (8 - i).abs() * 3); | |
67 _scale = i > 8 ? (d) => d / k : (d) => d * k; | |
68 _symbol = unitPrefixes[i]; | |
69 } | |
70 | |
71 _formatPrecision(num x, num p) { | |
72 return p - (x != 0 ? (math.log(x) / math.LN10).ceil() : 1); | |
73 } | |
74 | |
75 /** Returns the value of x rounded to the nth digit. */ | |
76 _roundToPrecision(num x, num n) { | |
77 return n != 0 ? | |
78 (x * (n = math.pow(10, n))).round() / n : x.round(); | |
79 } | |
80 | |
81 /** Returns the SI prefix for the value. */ | |
82 get symbol => _symbol; | |
83 | |
84 /** Returns the scale for the value corresponding to the SI prefix. */ | |
85 get scale => _scale; | |
86 } | |
OLD | NEW |