| import "../arrays/map"; | |
| import "../core/identity"; | |
| import "../format/formatPrefix"; | |
| import "../format/precision"; | |
| import "../format/round"; | |
| function d3_locale_numberFormat(locale) { | |
| var locale_decimal = locale.decimal, | |
| locale_thousands = locale.thousands, | |
| locale_grouping = locale.grouping, | |
| locale_currency = locale.currency, | |
| formatGroup = locale_grouping ? function(value) { | |
| var i = value.length, | |
| t = [], | |
| j = 0, | |
| g = locale_grouping[0]; | |
| while (i > 0 && g > 0) { | |
| t.push(value.substring(i -= g, i + g)); | |
| g = locale_grouping[j = (j + 1) % locale_grouping.length]; | |
| } | |
| return t.reverse().join(locale_thousands); | |
| } : d3_identity; | |
| return function(specifier) { | |
| var match = d3_format_re.exec(specifier), | |
| fill = match[1] || " ", | |
| align = match[2] || ">", | |
| sign = match[3] || "", | |
| symbol = match[4] || "", | |
| zfill = match[5], | |
| width = +match[6], | |
| comma = match[7], | |
| precision = match[8], | |
| type = match[9], | |
| scale = 1, | |
| prefix = "", | |
| suffix = "", | |
| integer = false; | |
| if (precision) precision = +precision.substring(1); | |
| if (zfill || fill === "0" && align === "=") { | |
| zfill = fill = "0"; | |
| align = "="; | |
| if (comma) width -= Math.floor((width - 1) / 4); | |
| } | |
| switch (type) { | |
| case "n": comma = true; type = "g"; break; | |
| case "%": scale = 100; suffix = "%"; type = "f"; break; | |
| case "p": scale = 100; suffix = "%"; type = "r"; break; | |
| case "b": | |
| case "o": | |
| case "x": | |
| case "X": if (symbol === "#") prefix = "0" + type.toLowerCase(); | |
| case "c": | |
| case "d": integer = true; precision = 0; break; | |
| case "s": scale = -1; type = "r"; break; | |
| } | |
| if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1]; | |
| // If no precision is specified for r, fallback to general notation. | |
| if (type == "r" && !precision) type = "g"; | |
| // Ensure that the requested precision is in the supported range. | |
| if (precision != null) { | |
| if (type == "g") precision = Math.max(1, Math.min(21, precision)); | |
| else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); | |
| } | |
| type = d3_format_types.get(type) || d3_format_typeDefault; | |
| var zcomma = zfill && comma; | |
| return function(value) { | |
| var fullSuffix = suffix; | |
| // Return the empty string for floats formatted as ints. | |
| if (integer && (value % 1)) return ""; | |
| // Convert negative to positive, and record the sign prefix. | |
| var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign; | |
| // Apply the scale, computing it from the value's exponent for si format. | |
| // Preserve the existing suffix, if any, such as the currency symbol. | |
| if (scale < 0) { | |
| var unit = d3.formatPrefix(value, precision); | |
| value = unit.scale(value); | |
| fullSuffix = unit.symbol + suffix; | |
| } else { | |
| value *= scale; | |
| } | |
| // Convert to the desired precision. | |
| value = type(value, precision); | |
| // Break the value into the integer part (before) and decimal part (after). | |
| var i = value.lastIndexOf("."), | |
| before = i < 0 ? value : value.substring(0, i), | |
| after = i < 0 ? "" : locale_decimal + value.substring(i + 1); | |
| // If the fill character is not "0", grouping is applied before padding. | |
| if (!zfill && comma) before = formatGroup(before); | |
| var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), | |
| padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; | |
| // If the fill character is "0", grouping is applied after padding. | |
| if (zcomma) before = formatGroup(padding + before); | |
| // Apply prefix. | |
| negative += prefix; | |
| // Rejoin integer and decimal parts. | |
| value = before + after; | |
| return (align === "<" ? negative + value + padding | |
| : align === ">" ? padding + negative + value | |
| : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) | |
| : negative + (zcomma ? value : padding + value)) + fullSuffix; | |
| }; | |
| }; | |
| } | |
| // [[fill]align][sign][symbol][0][width][,][.precision][type] | |
| var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; | |
| var d3_format_types = d3.map({ | |
| b: function(x) { return x.toString(2); }, | |
| c: function(x) { return String.fromCharCode(x); }, | |
| o: function(x) { return x.toString(8); }, | |
| x: function(x) { return x.toString(16); }, | |
| X: function(x) { return x.toString(16).toUpperCase(); }, | |
| g: function(x, p) { return x.toPrecision(p); }, | |
| e: function(x, p) { return x.toExponential(p); }, | |
| f: function(x, p) { return x.toFixed(p); }, | |
| r: function(x, p) { return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); } | |
| }); | |
| function d3_format_typeDefault(x) { | |
| return x + ""; | |
| } |