import { Scales , DataFrame , ChannelNames , SceneNode , ScaleCreationContext , ChannelHandler , Channels , ViewSize , Mark , } from '@chart-parts/interfaces' ; ignore export class SceneFrame { public constructor ( public node , public mark , public data , public view , public viewTL = [ 0 , 0 ] , public viewBR = [ view . height , view . width ] , public scales = { } , public channels = { } , public channelId = 0 , public channelHandlers = { } , public boundDataItem = { } , public parentId = '' ) { } /**
     * Pushes a new scene frame with a given scene node; recomputes scales.
     */ public pushNode ( node ) { const scales = this . getRecomputedScales ( node , this . viewTL , this . viewBR ) ; return new SceneFrame ( node , undefined , this . data , this . view , this . viewTL , this . viewBR , scales , { } , this . channelId , this . channelHandlers , this . boundDataItem , this . parentId ) ; } /**
     * Pushes a new mark context.
     */ public pushMark ( mark ) { const channels = this . registerChannels ( mark . channels ) ; return new SceneFrame ( this . node , mark , this . data , this . view , this . viewTL , this . viewBR , this . scales , channels , this . channelId , this . channelHandlers , this . boundDataItem , `${ this . parentId }.${ mark . name || mark . type }` ) ; } param data param facetKey public pushData ( data , facetKey ? ) { const dataFrame = { ... this . data , ... data } ; const id = facetKey ? `${ this . parentId }.facet(${ facetKey })` : this . parentId ; return new SceneFrame ( this . node , this . mark , dataFrame , this . view , this . viewTL , this . viewBR , this . scales , this . channels , this . channelId , this . channelHandlers , this . boundDataItem , id ) ; } param view param viewTL param viewBR public pushView ( view , viewTL = [ 0 , 0 ] , viewBR = [ view . height , view . width ] ) { if ( areViewSizesEqual ( view , this . view ) && areCoordsEqual ( viewTL , this . viewTL ) ) { return this ; } const scales = this . getRecomputedScales ( this . node , viewTL , viewBR ) ; return new SceneFrame ( this . node , this . mark , this . data , view , viewTL , viewBR , scales , this . channels , this . channelId , this . channelHandlers , this . boundDataItem , this . parentId ) ; } param dataItem public pushBoundDataItem ( dataItem ) { return new SceneFrame ( this . node , this . mark , this . data , this . view , this . viewTL , this . viewBR , this . scales , this . channels , this . channelId , this . channelHandlers , dataItem , this . parentId ) ; } private getRecomputedScales ( node , viewTL , viewBR ) { const scales = { ... this . scales } ; const ctx = { view : this . view , data : this . data , viewBounds : { x : [ viewTL [ 1 ] , viewBR [ 1 ] ] , y : [ viewBR [ 0 ] , viewTL [ 0 ] ] } , scales , } ; node . scales . forEach ( s => Object . assign ( scales , s ( ctx ) ) ) ; return scales ; } private registerChannels ( channels ) { const result = { } as ChannelNames ; Object . keys ( channels ) . forEach ( eventName => { result [ eventName ] = this . registerHandler ( eventName , channels [ eventName ] ) ; } ) ; return result ; } private registerHandler ( eventName , handler ) { const id = `evt_${ this . channelId ++ }` ; this . channelHandlers [ id ] = handler ; return id ; } } function areViewSizesEqual ( a , b ) { return a . height === b . height && a . width === b . width ; } function areCoordsEqual ( a , b ) { return a [ 0 ] === b [ 0 ] && a [ 1 ] === b [ 1 ] ; }