import * as d3 from 'd3' ; import * as Utils from '../utils/_index' ; import * as Options from '../options/_index' ; export class EventManager { private _dispatch : d3 . Dispatch < any > ; private data : Utils . Data ; private options : Options . Options ; public strictMode : Boolean = true ; static EVENTS : string [ ] = [ 'create' , 'update' , 'data-update' , 'resize' , 'destroy' , 'enter' , 'over' , 'move' , 'leave' , 'click' , 'dblclick' , 'legend-click' , 'legend-over' , 'legend-out' , 'container-over' , 'container-move' , 'container-out' , 'focus' , 'toggle' , 'outer-world-hover' , 'outer-world-domain-change' , 'pan' , 'pan-end' , 'zoom' , 'zoom-end' , 'zoom-pan-reset' , 'window-mouseup' , 'window-mousemove' , ] ; init ( events ) { this . _dispatch = d3 . dispatch . apply ( this , events ) ; let id = new Date ( ) . getTime ( ) ; d3 . select ( window ) . on ( 'mouseup.' + id , ( ) => { this . trigger ( 'window-mouseup' ) ; } ) ; d3 . select ( window ) . on ( 'mousemove.' + id , ( ) => { this . trigger ( 'window-mousemove' ) ; } ) ; return this ; } update ( data , options ) { this . data = data ; this . options = options ; return ; } on ( event , callback ) { if ( this . strictMode && EventManager . EVENTS . indexOf ( event . split ( '.' ) [ 0 ] ) === - 1 ) { throw new Error ( `Unknown event: ${ event }` ) ; } this . _dispatch . on ( event , callback ) ; return this ; } trigger ( event , ... args ) { this . _dispatch . apply ( event , this , args ) ; return this ; } triggerDataAndOptions ( event , ... args ) { args . push ( this . data ) ; args . push ( this . options ) ; this . _dispatch . apply ( event , this , args ) ; return this ; } datumEnter ( series , options ) { return ( selection ) => { return selection . on ( 'mouseenter' , ( d , i ) => { this . trigger ( 'enter' , d , i , series , options ) ; } ) ; } ; } datumOver ( series , options ) { return ( selection ) => { return selection . on ( 'mouseover' , ( d , i ) => { this . trigger ( 'over' , d , i , series , options ) ; } ) ; } ; } datumMove ( series , options ) { return ( selection ) => { return selection . on ( 'mousemove' , ( d , i ) => { this . trigger ( 'over' , d , i , series , options ) ; } ) ; } ; } datumLeave ( series , options ) { return ( selection ) => { return selection . on ( 'mouseleave' , ( d , i ) => { this . trigger ( 'leave' , d , i , series , options ) ; } ) ; } ; } listenForDblClick ( selection , callback , listenerSuffix ) { let down , tolerance = 5 , last , wait = null ; let dist = ( a , b ) : number => { return Math . sqrt ( Math . pow ( a [ 0 ] - b [ 0 ] , 2 ) + Math . pow ( a [ 1 ] - b [ 1 ] , 2 ) ) ; } ; selection . on ( 'mousedown.dbl.' + listenerSuffix , function ( ) { down = d3 . mouse ( document . body ) ; last = new Date ( ) . getTime ( ) ; } ) ; selection . on ( 'mouseup.dbl.' + listenerSuffix , ( ) => { if ( ! down || dist ( down , d3 . mouse ( document . body ) ) > tolerance ) { return ; } if ( wait && this . options . doubleClickEnabled ) { window . clearTimeout ( wait ) ; wait = null ; callback ( d3 . event ) ; } else { wait = window . setTimeout ( ( function ( e ) { return function ( ) { wait = null ; } ; } ) ( d3 . event ) , 300 ) ; } } ) ; return selection ; } }