import { SceneNode , ScaleCreator , ScaleBuilder } from '@chart-parts/interfaces' ; import { Subject , Subscription } from 'rxjs' ; import { SceneNodeSpec } from '../spec/SceneNodeSpec' ; import { AxisBuilder } from './AxisBuilder' ; import { MarkBuilder } from './MarkBuilder' ; interface SubscribableHandle < T > { item : T ; subscription : Subscription ; } category export class SceneNodeBuilder { public readonly onChange = new Subject < any > ( ) ; public readonly spec = new SceneNodeSpec ( ) ; private markBuilders : Array < SubscribableHandle < MarkBuilder > > = [ ] ; private axisBuilders : Array < SubscribableHandle < AxisBuilder > > = [ ] ; /**
     * The scales defined for children of this node
     */ private scales : ScaleCreator [ ] = [ ] ; param name param table param creator public scale ( ... creators ) { creators . forEach ( c => { const scaleCreator = typeof c === 'function' ? c : c . build ; this . spec . addScale ( scaleCreator ) ; this . scales . push ( scaleCreator ) ; } ) ; this . onChange . next ( 'node add scales' ) ; return this ; } public removeScale ( scale ) { if ( typeof scale === 'function' ) { this . spec . removeScale ( scale ) ; this . scales = this . scales . filter ( s => s !== scale ) ; } else { this . spec . removeScale ( scale . build ) ; this . scales = this . scales . filter ( s => s !== scale . build ) ; } this . onChange . next ( 'node remove scale' ) ; return this ; } public mark ( ... builders ) { builders . forEach ( b => { this . spec . addMark ( b . spec ) ; this . markBuilders . push ( { item : b , subscription : b . onChange . subscribe ( c => this . onChange . next ( c ) ) , } ) ; } ) ; this . onChange . next ( 'node add marks' ) ; return this ; } public removeMark ( builder ) { this . markBuilders = this . markBuilders . filter ( t => { if ( t . item === builder ) { this . spec . removeMark ( t . item . spec ) ; t . subscription . unsubscribe ( ) ; } return t . item !== builder ; } ) ; this . onChange . next ( 'node remove mark' ) ; return this ; } public axes ( ... builders ) { builders . forEach ( b => { this . spec . addAxis ( b . spec ) ; this . axisBuilders . push ( { item : b , subscription : b . onChange . subscribe ( c => this . onChange . next ( c ) ) , } ) ; } ) ; this . onChange . next ( 'node remove axes' ) ; return this ; } public removeAxis ( builder ) { this . axisBuilders = this . axisBuilders . filter ( t => { if ( t . item === builder ) { this . spec . removeAxis ( t . item . spec ) ; t . subscription . unsubscribe ( ) ; } return t . item !== builder ; } ) ; this . onChange . next ( 'node remove axis' ) ; return this ; } /**
     * Builds the scene object
     */ public build ( ) { return this . spec ; } }