1
1
import { InternMap , cross , rollup , sum } from "d3" ;
2
- import { range } from "./options.js" ;
2
+ import { keyof , map , range } from "./options.js" ;
3
3
import { createScales } from "./scales.js" ;
4
4
5
5
// Returns an array of {x?, y?, i} objects representing the facet domain.
@@ -17,8 +17,8 @@ export function createFacets(channelsByScale, options) {
17
17
}
18
18
19
19
export function recreateFacets ( facets , { x : X , y : Y } ) {
20
- X &&= new InternMap ( X . map ( ( x , i ) => [ x , i ] ) ) ;
21
- Y &&= new InternMap ( Y . map ( ( y , i ) => [ y , i ] ) ) ;
20
+ X &&= facetIndex ( X ) ;
21
+ Y &&= facetIndex ( Y ) ;
22
22
return facets
23
23
. filter (
24
24
X && Y // remove any facets no longer present in the domain
@@ -110,56 +110,72 @@ export function maybeFacetAnchor(facetAnchor) {
110
110
throw new Error ( `invalid facet anchor: ${ facetAnchor } ` ) ;
111
111
}
112
112
113
+ const indexCache = new WeakMap ( ) ;
114
+
115
+ function facetIndex ( V ) {
116
+ let I = indexCache . get ( V ) ;
117
+ if ( ! I ) indexCache . set ( V , ( I = new InternMap ( map ( V , ( v , i ) => [ v , i ] ) ) ) ) ;
118
+ return I ;
119
+ }
120
+
121
+ // Like V.indexOf(v), but with the same semantics as InternMap.
122
+ function facetIndexOf ( V , v ) {
123
+ return facetIndex ( V ) . get ( v ) ;
124
+ }
125
+
126
+ // Like facets.find, but with the same semantics as InternMap.
127
+ function facetFind ( facets , x , y ) {
128
+ x = keyof ( x ) ;
129
+ y = keyof ( y ) ;
130
+ return facets . find ( ( f ) => Object . is ( keyof ( f . x ) , x ) && Object . is ( keyof ( f . y ) , y ) ) ;
131
+ }
132
+
133
+ function facetEmpty ( facets , x , y ) {
134
+ return facetFind ( facets , x , y ) ?. empty ;
135
+ }
136
+
113
137
function facetAnchorTop ( facets , { y : Y } , { y} ) {
114
- return Y ? Y . indexOf ( y ) === 0 : true ;
138
+ return Y ? facetIndexOf ( Y , y ) === 0 : true ;
115
139
}
116
140
117
141
function facetAnchorBottom ( facets , { y : Y } , { y} ) {
118
- return Y ? Y . indexOf ( y ) === Y . length - 1 : true ;
142
+ return Y ? facetIndexOf ( Y , y ) === Y . length - 1 : true ;
119
143
}
120
144
121
145
function facetAnchorLeft ( facets , { x : X } , { x} ) {
122
- return X ? X . indexOf ( x ) === 0 : true ;
146
+ return X ? facetIndexOf ( X , x ) === 0 : true ;
123
147
}
124
148
125
149
function facetAnchorRight ( facets , { x : X } , { x} ) {
126
- return X ? X . indexOf ( x ) === X . length - 1 : true ;
150
+ return X ? facetIndexOf ( X , x ) === X . length - 1 : true ;
127
151
}
128
152
129
153
function facetAnchorTopEmpty ( facets , { y : Y } , { x, y, empty} ) {
130
154
if ( empty ) return false ;
131
- const i = Y ?. indexOf ( y ) ;
132
- if ( i > 0 ) {
133
- const y = Y [ i - 1 ] ;
134
- return facets . find ( ( f ) => f . x === x && f . y === y ) ?. empty ;
135
- }
155
+ if ( ! Y ) return ;
156
+ const i = facetIndexOf ( Y , y ) ;
157
+ if ( i > 0 ) return facetEmpty ( facets , x , Y [ i - 1 ] ) ;
136
158
}
137
159
138
160
function facetAnchorBottomEmpty ( facets , { y : Y } , { x, y, empty} ) {
139
161
if ( empty ) return false ;
140
- const i = Y ?. indexOf ( y ) ;
141
- if ( i < Y ?. length - 1 ) {
142
- const y = Y [ i + 1 ] ;
143
- return facets . find ( ( f ) => f . x === x && f . y === y ) ?. empty ;
144
- }
162
+ if ( ! Y ) return ;
163
+ const i = facetIndexOf ( Y , y ) ;
164
+ if ( i < Y . length - 1 ) return facetEmpty ( facets , x , Y [ i + 1 ] ) ;
145
165
}
146
166
147
167
function facetAnchorLeftEmpty ( facets , { x : X } , { x, y, empty} ) {
148
168
if ( empty ) return false ;
149
- const i = X ?. indexOf ( x ) ;
150
- if ( i > 0 ) {
151
- const x = X [ i - 1 ] ;
152
- return facets . find ( ( f ) => f . x === x && f . y === y ) ?. empty ;
153
- }
169
+ if ( ! X ) return ;
170
+ const i = facetIndexOf ( X , x ) ;
171
+ if ( i > 0 ) return facetEmpty ( facets , X [ i - 1 ] , y ) ;
154
172
}
155
173
156
174
function facetAnchorRightEmpty ( facets , { x : X } , { x, y, empty} ) {
157
175
if ( empty ) return false ;
158
- const i = X ?. indexOf ( x ) ;
159
- if ( i < X ?. length - 1 ) {
160
- const x = X [ i + 1 ] ;
161
- return facets . find ( ( f ) => f . x === x && f . y === y ) ?. empty ;
162
- }
176
+ if ( ! X ) return ;
177
+ const i = facetIndexOf ( X , x ) ;
178
+ if ( i < X . length - 1 ) return facetEmpty ( facets , X [ i + 1 ] , y ) ;
163
179
}
164
180
165
181
function facetAnchorEmpty ( facets , channels , { empty} ) {
0 commit comments