import { each , isString } from '@antv/util' ; import { Item , States } from '../../types' ; import { IAbstractGraph } from '../../interface/graph' ; import { INode } from '../../interface/item' ; interface CachedStates { enabled : States ; disabled : States ; } let timer = null ; export default class StateController { private graph : IAbstractGraph ; private cachedStates : CachedStates ; public destroyed : boolean ; constructor ( graph ) { this . graph = graph ; /**
         * this.cachedStates = {
         *    enabled: {
         *        hover: [Node]
         *    },
         *     disabled: {}
         *  }
         */ this . cachedStates = { enabled : { } , disabled : { } , } ; this . destroyed = false ; } private param { Item } item param { string } state param { object } cache returns memberof private static checkCache ( item , state , cache ) { if ( ! cache [ state ] ) { return ; } const index = cache [ state ] . indexOf ( item ) ; if ( index >= 0 ) { cache [ state ] . splice ( index , 1 ) ; } } private param { Item } item param { string } state param { object } states memberof private static cacheState ( item , state , states ) { if ( ! states [ state ] ) { states [ state ] = [ ] ; } states [ state ] . push ( item as INode ) ; } param { Item } item param { string } state param { boolean } enabled memberof public updateState ( item , state , enabled ) { const { checkCache , cacheState } = StateController ; if ( item . destroyed ) { return ; } const { cachedStates } = this ; const enabledStates = cachedStates . enabled ; const disabledStates = cachedStates . disabled ; if ( enabled ) { checkCache ( item , state , disabledStates ) ; cacheState ( item , state , enabledStates ) ; } else { checkCache ( item , state , enabledStates ) ; cacheState ( item , state , disabledStates ) ; } if ( timer ) { clearTimeout ( timer ) ; } timer = setTimeout ( ( ) => { timer = null ; this . updateGraphStates ( ) ; } , 16 ) ; } param { Item } item param { ( string | string [ ] ) } states param { boolean } enabled memberof public updateStates ( item , states , enabled ) { if ( isString ( states ) ) { this . updateState ( item , states , enabled ) ; } else { states . forEach ( ( state ) => { this . updateState ( item , state , enabled ) ; } ) ; } } memberof public updateGraphStates ( ) { const states = this . graph . get ( 'states' ) as States ; const { cachedStates } = this ; each ( cachedStates . disabled , ( val , key ) => { if ( states [ key ] ) { states [ key ] = states [ key ] . filter ( ( item ) => val . indexOf ( item ) < 0 && ! val . destroyed ) ; } } ) ; each ( cachedStates . enabled , ( val , key ) => { if ( ! states [ key ] ) { states [ key ] = val ; } else { const map = { } ; states [ key ] . forEach ( ( item ) => { if ( ! item . destroyed ) { map [ item . get ( 'id' ) ] = true ; } } ) ; val . forEach ( ( item ) => { if ( ! item . destroyed ) { const id = item . get ( 'id' ) ; if ( ! map [ id ] ) { map [ id ] = true ; states [ key ] . push ( item as INode ) ; } } } ) ; } } ) ; this . graph . emit ( 'graphstatechange' , { states } ) ; this . cachedStates = { enabled : { } , disabled : { } , } ; } public destroy ( ) { ( this . graph as IAbstractGraph | null ) = null ; ( this . cachedStates as CachedStates | null ) = null ; if ( timer ) { clearTimeout ( timer ) ; } timer = null ; this . destroyed = true ; } }