1 /**
  2  * Returns a root scale for the specified domain. The arguments to this
  3  * constructor are optional, and equivalent to calling {@link #domain}.
  4  * The default domain and range are [0,1].
  5  *
  6  * @class Represents a root scale; a function that performs a power
  7  * transformation. <style type="text/css">sub{line-height:0}</style> Most
  8  * commonly, a root scale represents a 1-dimensional root transformation from a
  9  * numeric domain of input data [<i>d<sub>0</sub></i>, <i>d<sub>1</sub></i>] to
 10  * a numeric range of pixels [<i>r<sub>0</sub></i>, <i>r<sub>1</sub></i>].
 11  *
 12  * <p>Note that the scale is itself a function, and thus can be used as a
 13  * property directly, assuming that the data associated with a mark is a
 14  * number. While this is convenient for single-use scales, frequently it is
 15  * desirable to define scales globally:
 16  *
 17  * <pre>var y = pv.Scale.root(0, 100).range(0, 640);</pre>
 18  *
 19  * The <tt>y</tt> scale can now be equivalently referenced within a property:
 20  *
 21  * <pre>    .height(function(d) y(d))</pre>
 22  *
 23  * Alternatively, if the data are not simple numbers, the appropriate value can
 24  * be passed to the <tt>y</tt> scale (e.g., <tt>d.foo</tt>). The {@link #by}
 25  * method similarly allows the data to be mapped to a numeric value before
 26  * performing the root transformation.
 27  *
 28  * @param {number...} domain... optional domain values.
 29  * @extends pv.Scale.quantitative
 30  */
 31 pv.Scale.root = function() {
 32   var scale = pv.Scale.quantitative();
 33 
 34   /**
 35    * Sets or gets the exponent; defaults to 2.
 36    *
 37    * @function
 38    * @name pv.Scale.root.prototype.power
 39    * @param {number} [v] the new exponent.
 40    * @returns {pv.Scale.root} <tt>this</tt>, or the current base.
 41    */
 42   scale.power = function(v) {
 43     if (arguments.length) {
 44       var b = Number(v), p = 1 / b;
 45       scale.transform(
 46         function(x) { return Math.pow(x, p); },
 47         function(y) { return Math.pow(y, b); });
 48       return this;
 49     }
 50     return b;
 51   };
 52 
 53   scale.domain.apply(scale, arguments);
 54   return scale.power(2);
 55 };
 56