'use strict'; var Axes = require('../../plots/cartesian/axes'); var isArray1D = require('../../lib').isArray1D; var cheaterBasis = require('./cheater_basis'); var arrayMinmax = require('./array_minmax'); var calcGridlines = require('./calc_gridlines'); var calcLabels = require('./calc_labels'); var calcClipPath = require('./calc_clippath'); var clean2dArray = require('../heatmap/clean_2d_array'); var smoothFill2dArray = require('./smooth_fill_2d_array'); var convertColumnData = require('../heatmap/convert_column_xyz'); var setConvert = require('./set_convert'); module.exports = function calc(gd, trace) { var xa = Axes.getFromId(gd, trace.xaxis); var ya = Axes.getFromId(gd, trace.yaxis); var aax = trace.aaxis; var bax = trace.baxis; var x = trace.x; var y = trace.y; var cols = []; if(x && isArray1D(x)) cols.push('x'); if(y && isArray1D(y)) cols.push('y'); if(cols.length) { convertColumnData(trace, aax, bax, 'a', 'b', cols); } var a = trace._a = trace._a || trace.a; var b = trace._b = trace._b || trace.b; x = trace._x || trace.x; y = trace._y || trace.y; var t = {}; if(trace._cheater) { var avals = aax.cheatertype === 'index' ? a.length : a; var bvals = bax.cheatertype === 'index' ? b.length : b; x = cheaterBasis(avals, bvals, trace.cheaterslope); } trace._x = x = clean2dArray(x); trace._y = y = clean2dArray(y); // Fill in any undefined values with elliptic smoothing. This doesn't take // into account the spacing of the values. That is, the derivatives should // be modified to use a and b values. It's not that hard, but this is already // moderate overkill for just filling in missing values. smoothFill2dArray(x, a, b); smoothFill2dArray(y, a, b); setConvert(trace); // create conversion functions that depend on the data trace.setScale(); // This is a rather expensive scan. Nothing guarantees monotonicity, // so we need to scan through all data to get proper ranges: var xrange = arrayMinmax(x); var yrange = arrayMinmax(y); var dx = 0.5 * (xrange[1] - xrange[0]); var xc = 0.5 * (xrange[1] + xrange[0]); var dy = 0.5 * (yrange[1] - yrange[0]); var yc = 0.5 * (yrange[1] + yrange[0]); // Expand the axes to fit the plot, except just grow it by a factor of 1.3 // because the labels should be taken into account except that's difficult // hence 1.3. var grow = 1.3; xrange = [xc - dx * grow, xc + dx * grow]; yrange = [yc - dy * grow, yc + dy * grow]; trace._extremes[xa._id] = Axes.findExtremes(xa, xrange, {padded: true}); trace._extremes[ya._id] = Axes.findExtremes(ya, yrange, {padded: true}); // Enumerate the gridlines, both major and minor, and store them on the trace // object: calcGridlines(trace, 'a', 'b'); calcGridlines(trace, 'b', 'a'); // Calculate the text labels for each major gridline and store them on the // trace object: calcLabels(trace, aax); calcLabels(trace, bax); // Tabulate points for the four segments that bound the axes so that we can // map to pixel coordinates in the plot function and create a clip rect: t.clipsegments = calcClipPath(trace._xctrl, trace._yctrl, aax, bax); t.x = x; t.y = y; t.a = a; t.b = b; return [t]; };