11import { deviation , max , min , median , mode , variance } from "d3" ;
22import { defined } from "../defined.js" ;
3- import { percentile , take } from "../options.js" ;
3+ import { percentile , taker } from "../options.js" ;
44import { warn } from "../warnings.js" ;
55import { mapX , mapY } from "./map.js" ;
66
@@ -51,24 +51,24 @@ function maybeShift(shift) {
5151
5252function maybeReduce ( reduce = "mean" ) {
5353 if ( typeof reduce === "string" ) {
54- if ( / ^ p \d { 2 } $ / i. test ( reduce ) ) return reduceNumbers ( percentile ( reduce ) ) ;
54+ if ( / ^ p \d { 2 } $ / i. test ( reduce ) ) return reduceAccessor ( percentile ( reduce ) ) ;
5555 switch ( reduce . toLowerCase ( ) ) {
5656 case "deviation" :
57- return reduceNumbers ( deviation ) ;
57+ return reduceAccessor ( deviation ) ;
5858 case "max" :
59- return reduceArray ( max ) ;
59+ return reduceArray ( ( I , V ) => max ( I , ( i ) => V [ i ] ) ) ;
6060 case "mean" :
6161 return reduceMean ;
6262 case "median" :
63- return reduceNumbers ( median ) ;
63+ return reduceAccessor ( median ) ;
6464 case "min" :
65- return reduceArray ( min ) ;
65+ return reduceArray ( ( I , V ) => min ( I , ( i ) => V [ i ] ) ) ;
6666 case "mode" :
67- return reduceArray ( mode ) ;
67+ return reduceArray ( ( I , V ) => mode ( I , ( i ) => V [ i ] ) ) ;
6868 case "sum" :
6969 return reduceSum ;
7070 case "variance" :
71- return reduceNumbers ( variance ) ;
71+ return reduceAccessor ( variance ) ;
7272 case "difference" :
7373 return reduceDifference ;
7474 case "ratio" :
@@ -80,7 +80,7 @@ function maybeReduce(reduce = "mean") {
8080 }
8181 }
8282 if ( typeof reduce !== "function" ) throw new Error ( `invalid reduce: ${ reduce } ` ) ;
83- return reduceArray ( reduce ) ;
83+ return reduceArray ( taker ( reduce ) ) ;
8484}
8585
8686function slice ( I , i , j ) {
@@ -91,29 +91,29 @@ function slice(I, i, j) {
9191// function f to handle that itself (e.g., by filtering as needed). The D3
9292// reducers (e.g., min, max, mean, median) do, and it’s faster to avoid
9393// redundant filtering.
94- function reduceNumbers ( f ) {
94+ function reduceAccessor ( f ) {
9595 return ( k , s , strict ) =>
9696 strict
9797 ? {
9898 mapIndex ( I , S , T ) {
99- const C = Float64Array . from ( I , ( i ) => ( S [ i ] === null ? NaN : S [ i ] ) ) ;
99+ const s = ( i ) => ( S [ i ] == null ? NaN : + S [ i ] ) ;
100100 let nans = 0 ;
101- for ( let i = 0 ; i < k - 1 ; ++ i ) if ( isNaN ( C [ i ] ) ) ++ nans ;
101+ for ( let i = 0 ; i < k - 1 ; ++ i ) if ( isNaN ( s ( i ) ) ) ++ nans ;
102102 for ( let i = 0 , n = I . length - k + 1 ; i < n ; ++ i ) {
103- if ( isNaN ( C [ i + k - 1 ] ) ) ++ nans ;
104- T [ I [ i + s ] ] = nans === 0 ? f ( C . subarray ( i , i + k ) ) : NaN ;
105- if ( isNaN ( C [ i ] ) ) -- nans ;
103+ if ( isNaN ( s ( i + k - 1 ) ) ) ++ nans ;
104+ T [ I [ i + s ] ] = nans === 0 ? f ( slice ( I , i , i + k ) , s ) : NaN ;
105+ if ( isNaN ( s ( i ) ) ) -- nans ;
106106 }
107107 }
108108 }
109109 : {
110110 mapIndex ( I , S , T ) {
111- const C = Float64Array . from ( I , ( i ) => ( S [ i ] === null ? NaN : S [ i ] ) ) ;
111+ const s = ( i ) => ( S [ i ] == null ? NaN : + S [ i ] ) ;
112112 for ( let i = - s ; i < 0 ; ++ i ) {
113- T [ I [ i + s ] ] = f ( C . subarray ( 0 , i + k ) ) ;
113+ T [ I [ i + s ] ] = f ( slice ( I , 0 , i + k ) , s ) ;
114114 }
115115 for ( let i = 0 , n = I . length - s ; i < n ; ++ i ) {
116- T [ I [ i + s ] ] = f ( C . subarray ( i , i + k ) ) ;
116+ T [ I [ i + s ] ] = f ( slice ( I , i , i + k ) , s ) ;
117117 }
118118 }
119119 } ;
@@ -128,18 +128,18 @@ function reduceArray(f) {
128128 for ( let i = 0 ; i < k - 1 ; ++ i ) count += defined ( S [ I [ i ] ] ) ;
129129 for ( let i = 0 , n = I . length - k + 1 ; i < n ; ++ i ) {
130130 count += defined ( S [ I [ i + k - 1 ] ] ) ;
131- if ( count === k ) T [ I [ i + s ] ] = f ( take ( S , slice ( I , i , i + k ) ) ) ;
131+ if ( count === k ) T [ I [ i + s ] ] = f ( slice ( I , i , i + k ) , S ) ;
132132 count -= defined ( S [ I [ i ] ] ) ;
133133 }
134134 }
135135 }
136136 : {
137137 mapIndex ( I , S , T ) {
138138 for ( let i = - s ; i < 0 ; ++ i ) {
139- T [ I [ i + s ] ] = f ( take ( S , slice ( I , 0 , i + k ) ) ) ;
139+ T [ I [ i + s ] ] = f ( slice ( I , 0 , i + k ) , S ) ;
140140 }
141141 for ( let i = 0 , n = I . length - s ; i < n ; ++ i ) {
142- T [ I [ i + s ] ] = f ( take ( S , slice ( I , i , i + k ) ) ) ;
142+ T [ I [ i + s ] ] = f ( slice ( I , i , i + k ) , S ) ;
143143 }
144144 }
145145 } ;
0 commit comments