UNPKG

d3-jsnext

Version:
175 lines (147 loc) 5.43 kB
import { abs } from '../math/abs'; import { d3_format_re } from '../locale/number-format'; import { d3_scaleExtent, d3$scale } from './scale'; import { d3_scale_niceStep, d3_scale_nice } from './nice'; import { d3_interpolateRound } from '../interpolate/round'; import { d3_interpolate } from '../interpolate/interpolate'; import { d3_uninterpolateNumber, d3_uninterpolateClamp } from '../interpolate/uninterpolate'; import { d3_scale_bilinear } from './bilinear'; import { d3_scale_polylinear } from './polylinear'; import { d3$format } from '../format/format'; import { d3$formatPrefix } from '../format/formatPrefix'; import { d3$range } from '../arrays/range'; import { d3$rebind } from '../core/rebind'; var d3$scale$linear; d3$scale$linear = function() { return d3_scale_linear([0, 1], [0, 1], d3_interpolate, false); }; function d3_scale_linear(domain, range, interpolate, clamp) { var output, input; function rescale() { var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; output = linear(domain, range, uninterpolate, interpolate); input = linear(range, domain, uninterpolate, d3_interpolate); return scale; } function scale(x) { return output(x); } // Note: requires range is coercible to number! scale.invert = function(y) { return input(y); }; scale.domain = function(x) { if (!arguments.length) return domain; domain = x.map(Number); return rescale(); }; scale.range = function(x) { if (!arguments.length) return range; range = x; return rescale(); }; scale.rangeRound = function(x) { return scale.range(x).interpolate(d3_interpolateRound); }; scale.clamp = function(x) { if (!arguments.length) return clamp; clamp = x; return rescale(); }; scale.interpolate = function(x) { if (!arguments.length) return interpolate; interpolate = x; return rescale(); }; scale.ticks = function(m) { return d3_scale_linearTicks(domain, m); }; scale.tickFormat = function(m, format) { return d3_scale_linearTickFormat(domain, m, format); }; scale.nice = function(m) { d3_scale_linearNice(domain, m); return rescale(); }; scale.copy = function() { return d3_scale_linear(domain, range, interpolate, clamp); }; return rescale(); } function d3_scale_linearRebind(scale, linear) { return d3$rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); } function d3_scale_linearNice(domain, m) { return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); } function d3_scale_linearTickRange(domain, m) { if (m == null) m = 10; var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; // Filter ticks to get closer to the desired count. if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; // Round start and stop values to step interval. extent[0] = Math.ceil(extent[0] / step) * step; extent[1] = Math.floor(extent[1] / step) * step + step * .5; // inclusive extent[2] = step; return extent; } function d3_scale_linearTicks(domain, m) { return d3$range.apply(d3, d3_scale_linearTickRange(domain, m)); } function d3_scale_linearTickFormat(domain, m, format) { var range = d3_scale_linearTickRange(domain, m); if (format) { var match = d3_format_re.exec(format); match.shift(); if (match[8] === "s") { var prefix = d3$formatPrefix(Math.max(abs(range[0]), abs(range[1]))); if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2])); match[8] = "f"; format = d3$format(match.join("")); return function(d) { return format(prefix.scale(d)) + prefix.symbol; }; } if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range); format = match.join(""); } else { format = ",." + d3_scale_linearPrecision(range[2]) + "f"; } return d3$format(format); } var d3_scale_linearFormatSignificant = {s: 1, g: 1, p: 1, r: 1, e: 1}; // Returns the number of significant digits after the decimal point. function d3_scale_linearPrecision(value) { return -Math.floor(Math.log(value) / Math.LN10 + .01); } // For some format types, the precision specifies the number of significant // digits; for others, it specifies the number of digits after the decimal // point. For significant format types, the desired precision equals one plus // the difference between the decimal precision of the range’s maximum absolute // value and the tick step’s decimal precision. For format "e", the digit before // the decimal point counts as one. function d3_scale_linearFormatPrecision(type, range) { var p = d3_scale_linearPrecision(range[2]); return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2; } export { d3$scale$linear, d3_scale_linearFormatPrecision, d3_scale_linearPrecision, d3_scale_linearFormatSignificant, d3_scale_linearTickFormat, d3_scale_linearTicks, d3_scale_linearTickRange, d3_scale_linearNice, d3_scale_linearRebind, d3_scale_linear };