11
11
var Axes = require ( '../../plots/cartesian/axes' ) ;
12
12
var cheaterBasis = require ( './cheater_basis' ) ;
13
13
var arrayMinmax = require ( './array_minmax' ) ;
14
-
14
+ var search = require ( '../../lib/search' ) . findBin ;
15
+ var computeControlPoints = require ( './compute_control_points' ) ;
16
+ var map2dArray = require ( './map_2d_array' ) ;
17
+ var evaluateControlPoints = require ( './evaluate_control_points' ) ;
15
18
16
19
module . exports = function calc ( gd , trace ) {
17
20
var xa = Axes . getFromId ( gd , trace . xaxis || 'x' ) ,
18
- ya = Axes . getFromId ( gd , trace . yaxis || 'y' ) ;
21
+ ya = Axes . getFromId ( gd , trace . yaxis || 'y' ) ,
22
+ aax = trace . aaxis ,
23
+ bax = trace . baxis ,
24
+ a = trace . a ,
25
+ b = trace . b ;
19
26
20
27
var xdata ;
21
28
var ydata = trace . y ;
22
29
23
30
if ( trace . _cheater ) {
24
- xdata = cheaterBasis ( trace . a . length , trace . b . length , trace . cheaterslope ) ;
31
+ var avals = aax . cheatertype === 'index' ? a . length : a
32
+ var bvals = bax . cheatertype === 'index' ? b . length : b ;
33
+ xdata = cheaterBasis ( avals , bvals , trace . cheaterslope ) ;
25
34
} else {
26
35
xdata = trace . x ;
27
36
}
@@ -44,12 +53,174 @@ module.exports = function calc(gd, trace) {
44
53
Axes . expand ( xa , xrange , { padded : true } ) ;
45
54
Axes . expand ( ya , yrange , { padded : true } ) ;
46
55
56
+ // Precompute the cartesian-space coordinates of the grid lines:
57
+ var x = xdata ;
58
+ var y = trace . y ;
59
+
60
+ // Convert cartesian-space x/y coordinates to screen space pixel coordinates:
61
+ trace . xp = map2dArray ( trace . xp , x , xa . c2p ) ;
62
+ trace . yp = map2dArray ( trace . yp , y , ya . c2p ) ;
63
+
64
+ // Next compute the control points in whichever directions are necessary:
65
+ var result = computeControlPoints ( trace . xctrl , trace . yctrl , x , y , aax . smoothing , bax . smoothing ) ;
66
+ trace . xctrl = result [ 0 ] ;
67
+ trace . yctrl = result [ 1 ] ;
68
+
69
+
70
+ console . log ( 'evaluateControlPoints(:' , evaluateControlPoints ( [ trace . xctrl , trace . yctrl ] , 0.5 , 0.5 ) ) ;
71
+
72
+
73
+ //trace.ab2c = getConvert(x, y, a, b, aax.smoothing, bax.smoothing);
74
+
75
+ // This is just a transposed function that will be useful in making
76
+ // the computations a/b-agnostic:
77
+ //trace.ba2c = function (b, a) { return trace.ab2c(a, b); }
78
+
79
+ //var agrid = makeGridLines(a, aax);
80
+ //var bgrid = makeGridLines(b, bax);
81
+
82
+ //trace.aaxis._tickinfo = agrid;
83
+ //trace.baxis._tickinfo = bgrid;
84
+
47
85
var cd0 = {
48
- x : xdata ,
49
- y : trace . y ,
50
- a : trace . a ,
51
- b : trace . b
86
+ x : x ,
87
+ y : y ,
88
+ a : a ,
89
+ b : b
52
90
} ;
53
91
54
92
return [ cd0 ] ;
55
93
} ;
94
+
95
+
96
+
97
+ /*
98
+ * Interpolate in the b-direction along constant-a lines
99
+ * x, y: 2D data arrays to be interpolated
100
+ * aidx: index of the a gridline along which to evaluate
101
+ * bidx0: lower-index of the b cell in which to interpolate
102
+ * tb: an interpolant in [0, 1]
103
+ */
104
+ /*function interpolateConstA (x, y, aidx, bidx0, tb, bsmoothing) {
105
+ if (bsmoothing) {
106
+ return [
107
+ x[aidx][bidx0] * (1 - tb) + x[aidx][bidx0 + 1] * tb,
108
+ y[aidx][bidx0] * (1 - tb) + y[aidx][bidx0 + 1] * tb
109
+ ];
110
+ } else {
111
+ return [
112
+ x[aidx][bidx0] * (1 - tb) + x[aidx][bidx0 + 1] * tb,
113
+ y[aidx][bidx0] * (1 - tb) + y[aidx][bidx0 + 1] * tb
114
+ ];
115
+ }
116
+ }*/
117
+
118
+ /*
119
+ * Interpolate in the a and b directions
120
+ * x, y: 2D data arrays to be interpolated
121
+ * aidx0: lower index of the a cell in which to interpolatel
122
+ * bidx0: lower index of the b cell in which to interpolate
123
+ * ta: an interpolant for the a direction in [0, 1]
124
+ * tb: an interpolant for the b direction in [0, 1]
125
+ */
126
+ /*function interpolateAB (x, y, aidx0, ta, bidx0, tb, asmoothing, bsmoothing) {
127
+ if (asmoothing) {
128
+ var xy0 = interpolateConstA(x, y, aidx0, bidx0, tb, bsmoothing);
129
+ var xy1 = interpolateConstA(x, y, aidx0 + 1, bidx0, tb, bsmoothing);
130
+
131
+ return [
132
+ xy0[0] * (1 - ta) + xy1[0] * ta,
133
+ xy0[1] * (1 - ta) + xy1[1] * ta
134
+ ];
135
+ } else {
136
+ var xy0 = interpolateConstA(x, y, aidx0, bidx0, tb, bsmoothing);
137
+ var xy1 = interpolateConstA(x, y, aidx0 + 1, bidx0, tb, bsmoothing);
138
+
139
+ return [
140
+ xy0[0] * (1 - ta) + xy1[0] * ta,
141
+ xy0[1] * (1 - ta) + xy1[1] * ta
142
+ ];
143
+ }
144
+ }*/
145
+
146
+ /*
147
+ * Return a function that converts a/b coordinates to x/y values
148
+ */
149
+ /*function getConvert (x, y, a, b, asmoothing, bsmoothing) {
150
+ return function (aval, bval) {
151
+ // Get the lower-indices of the box in which the point falls:
152
+ var aidx = Math.min(search(aval, a), a.length - 2);
153
+ var bidx = Math.min(search(bval, b), b.length - 2);
154
+
155
+ var ta = (aval - a[aidx]) / (a[aidx + 1] - a[aidx]);
156
+ var tb = (bval - b[bidx]) / (b[bidx + 1] - b[bidx]);
157
+
158
+ return interpolateAB(x, y, aidx, ta, bidx, tb, asmoothing, bsmoothing);
159
+ };
160
+ }*/
161
+
162
+ /*
163
+ * Interpret the tick properties to return indices, interpolants,
164
+ * and values of grid lines
165
+ *
166
+ * Output is:
167
+ * ilower: lower index of the cell in which the gridline lies
168
+ * interpolant: fractional distance of this gridline to the next cell (in [0, 1])
169
+ * values: value of the axis coordinate at each respective gridline
170
+ */
171
+ /*function makeGridLines (data, axis) {
172
+ var gridlines = [];
173
+ var t = [];
174
+ var i0 = [];
175
+ var i1 = [];
176
+ var values = [];
177
+ switch(axis.tickmode) {
178
+ case 'array':
179
+ var start = axis.arraytick0 % axis.arraydtick;
180
+ var step = axis.arraydtick;
181
+ var end = data.length;
182
+ // This could be optimized, but we'll convert this to a/b space and then do
183
+ // the interpolation in
184
+ for (var i = start; i < end; i += step) {
185
+ // If it's the end point, we'll use the end of the previous range to
186
+ // avoid going out of bounds:
187
+ var endshift = i >= end - 1 ? 1 : 0;
188
+
189
+ gridlines.push({
190
+ param: i,
191
+ idx: i - endshift,
192
+ tInterp: endshift,
193
+ value: data[i]
194
+ });
195
+ }
196
+ break;
197
+ case 'linear':
198
+ var v1 = getLinspaceStartingPoint(data[0], axis.tick0, axis.dtick);
199
+ var n = Math.ceil((data[data.length - 1] - v1) / axis.dtick);
200
+
201
+ // This could be optimized, but we'll convert this to a/b space and then do
202
+ // the interpolation in
203
+ for (var i = 0; i < n; i++) {
204
+ var val = v1 + axis.dtick * i;
205
+ var idx = Math.min(search(val, data), data.length - 2);
206
+ gridlines.push({
207
+ param: (val - data[0]) / (data[data.length - 1] - data[0]) * data.length,
208
+ idx: idx,
209
+ tInterp: (val - data[idx]) / (data[idx + 1] - data[idx]),
210
+ value: val
211
+ });
212
+ }
213
+ }
214
+
215
+ console.log('gridlines:', gridlines);
216
+
217
+ return gridlines;
218
+ }*/
219
+
220
+ /*
221
+ * Given a data range from starting at x1, this function computes the first
222
+ * point distributed along x0 + n * dx that lies within the range.
223
+ */
224
+ function getLinspaceStartingPoint ( xlow , x0 , dx ) {
225
+ return x0 + dx * Math . ceil ( ( xlow - x0 ) / dx ) ;
226
+ }
0 commit comments