import "../arrays/range"; import "../core/rebind"; import "../interpolate/interpolate"; import "../interpolate/round"; import "../interpolate/uninterpolate"; import "../format/format"; import "bilinear"; import "nice"; import "polylinear"; import "scale"; 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() { d3_scale_nice(domain, d3_scale_linearNice); 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(dx) { dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1); return dx && { floor: function(x) { return Math.floor(x / dx) * dx; }, ceil: function(x) { return Math.ceil(x / dx) * dx; } }; } function d3_scale_linearTickRange(domain, m) { 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 precision = -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01); return d3.format(format ? format.replace(d3_format_re, function(a, b, c, d, e, f, g, h, i, j) { return [b, c, d, e, f, g, h, i || "." + (precision - (j === "%") * 2), j].join(""); }) : ",." + precision + "f"); }