import * as d3 from 'd3' ; import * as _ from 'underscore' ; import { LinearScale , OrdinalScale } from 'bqscales' ; import { BaseXSelector } from './Selector' ; export class IndexSelector extends BaseXSelector { render ( ) { super . render ( ) ; this . active = false ; this . dirty = false ; const that = this ; const scale_creation_promise = this . create_scales ( ) ; Promise . all ( [ this . mark_views_promise , scale_creation_promise ] ) . then ( ( ) => { that . line = that . d3el . append ( 'line' ) . attr ( 'class' , 'selector indsel' ) . attr ( 'x1' , 0 ) . attr ( 'y1' , 0 ) . attr ( 'x2' , 0 ) . attr ( 'y2' , that . height ) . attr ( 'stroke-width' , that . model . get ( 'line_width' ) ) . attr ( 'pointer-events' , 'none' ) . attr ( 'visibility' , 'hidden' ) ; that . color_change ( ) ; that . background = that . d3el . append ( 'rect' ) . attr ( 'x' , 0 ) . attr ( 'y' , 0 ) . attr ( 'width' , that . width ) . attr ( 'height' , that . height ) . attr ( 'class' , 'selector selectormouse' ) . attr ( 'pointer-events' , 'all' ) . attr ( 'visibility' , 'hidden' ) ; that . background . on ( 'mousemove' , _ . bind ( that . mousemove , that ) ) . on ( 'click' , _ . bind ( that . initial_click , that ) ) ; that . create_listeners ( ) ; that . selected_changed ( ) ; } ) ; } create_listeners ( ) { super . create_listeners ( ) ; this . listenTo ( this . model , 'change:color' , this . color_change ) ; } color_change ( ) { if ( this . model . get ( 'color' ) !== null ) { this . line . style ( 'stroke' , this . model . get ( 'color' ) ) ; } } initial_click ( ) { this . line . attr ( 'visibility' , 'visible' ) ; this . click ( ) ; this . background . on ( 'click' , _ . bind ( this . click , this ) ) ; } click ( ) { this . active = ! this . active ; } mousemove ( ) { if ( ! this . active || this . dirty ) { return ; } this . dirty = true ; const mouse_pos = d3 . mouse ( this . background . node ( ) ) ; const xpixel = mouse_pos [ 0 ] ; this . line . attr ( 'x1' , xpixel ) . attr ( 'x2' , xpixel ) ; this . set_selected ( 'selected' , [ this . invert_pixel ( xpixel ) ] ) ; _ . each ( this . mark_views , ( mark_view ) => { mark_view . invert_point ( xpixel ) ; } ) ; this . touch ( ) ; this . dirty = false ; } invert_pixel ( pixel ) { return this . scale . invert ( pixel ) ; } reset ( ) { this . active = false ; if ( this . line !== undefined && this . line !== null ) { this . line . attr ( 'x1' , 0 ) . attr ( 'x2' , 0 ) . attr ( 'visibility' , 'hidden' ) ; } if ( this . background !== undefined && this . background !== null ) { this . background . on ( 'click' , _ . bind ( this . initial_click , this ) ) ; } this . model . set ( 'selected' , null ) ; _ . each ( this . mark_views , ( mark_view ) => { mark_view . invert_point ( ) ; } ) ; this . touch ( ) ; } update_scale_domain ( ignore_gui_update ) { super . update_scale_domain ( ) ; if ( ignore_gui_update !== true ) { this . selected_changed ( ) ; } } selected_changed ( ) { if ( this . dirty ) { return ; } const selected = this . model . get ( 'selected' ) || [ ] ; if ( selected . length === 0 ) { this . reset ( ) ; } else if ( selected . length != 1 ) { return ; } else { const pixel = this . scale . scale ( selected [ 0 ] ) ; if ( this . line !== undefined && this . line !== null ) { this . line . attr ( 'x1' , pixel ) . attr ( 'x2' , pixel ) . attr ( 'visibility' , 'visible' ) ; } this . background . on ( 'click' , _ . bind ( this . click , this ) ) ; _ . each ( this . mark_views , ( mark_view ) => { mark_view . invert_point ( pixel ) ; } ) ; } } relayout ( ) { super . relayout ( ) ; this . line . attr ( 'y1' , 0 ) . attr ( 'y2' , this . height ) ; this . background . attr ( 'width' , this . width ) . attr ( 'height' , this . height ) ; this . set_range ( [ this . scale ] ) ; } set_range ( array ) { for ( let iter = 0 ; iter < array . length ; iter ++ ) { array [ iter ] . setRange ( [ 0 , this . width ] ) ; } } active : boolean ; dirty : boolean ; line : d3 . Selection < SVGLineElement , any , any , any > ; background : d3 . Selection < SVGRectElement , any , any , any > ; scale : LinearScale | OrdinalScale ; }