import { Selector } from 'reselect' ; import { ChartType } from '../../..' ; import { PointerEvent , PointerOverEvent , PointerUpdateTrigger } from '../../../../specs' ; import { PointerEventType } from '../../../../specs/constants' ; import { GlobalChartState } from '../../../../state/chart_state' ; import { createCustomCachedSelector } from '../../../../state/create_selector' ; import { getChartIdSelector } from '../../../../state/selectors/get_chart_id' ; import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_specs' ; import { ComputedScales } from '../utils/types' ; import { computeSeriesGeometriesSelector } from './compute_series_geometries' ; import { getGeometriesIndexKeysSelector } from './get_geometries_index_keys' ; import { getOrientedProjectedPointerPositionSelector } from './get_oriented_projected_pointer_position' ; import { PointerPosition } from './get_projected_pointer_position' ; const getPointerEventSelector = createCustomCachedSelector ( [ getChartIdSelector , getOrientedProjectedPointerPositionSelector , computeSeriesGeometriesSelector , getGeometriesIndexKeysSelector , ] , ( chartId , orientedProjectedPointerPosition , seriesGeometries , geometriesIndexKeys ) : PointerEvent => getPointerEvent ( chartId , orientedProjectedPointerPosition , seriesGeometries . scales , geometriesIndexKeys ) ) ; function getPointerEvent ( chartId , orientedProjectedPointerPosition , { xScale , yScales } , geometriesIndexKeys ) { if ( ! xScale ) { return { chartId , type : PointerEventType . Out } ; } const { x , y , verticalPanelValue , horizontalPanelValue } = orientedProjectedPointerPosition ; if ( x === - 1 || y === - 1 ) { return { chartId , type : PointerEventType . Out } ; } const xValue = xScale . invertWithStep ( x , geometriesIndexKeys ) ; if ( ! xValue ) { return { chartId , type : PointerEventType . Out } ; } return { chartId , type : PointerEventType . Over , unit : xScale . unit , scale : xScale . type , x : xValue . value , y : [ ... yScales . entries ( ) ] . map ( ( [ groupId , yScale ] ) => { return { value : yScale . invert ( y ) , groupId } ; } ) , smVerticalValue : verticalPanelValue , smHorizontalValue : horizontalPanelValue , } ; } function isSameEventValue ( a , b , changeTrigger ) { const checkX = changeTrigger === PointerUpdateTrigger . X || changeTrigger === PointerUpdateTrigger . Both ; const checkY = changeTrigger === PointerUpdateTrigger . Y || changeTrigger === PointerUpdateTrigger . Both ; return ( ( ! checkX || ( a . x === b . x && a . scale === b . scale && a . unit === b . unit ) ) && ( ! checkY || a . y . every ( ( y , i ) => y . value === b . y [ i ] ?. value ) ) ) ; } const hasPointerEventChanged = ( prev , next , changeTrigger ) => next ?. type !== prev . type || ( prev . type === PointerEventType . Over && next ?. type === PointerEventType . Over && ! isSameEventValue ( prev , next , changeTrigger ) ) ; internal export function createOnPointerMoveCaller ( ) { let prevPointerEvent = null ; let selector = null ; return ( state ) => { if ( selector === null && state . chartType === ChartType . XYAxis ) { selector = createCustomCachedSelector ( [ getSettingsSpecSelector , getPointerEventSelector , getChartIdSelector ] , ( { onPointerUpdate , pointerUpdateTrigger } , nextPointerEvent , chartId ) : void => { if ( prevPointerEvent === null ) { prevPointerEvent = { chartId , type : PointerEventType . Out } ; } const tempPrev = { ... prevPointerEvent } ; prevPointerEvent = nextPointerEvent ; if ( onPointerUpdate && hasPointerEventChanged ( tempPrev , nextPointerEvent , pointerUpdateTrigger ) ) onPointerUpdate ( nextPointerEvent ) ; } ) ; } if ( selector ) { selector ( state ) ; } } ; }