import { ChartType } from '../../chart_types' ; import { drilldownActive } from '../../chart_types/partition_chart/state/selectors/drilldown_active' ; import { getPickedShapesLayerValues } from '../../chart_types/partition_chart/state/selectors/picked_shapes' ; import { LegendItem } from '../../common/legend' ; import { SeriesIdentifier } from '../../common/series_id' ; import { LayerValue } from '../../specs' ; import { getDelta } from '../../utils/point' ; import { DOMElementActions , ON_DOM_ELEMENT_ENTER , ON_DOM_ELEMENT_LEAVE } from '../actions/dom_element' ; import { KeyActions , ON_KEY_UP } from '../actions/key' ; import { LegendActions , ON_LEGEND_ITEM_OUT , ON_LEGEND_ITEM_OVER , ON_TOGGLE_DESELECT_SERIES , ToggleDeselectSeriesAction , } from '../actions/legend' ; import { MouseActions , ON_MOUSE_DOWN , ON_MOUSE_UP , ON_POINTER_MOVE } from '../actions/mouse' ; import { GlobalChartState , InteractionsState } from '../chart_state' ; import { getInitialPointerState } from '../utils' ; internal export const DRAG_DETECTION_TIMEOUT = 100 ; /**
 * The minimum number of pixel between two pointer positions to consider for dragging purposes
 */ const DRAG_DETECTION_PIXEL_DELTA = 4 ; internal export function interactionsReducer ( globalState , action , legendItems ) { const { interactions : state } = globalState ; switch ( action . type ) { case ON_KEY_UP : if ( action . key === 'Escape' ) { return { ... state , pointer : getInitialPointerState ( ) , } ; } return state ; case ON_POINTER_MOVE : const dragging = ! ! state . pointer . down && getDelta ( state . pointer . down . position , action . position ) > DRAG_DETECTION_PIXEL_DELTA ; return { ... state , pointer : { ... state . pointer , dragging , current : { position : { ... action . position , } , time : action . time , } , } , } ; case ON_MOUSE_DOWN : return { ... state , drilldown : getDrilldownData ( globalState ) , prevDrilldown : state . drilldown , pointer : { ... state . pointer , dragging : false , up : null , down : { position : { ... action . position , } , time : action . time , } , } , } ; case ON_MOUSE_UP : { return { ... state , pointer : { ... state . pointer , lastDrag : state . pointer . down && state . pointer . dragging ? { start : { position : { ... state . pointer . down . position , } , time : state . pointer . down . time , } , end : { position : { ... state . pointer . current . position , } , time : action . time , } , } : null , lastClick : state . pointer . down && ! state . pointer . dragging ? { position : { ... action . position , } , time : action . time , } : null , dragging : false , down : null , up : { position : { ... action . position , } , time : action . time , } , } , } ; } case ON_LEGEND_ITEM_OUT : return { ... state , highlightedLegendPath : [ ] , } ; case ON_LEGEND_ITEM_OVER : const { legendPath : highlightedLegendPath } = action ; return { ... state , highlightedLegendPath , } ; case ON_TOGGLE_DESELECT_SERIES : return { ... state , deselectedDataSeries : toggleDeselectedDataSeries ( action , state . deselectedDataSeries , legendItems ) , } ; case ON_DOM_ELEMENT_ENTER : return { ... state , hoveredDOMElement : action . element , } ; case ON_DOM_ELEMENT_LEAVE : return { ... state , hoveredDOMElement : null , } ; default : return state ; } } /**
 * Helper functions that currently depend on chart type eg. xy or partition
 */ function toggleDeselectedDataSeries ( { legendItemIds , negate } , deselectedDataSeries , legendItems ) { const actionSeriesKeys = legendItemIds . map ( ( { key } ) => key ) ; const deselectedDataSeriesKeys = new Set ( deselectedDataSeries . map ( ( { key } ) => key ) ) ; const legendItemsKeys = legendItems . map ( ( { seriesIdentifiers } ) => seriesIdentifiers ) ; const alreadyDeselected = actionSeriesKeys . every ( ( key ) => deselectedDataSeriesKeys . has ( key ) ) ; if ( negate ) { if ( ! alreadyDeselected && deselectedDataSeries . length === legendItemsKeys . length - 1 ) { return legendItemIds ; } return legendItems . map ( ( { seriesIdentifiers } ) => seriesIdentifiers ) . flat ( ) . filter ( ( { key } ) => ! actionSeriesKeys . includes ( key ) ) ; } if ( alreadyDeselected ) { return deselectedDataSeries . filter ( ( { key } ) => ! actionSeriesKeys . includes ( key ) ) ; } return [ ... deselectedDataSeries , ... legendItemIds ] ; } function getDrilldownData ( globalState ) { if ( globalState . chartType !== ChartType . Partition || ! drilldownActive ( globalState ) ) { return [ ] ; } const layerValues = getPickedShapesLayerValues ( globalState ) [ 0 ] ; return layerValues ? layerValues [ layerValues . length - 1 ] . path . map ( ( n ) => n . value ) : [ ] ; }