@@ -16,6 +16,7 @@ var binFunctions = require('../histogram/bin_functions');
1616var normFunctions = require ( '../histogram/norm_functions' ) ;
1717var doAvg = require ( '../histogram/average' ) ;
1818var cleanBins = require ( '../histogram/clean_bins' ) ;
19+ var getBinSpanLabelRound = require ( '../histogram/bin_label_vals' ) ;
1920
2021
2122module . exports = function calc ( gd , trace ) {
@@ -30,7 +31,7 @@ module.exports = function calc(gd, trace) {
3031 var xc2r = function ( v ) { return xa . c2r ( v , 0 , xcalendar ) ; } ;
3132 var yc2r = function ( v ) { return ya . c2r ( v , 0 , ycalendar ) ; } ;
3233
33- var i , n , m ;
34+ var i , j , n , m ;
3435
3536 var serieslen = Math . min ( x . length , y . length ) ;
3637 if ( x . length > serieslen ) x . splice ( serieslen , x . length - serieslen ) ;
@@ -46,10 +47,13 @@ module.exports = function calc(gd, trace) {
4647 var zerocol = [ ] ;
4748 var nonuniformBinsX = ( typeof ( trace . xbins . size ) === 'string' ) ;
4849 var nonuniformBinsY = ( typeof ( trace . ybins . size ) === 'string' ) ;
49- var xbins = nonuniformBinsX ? [ ] : trace . xbins ;
50- var ybins = nonuniformBinsY ? [ ] : trace . ybins ;
50+ var xEdges = [ ] ;
51+ var yEdges = [ ] ;
52+ var xbins = nonuniformBinsX ? xEdges : trace . xbins ;
53+ var ybins = nonuniformBinsY ? yEdges : trace . ybins ;
5154 var total = 0 ;
5255 var counts = [ ] ;
56+ var inputPoints = [ ] ;
5357 var norm = trace . histnorm ;
5458 var func = trace . histfunc ;
5559 var densitynorm = ( norm . indexOf ( 'density' ) !== - 1 ) ;
@@ -83,10 +87,10 @@ module.exports = function calc(gd, trace) {
8387
8488 for ( i = binStart ; i < binEnd ; i = Axes . tickIncrement ( i , binSpec . size , false , xcalendar ) ) {
8589 onecol . push ( sizeinit ) ;
86- if ( nonuniformBinsX ) xbins . push ( i ) ;
90+ xEdges . push ( i ) ;
8791 if ( doavg ) zerocol . push ( 0 ) ;
8892 }
89- if ( nonuniformBinsX ) xbins . push ( i ) ;
93+ xEdges . push ( i ) ;
9094
9195 var nx = onecol . length ;
9296 var x0c = xr2c ( trace . xbins . start ) ;
@@ -100,10 +104,13 @@ module.exports = function calc(gd, trace) {
100104
101105 for ( i = binStart ; i < binEnd ; i = Axes . tickIncrement ( i , binSpec . size , false , ycalendar ) ) {
102106 z . push ( onecol . slice ( ) ) ;
103- if ( nonuniformBinsY ) ybins . push ( i ) ;
107+ yEdges . push ( i ) ;
108+ var ipCol = new Array ( nx ) ;
109+ for ( j = 0 ; j < nx ; j ++ ) ipCol [ j ] = [ ] ;
110+ inputPoints . push ( ipCol ) ;
104111 if ( doavg ) counts . push ( zerocol . slice ( ) ) ;
105112 }
106- if ( nonuniformBinsY ) ybins . push ( i ) ;
113+ yEdges . push ( i ) ;
107114
108115 var ny = z . length ;
109116 var y0c = yr2c ( trace . ybins . start ) ;
@@ -121,11 +128,36 @@ module.exports = function calc(gd, trace) {
121128 if ( ! nonuniformBinsY && ya . type === 'date' ) ybins = binsToCalc ( yr2c , ybins ) ;
122129
123130 // put data into bins
131+ var uniqueValsPerX = true ;
132+ var uniqueValsPerY = true ;
133+ var xVals = new Array ( nx ) ;
134+ var yVals = new Array ( ny ) ;
135+ var xGapLow = Infinity ;
136+ var xGapHigh = Infinity ;
137+ var yGapLow = Infinity ;
138+ var yGapHigh = Infinity ;
124139 for ( i = 0 ; i < serieslen ; i ++ ) {
125- n = Lib . findBin ( x [ i ] , xbins ) ;
126- m = Lib . findBin ( y [ i ] , ybins ) ;
140+ var xi = x [ i ] ;
141+ var yi = y [ i ] ;
142+ n = Lib . findBin ( xi , xbins ) ;
143+ m = Lib . findBin ( yi , ybins ) ;
127144 if ( n >= 0 && n < nx && m >= 0 && m < ny ) {
128145 total += binfunc ( n , i , z [ m ] , rawCounterData , counts [ m ] ) ;
146+ inputPoints [ m ] [ n ] . push ( i ) ;
147+
148+ if ( uniqueValsPerX ) {
149+ if ( xVals [ n ] === undefined ) xVals [ n ] = xi ;
150+ else if ( xVals [ n ] !== xi ) uniqueValsPerX = false ;
151+ }
152+ if ( uniqueValsPerY ) {
153+ if ( yVals [ n ] === undefined ) yVals [ n ] = yi ;
154+ else if ( yVals [ n ] !== yi ) uniqueValsPerY = false ;
155+ }
156+
157+ xGapLow = Math . min ( xGapLow , xi - xEdges [ n ] ) ;
158+ xGapHigh = Math . min ( xGapHigh , xEdges [ n + 1 ] - xi ) ;
159+ yGapLow = Math . min ( yGapLow , yi - yEdges [ m ] ) ;
160+ yGapHigh = Math . min ( yGapHigh , yEdges [ m + 1 ] - yi ) ;
129161 }
130162 }
131163 // normalize, if needed
@@ -138,12 +170,15 @@ module.exports = function calc(gd, trace) {
138170
139171 return {
140172 x : x ,
173+ xRanges : getRanges ( xEdges , uniqueValsPerX && xVals , xGapLow , xGapHigh , xa , xcalendar ) ,
141174 x0 : x0 ,
142175 dx : dx ,
143176 y : y ,
177+ yRanges : getRanges ( yEdges , uniqueValsPerY && yVals , yGapLow , yGapHigh , ya , ycalendar ) ,
144178 y0 : y0 ,
145179 dy : dy ,
146- z : z
180+ z : z ,
181+ pts : inputPoints
147182 } ;
148183} ;
149184
@@ -195,3 +230,17 @@ function binsToCalc(r2c, bins) {
195230 size : bins . size
196231 } ;
197232}
233+
234+ function getRanges ( edges , uniqueVals , gapLow , gapHigh , ax , calendar ) {
235+ var i ;
236+ var len = edges . length - 1 ;
237+ var out = new Array ( len ) ;
238+ if ( uniqueVals ) {
239+ for ( i = 0 ; i < len ; i ++ ) out [ i ] = [ uniqueVals [ i ] , uniqueVals [ i ] ] ;
240+ }
241+ else {
242+ var roundFn = getBinSpanLabelRound ( gapLow , gapHigh , edges , ax , calendar ) ;
243+ for ( i = 0 ; i < len ; i ++ ) out [ i ] = [ roundFn ( edges [ i ] ) , roundFn ( edges [ i + 1 ] , true ) ] ;
244+ }
245+ return out ;
246+ }
0 commit comments