1
1
import { InternMap } from "d3-array" ;
2
- import { valueof } from "../mark" ;
2
+ import { valueof } from "../mark.js " ;
3
3
4
4
export function stackX ( { x, y, ...options } ) {
5
5
const [ transform , Y , x1 , x2 ] = stack ( y , x ) ;
@@ -13,15 +13,17 @@ export function stackY({x, y, ...options}) {
13
13
14
14
// TODO configurable series order
15
15
function stack ( x , y ) {
16
- let X , Y1 , Y2 ;
16
+ const [ X , setX ] = lazyChannel ( x ) ;
17
+ const [ Y1 , setY1 ] = lazyChannel ( y ) ;
18
+ const [ Y2 , setY2 ] = lazyChannel ( y ) ;
17
19
return [
18
20
data => {
19
- X = valueof ( data , x ) ;
21
+ const X = setX ( valueof ( data , x ) ) ;
20
22
const Y = valueof ( data , y ) ;
21
23
const n = X . length ;
22
24
const Y0 = new InternMap ( ) ;
23
- Y1 = new Float64Array ( n ) ;
24
- Y2 = new Float64Array ( n ) ;
25
+ const Y1 = setY1 ( new Float64Array ( n ) ) ;
26
+ const Y2 = setY2 ( new Float64Array ( n ) ) ;
25
27
for ( let i = 0 ; i < n ; ++ i ) {
26
28
const k = X [ i ] ;
27
29
const y1 = Y1 [ i ] = Y0 . has ( k ) ? Y0 . get ( k ) : 0 ;
@@ -30,16 +32,24 @@ function stack(x, y) {
30
32
}
31
33
return data ;
32
34
} ,
33
- transform ( ( ) => X , x ) ,
34
- transform ( ( ) => Y1 , y ) ,
35
- transform ( ( ) => Y2 )
35
+ X ,
36
+ Y1 ,
37
+ Y2
36
38
] ;
37
39
}
38
40
39
- // If x is labeled, propagate the label to the returned channel transform.
40
- function transform ( transform , x ) {
41
- return {
42
- transform,
43
- label : typeof x === "string" ? x : x ? x . label : undefined
44
- } ;
41
+ // Defines a channel whose values are lazily populated by calling the returned
42
+ // setter. If the given source is labeled, the label is propagated to the
43
+ // returned channel definition.
44
+ function lazyChannel ( source ) {
45
+ let value ;
46
+ return [
47
+ {
48
+ transform ( ) { return value ; } ,
49
+ label : typeof source === "string" ? source
50
+ : source ? source . label
51
+ : undefined
52
+ } ,
53
+ v => value = v
54
+ ] ;
45
55
}
0 commit comments