11import { group } from "d3-array" ;
22import { create } from "d3-selection" ;
3- import { Mark , indexOf } from "../mark.js" ;
3+ import { Mark } from "../mark.js" ;
44import { autoScaleRange } from "../scales.js" ;
55
66export class FacetY extends Mark {
@@ -12,32 +12,66 @@ export class FacetY extends Mark {
1212 ]
1313 ) ;
1414 this . marks = marks ;
15+ this . facets = undefined ; // set by initialize
1516 }
16- initialize ( ) {
17- return [
18- ...super . initialize ( ) ,
19- ...this . marks . flatMap ( m => m . initialize ( ) . map ( facetYChannel ) )
20- ] ;
17+ initialize ( data ) {
18+ const { index, channels : [ y ] } = super . initialize ( data ) ;
19+ const [ , { value : Y } ] = y ;
20+ const subchannels = [ ] ;
21+ const facets = this . facets = new Map ( ) ;
22+
23+ //
24+ for ( const [ facetKey , facetIndex ] of group ( index , ( d , i ) => Y [ i ] ) ) {
25+ const facetData = Array . from ( facetIndex , i => data [ i ] ) ;
26+ const markIndex = new Map ( ) ;
27+ const markChannels = new Map ( ) ;
28+ for ( const mark of this . marks ) {
29+ if ( markIndex . has ( mark ) ) throw new Error ( "duplicate mark" ) ;
30+ const markData = mark . data === data ? facetData : mark . data ;
31+ const named = Object . create ( null ) ;
32+ const { index, channels} = mark . initialize ( markData ) ;
33+ for ( const [ name , channel ] of channels ) {
34+ if ( name !== undefined ) named [ name ] = channel . value ;
35+ subchannels . push ( [ undefined , facetYChannel ( channel ) ] ) ;
36+ }
37+ markIndex . set ( mark , index ) ;
38+ markChannels . set ( mark , named ) ;
39+ }
40+ facets . set ( facetKey , { markIndex, markChannels} ) ;
41+ }
42+
43+ return { index, channels : [ y , ...subchannels ] } ;
2144 }
22- render ( I , { y, fy, ...scales } , dimensions ) {
23- const { data, marks, channels : { y : { value : Y } } } = this ;
45+ render ( index , { y, fy, ...scales } , channels , options ) {
46+ const { marks, facets} = this ;
47+ const { marginRight, marginLeft, width} = options ;
2448 const subscales = { y : fy , ...scales } ;
25- const subdimensions = { ...dimensions , marginTop : 0 , marginBottom : 0 , height : y . bandwidth ( ) } ;
26- const G = group ( I , i => Y [ i ] ) ;
2749
28- autoScaleRange ( { y : fy } , subdimensions ) ;
50+ const subdimensions = {
51+ marginTop : 0 ,
52+ marginRight,
53+ marginBottom : 0 ,
54+ marginLeft,
55+ width,
56+ height : y . bandwidth ( )
57+ } ;
58+
59+ autoScaleRange ( { y : options . scales . fy } , subdimensions ) ;
2960
3061 return create ( "svg:g" )
3162 . call ( g => g . selectAll ( )
3263 . data ( y . domain ( ) )
3364 . join ( "g" )
3465 . attr ( "transform" , ( key ) => `translate(0,${ y ( key ) } )` )
3566 . each ( function ( key ) {
67+ const { markIndex, markChannels} = facets . get ( key ) ;
3668 for ( const mark of marks ) {
37- const index = mark . data === data ? G . get ( key )
38- : mark . data === undefined ? undefined
39- : Array . from ( mark . data , indexOf ) ;
40- const node = mark . render ( index , subscales , subdimensions ) ;
69+ const node = mark . render (
70+ markIndex . get ( mark ) ,
71+ subscales ,
72+ markChannels . get ( mark ) ,
73+ subdimensions
74+ ) ;
4175 if ( node != null ) this . appendChild ( node ) ;
4276 }
4377 } ) )
@@ -49,7 +83,6 @@ export function facetY(data, channels, marks) {
4983 return new FacetY ( data , channels , marks ) ;
5084}
5185
52- function facetYChannel ( [ name , { scale, ...channel } ] ) {
53- name ; // TODO Retrieve each mark’s channels.
54- return [ undefined , { ...channel , scale : scale === "y" ? "fy" : scale } ] ;
86+ function facetYChannel ( { scale, ...channel } ) {
87+ return { ...channel , scale : scale === "y" ? "fy" : scale } ;
5588}
0 commit comments