module powerbi . extensibility . visual { export interface TooltipEventArgs < TData > { data : TData ; coordinates : number [ ] ; isTouchEvent : boolean ; } export interface ITooltipServiceWrapper { addTooltip < T > ( map , layer , tooltips , getTooltipInfoDelegate , reloadTooltipDataOnMouseMove ? ) : void ; hide ( immediately ? ) : void ; } const DefaultHandleTouchDelay = 1000 ; export function createTooltipServiceWrapper ( tooltipService , rootElement , handleTouchDelay = DefaultHandleTouchDelay ) { return new TooltipServiceWrapper ( tooltipService , rootElement , handleTouchDelay ) ; } class TooltipServiceWrapper implements ITooltipServiceWrapper { private handleTouchTimeoutId : number ; private visualHostTooltipService : ITooltipService ; private rootElement : HTMLElement ; private handleTouchDelay : number ; private mapShowTooltip : any ; private mapHideTooltip : any ; constructor ( tooltipService , rootElement , handleTouchDelay ) { this . visualHostTooltipService = tooltipService ; this . handleTouchDelay = handleTouchDelay ; this . rootElement = rootElement ; this . mapShowTooltip = { } ; this . mapHideTooltip = { } ; } public addTooltip < T > ( map , layer , getTooltips , getTooltipInfoDelegate , reloadTooltipDataOnMouseMove ? ) { if ( ! map || ! this . visualHostTooltipService . enabled ( ) ) { return ; } let rootNode = this . rootElement ; rootNode . style . cursor = '-webkit-grab' ; rootNode . style . cursor = 'grab' ; layer . getLayerIDs ( ) . map ( layerId => { if ( ! this . mapHideTooltip [ layerId ] ) { this . mapHideTooltip [ layerId ] = ( e ) => { this . hide ( ) ; } ; } if ( ! this . mapShowTooltip [ layerId ] ) { this . mapShowTooltip [ layerId ] = mapboxUtils . debounce ( ( e ) => { rootNode . style . cursor = 'pointer' ; let tooltipEventArgs = this . makeTooltipEventArgs < T > ( e , getTooltips ) ; if ( ! tooltipEventArgs ) return ; let tooltipInfo ; if ( reloadTooltipDataOnMouseMove || true ) { tooltipInfo = getTooltipInfoDelegate ( tooltipEventArgs ) ; if ( ! tooltipInfo || tooltipInfo . length < 1 ) { return ; } } this . visualHostTooltipService . show ( { coordinates : tooltipEventArgs . coordinates , isTouchEvent : false , dataItems : tooltipInfo , identities : [ ] , } ) ; } , 6 , true ) ; } map . off ( 'mouseleave' , layerId , this . mapHideTooltip [ layerId ] ) ; map . off ( 'mousemove' , layerId , this . mapShowTooltip [ layerId ] ) ; if ( layer . hasTooltip ( getTooltips ( ) ) ) { map . on ( 'mouseleave' , layerId , this . mapHideTooltip [ layerId ] ) ; map . on ( 'mousemove' , layerId , this . mapShowTooltip [ layerId ] ) ; } else { this . mapShowTooltip [ layerId ] = null ; this . mapHideTooltip [ layerId ] = null ; } } ) ; } private getDisplayNameMap ( metadata ) { let ret = { } ; metadata . columns . map ( column => { Object . keys ( column . roles ) . map ( role => { ret [ role ] = column . displayName ; } ) ; } ) ; return ret ; } public hide ( immediately = false ) { const rootNode = this . rootElement ; rootNode . style . cursor = '-webkit-grab' ; rootNode . style . cursor = 'grab' ; this . visualHostTooltipService . hide ( { isTouchEvent : false , immediately } ) ; } private makeTooltipEventArgs < T > ( e , getTooltips ) { let tooltipEventArgs = null ; try { if ( e . features && e . features . length > 0 ) { tooltipEventArgs = { data : e . features . slice ( 0 , 3 ) . map ( feature => { return Object . keys ( feature . properties ) . map ( prop => { return { key : prop , value : feature . properties [ prop ] } ; } ) ; } ) , coordinates : [ e . point . x , e . point . y ] , isTouchEvent : false } ; } } finally { return tooltipEventArgs ; } } } }