import { Component , ViewEncapsulation , Input , SimpleChanges , OnChanges } from '@angular/core' ; import { SelectionRange } from '@progress/kendo-angular-dateinputs' ; import { StockDataService } from 'src/app/services/stock-data.service' ; import { PlotBand } from '@progress/kendo-angular-charts' ; import { StockIntervalDetails , Interval , IntervalUnitsMap , defaultRange } from 'src/app/models' ; const currencies = { EUR : '€' , USD : '$' , GBP : '£' } ; @ Component ( { selector : 'app-stock-details' , templateUrl : './stock-details.component.html' , styleUrls : [ './stock-details.component.scss' ] , encapsulation : ViewEncapsulation . None } ) export class StockDetailsComponent implements OnChanges { @ Input ( ) public chartType : 'candle' | 'line' | 'area' = 'candle' ; @ Input ( ) public interval : Interval = { unit : 'hours' , step : 1 } ; @ Input ( ) public range : SelectionRange = defaultRange ; @ Input ( ) public symbol : string = 'EUR' ; public stockData : StockIntervalDetails [ ] = [ ] ; public volumeValueAxisMax : number = 100 ; public candleChartAggregate = { open : ( value ) => value [ 0 ] , close : ( value ) => value [ value . length - 1 ] , high : ( value ) => Math . max ( ... value ) , low : ( value ) => Math . min ( ... value ) , volume : ( value ) => value . reduce ( ( total , current ) => total + current , 0 ) } ; public categoryPlotBands : PlotBand [ ] = [ ] ; public get currency ( ) : string { return currencies [ this . stockDataService . selectedCurrency ] ; } private previousColumnChartItem : StockIntervalDetails = { volume : 100 } ; constructor ( private stockDataService ) { } public ngOnChanges ( changes ) { if ( changes [ 'interval' ] || changes [ 'range' ] || changes [ 'symbol' ] ) { if ( ! ( this . range . start && this . range . end ) ) { return ; } const intervalInMinutes = this . interval . step * IntervalUnitsMap [ this . interval . unit ] ; this . stockData = this . stockDataService . getStockIntervalDetails ( this . symbol , this . range , intervalInMinutes ) ; this . configureVolumeValueAxisHeight ( ) ; this . composeCategoryPlotBands ( ) ; } } public itemColor = ( args ) => { const current = args . dataItem ; const currentLargerThenPrev = ! this . previousColumnChartItem || ( current . volume >= this . previousColumnChartItem . volume ) ; if ( current . volume ) { this . previousColumnChartItem = args . dataItem ; } return currentLargerThenPrev ? '#5CB85C' : '#FF6358' ; } ; public configureVolumeValueAxisHeight ( ) { this . volumeValueAxisMax = Math . max ( ... this . stockData . map ( stock => stock . volume ) ) * 4 ; } private composeCategoryPlotBands ( ) { this . categoryPlotBands = this . stockData . reduce ( ( bands , current , index , allStocks ) => { bands . push ( { from : current . date , to : ( allStocks [ index + 1 ] || current ) . date , color : index % 2 !== 0 ? 'white' : 'lightgrey' , opacity : 0.2 } as PlotBand ) ; return bands ; } , [ ] as PlotBand [ ] ) ; } }