1- import { bin as binner , extent , thresholdFreedmanDiaconis , thresholdScott , thresholdSturges , utcTickInterval } from "d3" ;
1+ import { bisect , extent , thresholdFreedmanDiaconis , thresholdScott , thresholdSturges , ticks , utcTickInterval } from "d3" ;
22import {
33 valueof ,
4- range ,
54 identity ,
65 maybeColumn ,
76 maybeInterval ,
@@ -11,7 +10,8 @@ import {
1110 mid ,
1211 labelof ,
1312 isTemporal ,
14- isIterable
13+ isIterable ,
14+ map
1515} from "../options.js" ;
1616import { coerceDate , coerceNumber } from "../scales.js" ;
1717import { basic } from "./basic.js" ;
@@ -147,8 +147,8 @@ function binn(
147147 const GZ = Z && setGZ ( [ ] ) ;
148148 const GF = F && setGF ( [ ] ) ;
149149 const GS = S && setGS ( [ ] ) ;
150- const BX = bx ? bx ( data ) : [ [ , , ( I ) => I ] ] ;
151- const BY = by ? by ( data ) : [ [ , , ( I ) => I ] ] ;
150+ const BX = bx ?. ( data ) ;
151+ const BY = by ?. ( data ) ;
152152 const BX1 = bx && setBX1 ( [ ] ) ;
153153 const BX2 = bx && setBX2 ( [ ] ) ;
154154 const BY1 = by && setBY1 ( [ ] ) ;
@@ -164,24 +164,34 @@ function binn(
164164 if ( filter ) filter . scope ( "facet" , facet ) ;
165165 for ( const [ f , I ] of maybeGroup ( facet , G ) ) {
166166 for ( const [ k , g ] of maybeGroup ( I , K ) ) {
167- for ( const [ x1 , x2 , fx ] of BX ) {
168- const bb = fx ( g ) ;
169- for ( const [ y1 , y2 , fy ] of BY ) {
170- const extent = { x1, x2, y1, y2} ;
171- const b = fy ( bb ) ;
172- if ( filter && ! filter . reduce ( b , extent ) ) continue ;
173- groupFacet . push ( i ++ ) ;
174- groupData . push ( reduceData . reduce ( b , data , extent ) ) ;
175- if ( K ) GK . push ( k ) ;
176- if ( Z ) GZ . push ( G === Z ? f : Z [ b [ 0 ] ] ) ;
177- if ( F ) GF . push ( G === F ? f : F [ b [ 0 ] ] ) ;
178- if ( S ) GS . push ( G === S ? f : S [ b [ 0 ] ] ) ;
179- if ( BX1 ) BX1 . push ( x1 ) , BX2 . push ( x2 ) ;
180- if ( BY1 ) BY1 . push ( y1 ) , BY2 . push ( y2 ) ;
181- for ( const o of outputs ) o . reduce ( b , extent ) ;
182- if ( sort ) sort . reduce ( b ) ;
183- }
167+ const B = new Array ( BX . length ) ;
168+ for ( const i of g ) {
169+ const xi = BX . bin ( i ) ;
170+ if ( B [ xi ] ) B [ xi ] . push ( i ) ;
171+ else B [ xi ] = [ i ] ;
184172 }
173+ for ( const [ xi , [ x1 , x2 ] ] of BX . entries ( ) ) {
174+ const extent = { x1, x2, y1, y2} ;
175+ const b = B [ xi ] ; //fy(bb);
176+ if ( ! b ) continue ;
177+ // if (filter && !filter.reduce(b, extent)) continue;
178+ groupFacet . push ( i ++ ) ;
179+ // groupData.push(reduceData.reduce(b, data, extent));
180+ groupData . push ( undefined ) ;
181+ if ( K ) GK . push ( k ) ;
182+ if ( Z ) GZ . push ( G === Z ? f : Z [ b [ 0 ] ] ) ;
183+ if ( F ) GF . push ( G === F ? f : F [ b [ 0 ] ] ) ;
184+ if ( S ) GS . push ( G === S ? f : S [ b [ 0 ] ] ) ;
185+ if ( BX1 ) BX1 . push ( x1 ) , BX2 . push ( x2 ) ;
186+ if ( BY1 ) BY1 . push ( y1 ) , BY2 . push ( y2 ) ;
187+ for ( const o of outputs ) o . reduce ( b , extent ) ;
188+ if ( sort ) sort . reduce ( b ) ;
189+ }
190+ // for (const [x1, x2, fx] of BX) {
191+ // const bb = fx(g);
192+ // for (const [y1, y2, fy] of BY) {
193+ // }
194+ // }
185195 }
186196 }
187197 groupFacets . push ( groupFacet ) ;
@@ -224,10 +234,12 @@ function maybeBin(options) {
224234 if ( options == null ) return ;
225235 const { value, cumulative, domain = extent , thresholds} = options ;
226236 const bin = ( data ) => {
227- let V = valueof ( data , value , Array ) ; // d3.bin prefers Array input
228- const bin = binner ( ) . value ( ( i ) => V [ i ] ) ;
237+ let V = valueof ( data , value ) ;
238+ let T ;
239+ // const bin = binner().value((i) => V[i]);
229240 if ( isTemporal ( V ) || isTimeThresholds ( thresholds ) ) {
230- V = V . map ( coerceDate ) ;
241+ // V = V.map(coerceDate);
242+ V = map ( V , coerceDate , Float64Array ) ;
231243 let [ min , max ] = typeof domain === "function" ? domain ( V ) : domain ;
232244 let t = typeof thresholds === "function" && ! isInterval ( thresholds ) ? thresholds ( V , min , max ) : thresholds ;
233245 if ( typeof t === "number" ) t = utcTickInterval ( min , max , t ) ;
@@ -238,25 +250,39 @@ function maybeBin(options) {
238250 }
239251 t = t . range ( min , max ) ;
240252 }
241- bin . thresholds ( t ) . domain ( [ min , max ] ) ;
253+ T = t ;
242254 } else {
243- V = V . map ( coerceNumber ) ;
244- let d = domain ;
245- let t = thresholds ;
246- if ( isInterval ( t ) ) {
247- let [ min , max ] = typeof d === "function" ? d ( V ) : d ;
248- if ( d === extent ) {
255+ // V = V.map(coerceNumber);
256+ V = map ( V , coerceNumber , Float64Array ) ;
257+ let [ min , max ] = typeof domain === "function" ? domain ( V ) : domain ;
258+ let t = typeof thresholds === "function" && ! isInterval ( thresholds ) ? thresholds ( V , min , max ) : thresholds ;
259+ if ( typeof t === "number" ) t = ticks ( min , max , t ) ;
260+ else if ( isInterval ( t ) ) {
261+ if ( domain === extent ) {
249262 min = t . floor ( min ) ;
250263 max = t . offset ( t . floor ( max ) ) ;
251- d = [ min , max ] ;
252264 }
253265 t = t . range ( min , max ) ;
254266 }
255- bin . thresholds ( t ) . domain ( d ) ;
267+ T = t ;
268+ // bin.thresholds(t).domain(d);
269+ }
270+ // let bins = bin(range(data)).map(binset);
271+ // if (cumulative) bins = (cumulative < 0 ? bins.reverse() : bins).map(bincumset);
272+ // return bins.map(binfilter);
273+ const bins = [ ] ;
274+ for ( let i = 0 ; i <= T . length ; ++ i ) {
275+ bins . push ( [ T [ i - 1 ] , T [ i ] ] ) ;
256276 }
257- let bins = bin ( range ( data ) ) . map ( binset ) ;
258- if ( cumulative ) bins = ( cumulative < 0 ? bins . reverse ( ) : bins ) . map ( bincumset ) ;
259- return bins . map ( binfilter ) ;
277+ // bin.thresholds(t).domain([min, max]);
278+ T = T . map ( coerceNumber ) ;
279+ // V = V.map(coerceNumber);
280+ bins . bin = ( i ) => {
281+ let x = V [ i ] ;
282+ if ( x == null ) return - 1 ; // TODO non-comparable?
283+ return bisect ( T , x , 0 , T . length ) ;
284+ } ;
285+ return bins ;
260286 } ;
261287 bin . label = labelof ( value ) ;
262288 return bin ;
0 commit comments