import * as d3 from 'd3' ; import * as Utils from '../utils/_index' ; import * as Options from '../options/_index' ; import { BaseFactory } from './BaseFactory' ; import { Axis } from './Axis' ; export interface ICoordinates { x ? : number | Date ; y ? : number ; } export class Container extends BaseFactory { public defs : d3 . Selection < any , any , any , any > ; public svg : d3 . Selection < any , any , any , any > ; public vis : d3 . Selection < any , any , any , any > ; public data : d3 . Selection < any , any , any , any > ; public overlay : d3 . Selection < any , any , any , any > ; public symbols : d3 . Selection < any , any , any , any > ; public axes : d3 . Selection < any , any , any , any > ; public dim : Options . Dimensions = new Options . Dimensions ( ) ; private clippingPathId : string ; constructor ( private element ) { super ( ) ; } create ( options ) { this . dim . updateMargins ( options ) ; this . listenToElement ( this . element , options ) ; this . createRoot ( ) ; this . createContainer ( ) ; this . dim . fromParentElement ( this . element . parentElement ) ; this . eventMgr . on ( 'resize' , ( ) => { this . dim . fromParentElement ( this . element . parentElement ) ; this . update ( ) ; } ) ; this . eventMgr . listenForDblClick ( this . svg , ( ) => { this . eventMgr . trigger ( 'zoom-pan-reset' , true ) ; } , this . key ) ; this . eventMgr . on ( 'zoom-pan-reset.' + this . key , ( event ) => { this . eventMgr . triggerDataAndOptions ( 'update' ) ; } ) ; } listenToElement ( element , options ) { var eventMgr = this . eventMgr ; element . addEventListener ( 'mouseover' , ( event ) => { eventMgr . triggerDataAndOptions . apply ( eventMgr , [ 'container-over' , event ] ) ; } ) ; element . addEventListener ( 'mousemove' , ( event ) => { eventMgr . triggerDataAndOptions . apply ( eventMgr , [ 'container-move' , event ] ) ; } ) ; element . addEventListener ( 'mouseout' , ( event ) => { eventMgr . triggerDataAndOptions . apply ( eventMgr , [ 'container-out' , event ] ) ; } ) ; } getCoordinatesFromEvent ( event ) { var dim = this . getDimensions ( ) ; var { left , top } = event . currentTarget . getBoundingClientRect ( ) ; var xScale = ( < Axis > this . factoryMgr . get ( 'x-axis' ) ) ; var x = xScale . invert ( event . clientX - left - dim . margin . left ) ; var yScale = ( < Axis > this . factoryMgr . get ( 'y-axis' ) ) ; var y = < number > yScale . invert ( event . clientY - top - dim . margin . top ) ; return { y , x } ; } update ( ) { this . updateRoot ( ) ; this . updateContainer ( ) ; } destroy ( ) { this . destroyRoot ( ) ; } createRoot ( ) { this . svg = d3 . select ( this . element ) . append ( 'svg' ) . attr ( 'class' , 'chart' ) ; this . defs = this . svg . append ( 'defs' ) ; } updateRoot ( ) { this . svg . attr ( 'width' , this . dim . width ) . attr ( 'height' , this . dim . height ) ; } destroyRoot ( ) { this . svg . remove ( ) ; } createContainer ( ) { this . vis = this . svg . append ( 'g' ) . attr ( 'class' , 'container' ) ; this . axes = this . vis . append ( 'g' ) . attr ( 'class' , 'axes' ) ; this . clippingPathId = 'clipping-path-' + Utils . UUID . generate ( ) ; this . defs . append ( 'svg:clipPath' ) . attr ( 'id' , this . clippingPathId ) . append ( 'svg:rect' ) . attr ( 'id' , 'clipping-rect' ) ; this . data = this . vis . append ( 'g' ) . attr ( 'class' , 'data' ) . attr ( 'clip-path' , 'url(#' + this . clippingPathId + ')' ) ; this . overlay = this . vis . append ( 'g' ) . attr ( 'class' , 'overlay' ) ; this . symbols = this . overlay . append ( 'g' ) . attr ( 'class' , 'symbols' ) . attr ( 'clip-path' , 'url(#' + this . clippingPathId + ')' ) ; } updateContainer ( ) { this . vis . attr ( 'width' , this . dim . innerWidth ) . attr ( 'height' , Math . max ( this . dim . innerHeight , 0 ) ) . attr ( 'transform' , 'translate(' + this . dim . margin . left + ', ' + this . dim . margin . top + ')' ) ; d3 . select ( this . element ) . select ( '#clipping-rect' ) . attr ( 'width' , Math . max ( this . dim . innerWidth , 0 ) ) . attr ( 'height' , Math . max ( this . dim . innerHeight , 0 ) ) ; } getDimensions ( ) { return this . dim ; } }