import { Glyph } from 'src/app/glyph/glyph' ; import { FeatureFilter } from 'src/app/shared/filter/feature-filter' ; import { BehaviorSubject , Observable } from 'rxjs' ; import * as d3 from 'd3' ; import { GlyphConfiguration } from 'src/app/glyph/glyph.configuration' ; import { Configuration } from './configuration.service' ; import { GlyphLayout } from 'src/app/glyph/glyph.layout' ; import { EventAggregatorService } from 'src/app/shared/events/event-aggregator.service' ; import { RefreshHoverEvent } from 'src/app/shared/events/refresh-hover.event' ; import { RefreshHoverEventData } from 'src/app/shared/events/refresh-hover.event.data' ; import { FlowerGlyph } from 'src/app/glyph/glyph.flower' ; import { DotGlyph } from 'src/app/glyph/glyph.dot' ; import { DotGlyphConfiguration } from 'src/app/glyph/glyph.dot.configuration' ; export class ConfigurationData { private configuration : Configuration ; private eventAggregator : EventAggregatorService ; private _categoryColor = d3 . scaleQuantize ( ) . domain ( [ 0.0 , 1.0 ] ) . range ( [ '#4f366d' , '#933765' , '#d08f51' , '#286367' , '#8BC34A' , '#FFC107' , '#2196F3' , '#FF5722' , '#607D8B' , '#BF3330' ] as any ) ; private _rangeColor = d3 . scaleLinear < any , any > ( ) . domain ( [ 0.0 , 0.5 , 1.0 ] ) . range ( [ '#198FBD' , '#F7D529' , '#F7295B' ] ) ; public duration = 1000 ; private _levelOfDetails : number [ ] = [ ] ; private _maxZoom : number = 1 ; private _currentLevelOfDetail = 0 ; private _previousLevelOfDetail : any ; private _lockLevelOfDetail : boolean = false ; private _lockUpdated : boolean = false ; private _currentZoomLevel : number = 1 ; private _zoomIdentity = d3 . zoomIdentity ; private _minScaleLevel = 0.5 ; private _useColorRange : boolean = false ; private _featureFilters : FeatureFilter [ ] = [ ] ; private _glyph : Glyph ; private _activeFeatures : any [ ] = [ ] ; private _featureGroups : any [ ] = [ ] ; private _activeDataSet : any ; private _activeGlyphConfig : GlyphConfiguration | undefined ; private _selectedContext : any ; private _featureContexts = new Array < any > ( ) ; private _selectedFeatureName : string = "" ; private _globalFeatureContext = - 1 ; private _individualFeatureContexts : any = { } ; private _useDragSelection = false ; private _extendSelection = false ; private _useForceLayout = false ; private _layouts : GlyphLayout | undefined ; private _currentLayout = 0 ; private _data = new BehaviorSubject < any > ( null ) ; private _selectedDataSetInfo = { name : '' , version : '' , positionAlgorithm : '' } ; private _idOfHoveredGlyph = - 1 ; private _showHighlightInNormalMode = false ; private _selectedItemVersions : any ; private _aggregateItems = false ; private _itemsCount : number = 0 ; private _leftSide : boolean = false ; private _filteredItemsIds : number [ ] = [ ] ; private _filteredItemsCount = 0 ; private _uniqueID : string = "" ; constructor ( configuration , eventAggregator ) { this . _glyph = new DotGlyph ( 0 , 0 , new DotGlyphConfiguration ) ; this . configuration = configuration ; this . eventAggregator = eventAggregator ; this . maxZoom = 50 ; this . _levelOfDetails = [ 1 , this . maxZoom * 0.08 , this . maxZoom * 0.2 ] ; } param { number } zoomLevel public updateCurrentLevelOfDetail ( zoomLevel ) { this . _currentZoomLevel = zoomLevel ; if ( this . lockLevelOfDetail ) { if ( this . lockUpdated ) { this . lockUpdated = false ; } else { this . previousLevelOfDetail = this . currentLevelOfDetail ; } return ; } else if ( this . lockUpdated ) { this . lockUpdated = false ; return ; } let count = 0 ; let newLevel = this . currentLevelOfDetail ; this . _levelOfDetails . forEach ( element => { if ( zoomLevel > element ) { newLevel = count ; } count ++ ; } ) ; var hasActiveFeatures = false ; if ( this . activeFeatures != undefined ) { this . activeFeatures . forEach ( ( d ) => { if ( d . active ) { hasActiveFeatures = true ; } } ) ; } if ( hasActiveFeatures || this . activeFeatures == undefined ) { this . currentLevelOfDetail = newLevel ; } else { this . currentLevelOfDetail = 0 ; } } return { boolean } public levelChanged ( ) { return this . _previousLevelOfDetail !== this . _currentLevelOfDetail ; } get color ( ) : any { return this . _useColorRange ? this . _rangeColor : this . _categoryColor ; } public setData ( value ) { this . _data . next ( value ) ; } public getData ( ) { return this . _data . asObservable ( ) ; } get activeFeatures ( ) : any { return this . _activeFeatures ; } set activeFeatures ( features ) { this . _activeFeatures = features ; } get featureGroups ( ) : any { return this . _featureGroups ; } set featureGroups ( groups ) { this . _featureGroups = groups ; } get glyph ( ) : Glyph { return this . _glyph ; } set glyph ( value ) { this . _glyph = value ; } get useDragSelection ( ) : boolean { return this . _useDragSelection ; } set useDragSelection ( flag ) { this . _useDragSelection = flag ; } get useForceLayout ( ) : boolean { return this . _useForceLayout ; } set useForceLayout ( flag ) { this . _useForceLayout = flag ; } get currentLevelOfDetail ( ) : number { return this . _currentLevelOfDetail ; } set currentLevelOfDetail ( level ) { if ( this . _currentLevelOfDetail === level ) { this . previousLevelOfDetail = level ; } else { this . _currentLevelOfDetail = level ; } } get levelOfDetails ( ) : any { return this . _levelOfDetails . map ( level => level / this . maxZoom ) ; } set levelOfDetails ( lods ) { lods . forEach ( ( level , i ) => { this . _levelOfDetails [ i ] = level * this . maxZoom ; } ) ; } get miniatureLevel ( ) : number { return this . _levelOfDetails [ 1 ] / this . maxZoom ; } set miniatureLevel ( l ) { this . _levelOfDetails [ 1 ] = l * this . maxZoom ; } get previousLevelOfDetail ( ) : number { return this . _previousLevelOfDetail ; } set previousLevelOfDetail ( level ) { this . _previousLevelOfDetail = level ; } get lockLevelOfDetail ( ) : boolean { return this . _lockLevelOfDetail ; } set lockLevelOfDetail ( lock ) { this . _lockLevelOfDetail = lock ; this . lockUpdated = true ; } get lockUpdated ( ) : boolean { return this . _lockUpdated ; } set lockUpdated ( updated ) { this . _lockUpdated = updated ; } get maxZoom ( ) : number { return this . _maxZoom ; } set maxZoom ( zoom ) { this . _maxZoom = zoom ; } get useColorRange ( ) : boolean { return this . _useColorRange ; } set useColorRange ( flag ) { this . _useColorRange = flag ; } get currentLayout ( ) : GlyphLayout { return this . _currentLayout ; } set currentLayout ( layout ) { this . _currentLayout = layout ; } get globalFeatureContext ( ) : number { return this . _globalFeatureContext ; } set globalFeatureContext ( newContext ) { this . _globalFeatureContext = newContext ; } get individualFeatureContexts ( ) : any { return this . _individualFeatureContexts ; } set individualFeatureContexts ( contexts ) { this . _individualFeatureContexts = contexts ; } get featureFilters ( ) : FeatureFilter [ ] { return this . _featureFilters ; } set featureFilters ( filter ) { this . _featureFilters = filter ; } get currentZoomLevel ( ) : number { return this . _currentZoomLevel ; } get uniqueID ( ) : string { return this . _uniqueID ; } set uniqueID ( uniqueID ) { this . _uniqueID = uniqueID ; } get selectedDataSetInfo ( ) : { name : string ; version : string ; positionAlgorithm : string ; } { return this . _selectedDataSetInfo ; } set selectedDataSetInfo ( value ) { this . _selectedDataSetInfo = value ; } get idOfHoveredGlyph ( ) : number { return this . _idOfHoveredGlyph ; } set idOfHoveredGlyph ( value ) { const changed = this . _idOfHoveredGlyph !== value && value >= 0 ; this . _idOfHoveredGlyph = value ; if ( this . _idOfHoveredGlyph > 0 && changed ) { this . selectedItemVersions = [ ] ; const data = this . _data . getValue ( ) ; const item = data . features . find ( ( f ) => { return f . id === this . _idOfHoveredGlyph ; } ) ; if ( item !== undefined ) { for ( const context in item . features ) { if ( context === 'global' ) { continue ; } if ( item . features . hasOwnProperty ( context ) ) { const features = item . features [ context ] ; let label = "" ; for ( const ctx in data . schema [ 'variant-context' ] ) { if ( data . schema [ 'variant-context' ] . hasOwnProperty ( ctx ) ) { const c = data . schema [ 'variant-context' ] [ ctx ] ; if ( c . id === context ) { label = c . description ; } } } this . selectedItemVersions . push ( { label : label , features : features } ) ; } } } const payload = new RefreshHoverEventData ( this . _idOfHoveredGlyph , item . features [ this . selectedContext . id ] , item ) ; this . eventAggregator . getEvent ( RefreshHoverEvent ) . publish ( payload ) ; } } get extendSelection ( ) : boolean { return this . _extendSelection ; } set extendSelection ( value ) { this . _extendSelection = value ; } get showHighlightInNormalMode ( ) : boolean { return this . _showHighlightInNormalMode ; } set showHighlightInNormalMode ( value ) { this . _showHighlightInNormalMode = value ; } get selectedItemVersions ( ) { return this . _selectedItemVersions ; } set selectedItemVersions ( array ) { this . _selectedItemVersions = array ; } get aggregateItems ( ) { return this . _aggregateItems ; } set aggregateItems ( value ) { this . _aggregateItems = value ; } get activeDataSet ( ) { return this . _activeDataSet ; } set activeDataSet ( value ) { this . _activeDataSet = value ; } get selectedContext ( ) { return this . _selectedContext ; } set selectedContext ( value ) { this . _selectedContext = value ; } get featureContexts ( ) { return this . _featureContexts ; } set featureContexts ( value ) { this . _featureContexts = value ; } get selectedFeatureName ( ) { return this . _selectedFeatureName ; } set selectedFeatureName ( value ) { this . _selectedFeatureName = value ; } get activeGlyphConfig ( ) : GlyphConfiguration | undefined { return this . _activeGlyphConfig ; } set activeGlyphConfig ( value ) { this . _activeGlyphConfig = value ; } get itemsCount ( ) { return this . _itemsCount ; } set itemsCount ( value ) { this . _itemsCount = value ; } get leftSide ( ) { return this . _leftSide ; } set leftSide ( value ) { this . _leftSide = value ; } get filteredItemsCount ( ) { return this . _filteredItemsCount ; } set filteredItemsCount ( value ) { this . _filteredItemsCount = value ; } get filteredItemsIds ( ) { return this . _filteredItemsIds ; } set filteredItemsIds ( value ) { this . _filteredItemsIds = value ; } get minScaleLevel ( ) { return this . _minScaleLevel ; } set minScaleLevel ( value ) { this . _minScaleLevel = value ; } get zoomIdentity ( ) { return this . _zoomIdentity ; } set zoomIdentity ( newIdentity ) { this . _zoomIdentity = newIdentity ; } public filterRefresh ( ) { var filteredIds = [ ] ; this . _data . getValue ( ) . positions . forEach ( ( d ) => { let itemConfirmsFilter = true ; let featureItem = this . getFeaturesForItem ( d ) ; const filters = this . featureFilters ; let filter ; for ( let i = 0 ; i < filters . length ; i ++ ) { filter = filters [ i ] ; itemConfirmsFilter = itemConfirmsFilter && filter . itemConfirmsToFilter ( d . id , featureItem . features , featureItem . values ) ; } if ( itemConfirmsFilter ) { filteredIds . push ( d . id ) ; } } ) ; this . _filteredItemsIds = filteredIds ; if ( this . _featureFilters . length == 0 ) { this . _filteredItemsCount = this . _data . getValue ( ) . positions . length ; } else { this . _filteredItemsCount = this . _filteredItemsIds . length ; } } private getFeaturesForItem ( d ) { const item = this . _data . getValue ( ) . features . find ( ( f ) => { return f . id === d . id ; } ) ; let itemContext = this . individualFeatureContexts [ d . id ] ; if ( itemContext === undefined ) { if ( this . globalFeatureContext >= 0 ) { itemContext = this . globalFeatureContext ; } else { itemContext = item [ 'default-context' ] ; } } const ret = { features : Object . assign ( item . features [ itemContext ] , item . features [ 'global' ] ) , values : item . values } ; return ret ; } }