@@ -32,47 +32,13 @@ module.exports = function calc(gd, trace) {
3232
3333 var i , n , m ;
3434
35- cleanBins ( trace , xa , 'x' ) ;
36- cleanBins ( trace , ya , 'y' ) ;
37-
3835 var serieslen = Math . min ( x . length , y . length ) ;
3936 if ( x . length > serieslen ) x . splice ( serieslen , x . length - serieslen ) ;
4037 if ( y . length > serieslen ) y . splice ( serieslen , y . length - serieslen ) ;
4138
42-
4339 // calculate the bins
44- if ( trace . autobinx || ! trace . xbins ||
45- trace . xbins . start === null || trace . xbins . end === null ) {
46- trace . xbins = Axes . autoBin ( x , xa , trace . nbinsx , '2d' , xcalendar ) ;
47- if ( trace . type === 'histogram2dcontour' ) {
48- // the "true" last argument reverses the tick direction (which we can't
49- // just do with a minus sign because of month bins)
50- trace . xbins . start = xc2r ( Axes . tickIncrement (
51- xr2c ( trace . xbins . start ) , trace . xbins . size , true , xcalendar ) ) ;
52- trace . xbins . end = xc2r ( Axes . tickIncrement (
53- xr2c ( trace . xbins . end ) , trace . xbins . size , false , xcalendar ) ) ;
54- }
55-
56- // copy bin info back to the source data.
57- trace . _input . xbins = trace . xbins ;
58- // note that it's possible to get here with an explicit autobin: false
59- // if the bins were not specified.
60- // in that case this will remain in the trace, so that future updates
61- // which would change the autobinning will not do so.
62- trace . _input . autobinx = trace . autobinx ;
63- }
64- if ( trace . autobiny || ! trace . ybins ||
65- trace . ybins . start === null || trace . ybins . end === null ) {
66- trace . ybins = Axes . autoBin ( y , ya , trace . nbinsy , '2d' , ycalendar ) ;
67- if ( trace . type === 'histogram2dcontour' ) {
68- trace . ybins . start = yc2r ( Axes . tickIncrement (
69- yr2c ( trace . ybins . start ) , trace . ybins . size , true , ycalendar ) ) ;
70- trace . ybins . end = yc2r ( Axes . tickIncrement (
71- yr2c ( trace . ybins . end ) , trace . ybins . size , false , ycalendar ) ) ;
72- }
73- trace . _input . ybins = trace . ybins ;
74- trace . _input . autobiny = trace . autobiny ;
75- }
40+ cleanAndAutobin ( trace , 'x' , x , xa , xr2c , xc2r , xcalendar ) ;
41+ cleanAndAutobin ( trace , 'y' , y , ya , yr2c , yc2r , ycalendar ) ;
7642
7743 // make the empty bin array & scale the map
7844 var z = [ ] ;
@@ -110,12 +76,12 @@ module.exports = function calc(gd, trace) {
11076 }
11177
11278 // decrease end a little in case of rounding errors
113- var binspec = trace . xbins ,
114- binStart = xr2c ( binspec . start ) ,
115- binEnd = xr2c ( binspec . end ) +
116- ( binStart - Axes . tickIncrement ( binStart , binspec . size , false , xcalendar ) ) / 1e6 ;
79+ var binSpec = trace . xbins ,
80+ binStart = xr2c ( binSpec . start ) ,
81+ binEnd = xr2c ( binSpec . end ) +
82+ ( binStart - Axes . tickIncrement ( binStart , binSpec . size , false , xcalendar ) ) / 1e6 ;
11783
118- for ( i = binStart ; i < binEnd ; i = Axes . tickIncrement ( i , binspec . size , false , xcalendar ) ) {
84+ for ( i = binStart ; i < binEnd ; i = Axes . tickIncrement ( i , binSpec . size , false , xcalendar ) ) {
11985 onecol . push ( sizeinit ) ;
12086 if ( nonuniformBinsX ) xbins . push ( i ) ;
12187 if ( doavg ) zerocol . push ( 0 ) ;
@@ -127,15 +93,15 @@ module.exports = function calc(gd, trace) {
12793 var dx = ( i - x0c ) / nx ;
12894 var x0 = xc2r ( x0c + dx / 2 ) ;
12995
130- binspec = trace . ybins ;
131- binStart = yr2c ( binspec . start ) ;
132- binEnd = yr2c ( binspec . end ) +
133- ( binStart - Axes . tickIncrement ( binStart , binspec . size , false , ycalendar ) ) / 1e6 ;
96+ binSpec = trace . ybins ;
97+ binStart = yr2c ( binSpec . start ) ;
98+ binEnd = yr2c ( binSpec . end ) +
99+ ( binStart - Axes . tickIncrement ( binStart , binSpec . size , false , ycalendar ) ) / 1e6 ;
134100
135- for ( i = binStart ; i < binEnd ; i = Axes . tickIncrement ( i , binspec . size , false , ycalendar ) ) {
136- z . push ( onecol . concat ( ) ) ;
101+ for ( i = binStart ; i < binEnd ; i = Axes . tickIncrement ( i , binSpec . size , false , ycalendar ) ) {
102+ z . push ( onecol . slice ( ) ) ;
137103 if ( nonuniformBinsY ) ybins . push ( i ) ;
138- if ( doavg ) counts . push ( zerocol . concat ( ) ) ;
104+ if ( doavg ) counts . push ( zerocol . slice ( ) ) ;
139105 }
140106 if ( nonuniformBinsY ) ybins . push ( i ) ;
141107
@@ -145,33 +111,14 @@ module.exports = function calc(gd, trace) {
145111 var y0 = yc2r ( y0c + dy / 2 ) ;
146112
147113 if ( densitynorm ) {
148- xinc = onecol . map ( function ( v , i ) {
149- if ( nonuniformBinsX ) return 1 / ( xbins [ i + 1 ] - xbins [ i ] ) ;
150- return 1 / dx ;
151- } ) ;
152- yinc = z . map ( function ( v , i ) {
153- if ( nonuniformBinsY ) return 1 / ( ybins [ i + 1 ] - ybins [ i ] ) ;
154- return 1 / dy ;
155- } ) ;
114+ xinc = makeIncrements ( onecol . length , xbins , dx , nonuniformBinsX ) ;
115+ yinc = makeIncrements ( z . length , ybins , dy , nonuniformBinsY ) ;
156116 }
157117
158118 // for date axes we need bin bounds to be calcdata. For nonuniform bins
159119 // we already have this, but uniform with start/end/size they're still strings.
160- if ( ! nonuniformBinsX && xa . type === 'date' ) {
161- xbins = {
162- start : xr2c ( xbins . start ) ,
163- end : xr2c ( xbins . end ) ,
164- size : xbins . size
165- } ;
166- }
167- if ( ! nonuniformBinsY && ya . type === 'date' ) {
168- ybins = {
169- start : yr2c ( ybins . start ) ,
170- end : yr2c ( ybins . end ) ,
171- size : ybins . size
172- } ;
173- }
174-
120+ if ( ! nonuniformBinsX && xa . type === 'date' ) xbins = binsToCalc ( xr2c , xbins ) ;
121+ if ( ! nonuniformBinsY && ya . type === 'date' ) ybins = binsToCalc ( yr2c , ybins ) ;
175122
176123 // put data into bins
177124 for ( i = 0 ; i < serieslen ; i ++ ) {
@@ -199,3 +146,52 @@ module.exports = function calc(gd, trace) {
199146 z : z
200147 } ;
201148} ;
149+
150+ function cleanAndAutobin ( trace , axLetter , data , ax , r2c , c2r , calendar ) {
151+ var binSpecAttr = axLetter + 'bins' ;
152+ var autoBinAttr = 'autobin' + axLetter ;
153+ var binSpec = trace [ binSpecAttr ] ;
154+
155+ cleanBins ( trace , ax , axLetter ) ;
156+
157+ if ( trace [ autoBinAttr ] || ! binSpec || binSpec . start === null || binSpec . end === null ) {
158+ binSpec = Axes . autoBin ( data , ax , trace [ 'nbins' + axLetter ] , '2d' , calendar ) ;
159+ if ( trace . type === 'histogram2dcontour' ) {
160+ // the "true" last argument reverses the tick direction (which we can't
161+ // just do with a minus sign because of month bins)
162+ binSpec . start = c2r ( Axes . tickIncrement (
163+ r2c ( binSpec . start ) , binSpec . size , true , calendar ) ) ;
164+ binSpec . end = c2r ( Axes . tickIncrement (
165+ r2c ( binSpec . end ) , binSpec . size , false , calendar ) ) ;
166+ }
167+
168+ // copy bin info back to the source data.
169+ trace . _input [ binSpecAttr ] = trace [ binSpecAttr ] = binSpec ;
170+ // note that it's possible to get here with an explicit autobin: false
171+ // if the bins were not specified.
172+ // in that case this will remain in the trace, so that future updates
173+ // which would change the autobinning will not do so.
174+ trace . _input [ autoBinAttr ] = trace [ autoBinAttr ] ;
175+ }
176+ }
177+
178+ function makeIncrements ( len , bins , dv , nonuniform ) {
179+ var out = new Array ( len ) ;
180+ var i ;
181+ if ( nonuniform ) {
182+ for ( i = 0 ; i < len ; i ++ ) out [ i ] = 1 / ( bins [ i + 1 ] - bins [ i ] ) ;
183+ }
184+ else {
185+ var inc = 1 / dv ;
186+ for ( i = 0 ; i < len ; i ++ ) out [ i ] = inc ;
187+ }
188+ return out ;
189+ }
190+
191+ function binsToCalc ( r2c , bins ) {
192+ return {
193+ start : r2c ( bins . start ) ,
194+ end : r2c ( bins . end ) ,
195+ size : bins . size
196+ } ;
197+ }
0 commit comments