import powerbiVisualsApi from "powerbi-visuals-api" ; import * as lodash from "lodash" ; import ISelectionManager = powerbiVisualsApi . extensibility . ISelectionManager ; import IVisualHost = powerbiVisualsApi . extensibility . visual . IVisualHost ; import ISelectionId = powerbiVisualsApi . visuals . ISelectionId ; import { WordCloudDataPoint } from "./dataInterfaces" ; export interface SelectionIdValues < T > { value : T ; selectionId : ISelectionId [ ] ; } export class ValueSelectionManager < T > { private selectedValuesValue : T [ ] = [ ] ; private visualHost : IVisualHost ; private getSelectionIds : ( value : T | T [ ] ) => ISelectionId [ ] ; private selectionManager : ISelectionManager ; public constructor ( visualHost , getSelectionIds , getDataPoints , renderSelection ) { this . visualHost = visualHost ; this . selectionManager = visualHost . createSelectionManager ( ) ; this . selectionManager . registerOnSelectCallback ( ( ids ) => { this . clear ( false ) ; ids . forEach ( ( selection ) => { getDataPoints ( ) . forEach ( ( dataPoint ) => { if ( selection . includes ( dataPoint . selectionIds [ 0 ] ) ) { this . selectedValues . push ( < any > dataPoint . text ) ; renderSelection ( ) ; } } ) ; } ) ; } ) ; this . getSelectionIds = ( value ) => lodash . isArray ( value ) ? < ISelectionId [ ] > lodash . flatten ( ( < T [ ] > value ) . map ( ( valueElement ) => { return getSelectionIds ( valueElement ) ; } ) ) : getSelectionIds ( value ) ; } public get selectedValues ( ) : T [ ] { return this . selectedValuesValue ; } public get selectionIds ( ) : ISelectionId [ ] { return this . getSelectionIds ( this . selectedValues ) ; } public get hasSelection ( ) : boolean { return this . selectedValues . length > 0 ; } public get getSelectionIdValues ( ) : SelectionIdValues < T > [ ] { return this . selectedValues . map ( ( value ) => { return { value , selectionId : this . getSelectionIds ( value ) } ; } ) ; } public selectAndSendSelection ( value , multiSelect = false ) { const values = lodash . isArray ( value ) ? value : [ value ] ; this . selectInternal ( values , multiSelect ) ; this . sendSelection ( ) ; } public isSelected ( selectionId ) { const values = lodash . isArray ( selectionId ) ? selectionId : [ selectionId ] ; return values . every ( ( value ) => this . selectedValues . some ( ( selectedValue ) => { return selectedValue === value ; } ) ) ; } public sendSelection ( ) { this . sendSelectionToHost ( this . selectionIds ) ; } public clear ( sendToHost ) { this . selectedValues . length = 0 ; if ( sendToHost ) { this . sendSelection ( ) ; } } private selectInternal ( values , multiSelect ) { let resultValues ; if ( this . isSelected ( values ) ) { resultValues = multiSelect ? this . selectedValues . filter ( ( selectedValue ) => { return ! values . some ( ( value ) => value === selectedValue ) ; } ) : this . selectedValues . length === values . length ? [ ] : values ; } else { resultValues = multiSelect ? values . filter ( ( value ) => { return ! this . isSelected ( value ) ; } ) . concat ( this . selectedValues ) : values ; } this . selectedValues . length = 0 ; resultValues . forEach ( ( value ) => { this . selectedValues . push ( value ) ; } ) ; } private sendSelectionToHost ( ids ) { ( < any > this . selectionManager ) . sendSelectionToHost ( ids ) ; } }