1 /**
  2  * Returns a new grid layout.
  3  *
  4  * @class A grid layout with regularly-sized rows and columns. <img
  5  * src="../grid.png" width="160" height="160" align="right"> The number of rows
  6  * and columns are determined from the array, which should be in row-major
  7  * order. For example, the 2×3 array:
  8  *
  9  * <pre>1 2 3
 10  * 4 5 6</pre>
 11  *
 12  * should be represented as:
 13  *
 14  * <pre>[[1, 2, 3], [4, 5, 6]]</pre>
 15  *
 16  * If your data is in column-major order, you can use {@link pv.transpose} to
 17  * transpose it.
 18  *
 19  * <p>This layout defines left, top, width, height and data properties. The data
 20  * property will be the associated element in the array. For example, if the
 21  * array is a two-dimensional array of values in the range [0,1], a simple
 22  * heatmap can be generated as:
 23  *
 24  * <pre>.add(pv.Bar)
 25  *   .extend(pv.Layout.grid(array))
 26  *   .fillStyle(pv.ramp("white", "black"))</pre>
 27  *
 28  * By default, the grid fills the full width and height of the parent panel.
 29  *
 30  * @param {array[]} arrays an array of arrays.
 31  * @returns {pv.Layout.grid} a grid layout.
 32  */
 33 pv.Layout.grid = function(arrays) {
 34   var rows = arrays.length, cols = arrays[0].length;
 35 
 36   /** @private */
 37   function w() { return this.parent.width() / cols; }
 38 
 39   /** @private */
 40   function h() { return this.parent.height() / rows; }
 41 
 42   /* A dummy mark, like an anchor, which the caller extends. */
 43   return new pv.Mark()
 44       .data(pv.blend(arrays))
 45       .left(function() { return w.call(this) * (this.index % cols); })
 46       .top(function() { return h.call(this) * Math.floor(this.index / cols); })
 47       .width(w)
 48       .height(h);
 49 };
 50