/** * Abstract; see the various scale implementations. * * @class Represents a scale; a function that performs a transformation from * data domain to visual range. For quantitative and quantile scales, the domain * is expressed as numbers; for ordinal scales, the domain is expressed as * strings (or equivalently objects with unique string representations). The * "visual range" may correspond to pixel space, colors, font sizes, and the * like. * *
Note that scales are functions, and thus can be used as properties * directly, assuming that the data associated with a mark is a number. While * this is convenient for single-use scales, frequently it is desirable to * define scales globally: * *
var y = pv.Scale.linear(0, 100).range(0, 640);* * The y scale can now be equivalently referenced within a property: * *
.height(function(d) y(d))* * Alternatively, if the data are not simple numbers, the appropriate value can * be passed to the y scale (e.g., d.foo). The {@link #by} * method similarly allows the data to be mapped to a numeric value before * performing the linear transformation. * * @see pv.Scale.quantitative * @see pv.Scale.quantile * @see pv.Scale.ordinal * @extends function */ pv.Scale = function() {}; /** * @private Returns a function that interpolators from the start value to the * end value, given a parameter t in [0, 1]. * * @param start the start value. * @param end the end value. */ pv.Scale.interpolator = function(start, end) { if (typeof start == "number") { return function(t) { return t * (end - start) + start; }; } /* For now, assume color. */ start = pv.color(start).rgb(); end = pv.color(end).rgb(); return function(t) { var a = start.a * (1 - t) + end.a * t; if (a < 1e-5) a = 0; // avoid scientific notation return (start.a == 0) ? pv.rgb(end.r, end.g, end.b, a) : ((end.a == 0) ? pv.rgb(start.r, start.g, start.b, a) : pv.rgb( Math.round(start.r * (1 - t) + end.r * t), Math.round(start.g * (1 - t) + end.g * t), Math.round(start.b * (1 - t) + end.b * t), a)); }; }; /** * Returns a view of this scale by the specified accessor function f. * Given a scale y, y.by(function(d) d.foo) is equivalent to * function(d) y(d.foo). * *
This method is provided for convenience, such that scales can be * succinctly defined inline. For example, given an array of data elements that * have a score attribute with the domain [0, 1], the height property * could be specified as: * *
.height(pv.Scale.linear().range(0, 480).by(function(d) d.score))* * This is equivalent to: * *
.height(function(d) d.score * 480)* * This method should be used judiciously; it is typically more clear to invoke * the scale directly, passing in the value to be scaled. * * @function * @name pv.Scale.prototype.by * @param {function} f an accessor function. * @returns {pv.Scale} a view of this scale by the specified accessor function. */