1
+ import { valueObject } from "../channel.js" ;
1
2
import { coerceNumbers } from "../scales.js" ;
2
3
import { sqrt3 } from "../symbols.js" ;
3
- import { identity , isNoneish , number , valueof } from "../options.js" ;
4
+ import { isNoneish , number , valueof } from "../options.js" ;
4
5
import { initializer } from "./basic.js" ;
5
6
import { hasOutput , maybeGroup , maybeOutputs , maybeSubgroup } from "./group.js" ;
6
7
@@ -13,32 +14,34 @@ export const ox = 0.5,
13
14
oy = 0 ;
14
15
15
16
/** @jsdoc hexbin */
16
- export function hexbin ( outputs = { fill : "count" } , options = { } ) {
17
+ export function hexbin ( outputs = { fill : "count" } , { binWidth , ... options } = { } ) {
17
18
// TODO filter e.g. to show empty hexbins?
18
19
// TODO disallow x, x1, x2, y, y1, y2 reducers?
19
- let { binWidth, ...remainingOptions } = options ;
20
20
binWidth = binWidth === undefined ? 20 : number ( binWidth ) ;
21
- outputs = maybeOutputs ( outputs , remainingOptions ) ;
21
+ outputs = maybeOutputs ( outputs , options ) ;
22
22
23
23
// A fill output means a fill channel, and hence the stroke should default to
24
24
// none (assuming a mark that defaults to fill and no stroke, such as dot).
25
25
// Note that it’s safe to mutate options here because we just created it with
26
26
// the rest operator above.
27
- const { z, fill, stroke} = remainingOptions ;
28
- if ( stroke === undefined && isNoneish ( fill ) && hasOutput ( outputs , "fill" ) ) remainingOptions . stroke = "none" ;
27
+ const { z, fill, stroke} = options ;
28
+ if ( stroke === undefined && isNoneish ( fill ) && hasOutput ( outputs , "fill" ) ) options . stroke = "none" ;
29
29
30
30
// Populate default values for the r and symbol options, as appropriate.
31
- if ( remainingOptions . symbol === undefined ) remainingOptions . symbol = "hexagon" ;
32
- if ( remainingOptions . r === undefined && ! hasOutput ( outputs , "r" ) ) remainingOptions . r = binWidth / 2 ;
31
+ if ( options . symbol === undefined ) options . symbol = "hexagon" ;
32
+ if ( options . r === undefined && ! hasOutput ( outputs , "r" ) ) options . r = binWidth / 2 ;
33
33
34
- return initializer ( remainingOptions , ( data , facets , { x : X , y : Y , z : Z , fill : F , stroke : S , symbol : Q } , scales ) => {
34
+ return initializer ( options , ( data , facets , { x : X , y : Y , z : Z , fill : F , stroke : S , symbol : Q } , scales , _ , context ) => {
35
35
if ( X === undefined ) throw new Error ( "missing channel: x" ) ;
36
36
if ( Y === undefined ) throw new Error ( "missing channel: y" ) ;
37
37
38
- // Coerce the X and Y channels to numbers (so that null is properly treated
39
- // as an undefined value rather than being coerced to zero).
40
- X = coerceNumbers ( valueof ( X . value , scales [ X . scale ] || identity ) ) ;
41
- Y = coerceNumbers ( valueof ( Y . value , scales [ Y . scale ] || identity ) ) ;
38
+ // Extract the scaled (or projected!) values for the x and y channels.
39
+ ( { x : X , y : Y } = valueObject ( { x : X , y : Y } , scales , context ) ) ;
40
+
41
+ // Coerce the x and y channels to numbers (so that null is properly
42
+ // treated as an undefined value rather than being coerced to zero).
43
+ X = coerceNumbers ( X ) ;
44
+ Y = coerceNumbers ( Y ) ;
42
45
43
46
// Extract the values for channels that are eligible for grouping; not all
44
47
// marks define a z channel, so compute one if it not already computed. If z
0 commit comments