import { HttpClient , HttpErrorResponse } from '@angular/common/http' ; import { Injectable } from '@angular/core' ; import { BehaviorSubject , Observable , of } from 'rxjs' ; import { catchError } from 'rxjs/operators' ; /**
 * DYFI Service
 */ @ Injectable ( ) export class DyfiService { cdiZip$ : BehaviorSubject < any > = new BehaviorSubject < any > ( null ) ; error : any = null ; plotAtten$ : BehaviorSubject < any > = new BehaviorSubject < any > ( null ) ; plotNumResp$ : BehaviorSubject < any > = new BehaviorSubject < any > ( null ) ; constructor ( private httpClient ) { } param product getAtten ( product ) { if ( product === null || ! product . contents [ 'dyfi_plot_atten.json' ] ) { this . plotAtten$ . next ( null ) ; return ; } const atten = product . contents [ 'dyfi_plot_atten.json' ] ; this . httpClient . get ( atten . url ) . pipe ( catchError ( this . handleError ( ) ) ) . subscribe ( response => { try { const dyfiData = this . onData ( response ) ; this . plotAtten$ . next ( dyfiData ) ; } catch ( e ) { this . error = e ; this . plotAtten$ . next ( null ) ; } } ) ; } param product getCdi ( product ) { if ( product === null || ! product . contents [ 'cdi_zip.xml' ] ) { this . cdiZip$ . next ( null ) ; return ; } const cdiZip = product . contents [ 'cdi_zip.xml' ] ; this . httpClient . get ( cdiZip . url , { responseType : 'text' } ) . pipe ( catchError ( this . handleError ( ) ) ) . subscribe ( response => { try { const cdiZipJson = this . translateCdi ( response ) ; this . cdiZip$ . next ( cdiZipJson ) ; } catch ( e ) { this . error = e ; this . cdiZip$ . next ( null ) ; } } ) ; } param product getNumResp ( product ) { if ( product === null || ! product . contents [ 'dyfi_plot_numresp.json' ] ) { this . plotNumResp$ . next ( null ) ; return ; } const numResp = product . contents [ 'dyfi_plot_numresp.json' ] ; this . httpClient . get ( numResp . url ) . pipe ( catchError ( this . handleError ( ) ) ) . subscribe ( response => { try { const dyfiData = this . onData ( response ) ; this . plotNumResp$ . next ( dyfiData ) ; } catch ( e ) { this . error = e ; this . plotNumResp$ . next ( null ) ; } } ) ; } param dyfiData onData ( dyfiData ) { if ( dyfiData === null ) { return null ; } const series = [ ] ; let ngxDataset , ngxData ; for ( const dataset of dyfiData . datasets ) { ngxDataset = { class : dataset . class , name : dataset . legend || 'Responses' , series : [ ] } ; for ( const data of dataset . data ) { ngxData = { name : data . x , value : data . y , ... data } ; if ( data . stdev ) { ngxData . max = data . y + data . stdev ; ngxData . min = data . y - data . stdev ; } if ( ngxDataset . series . length > 0 && ngxDataset . series [ ngxDataset . series . length - 1 ] . name === data . x ) { ngxDataset . series [ ngxDataset . series . length - 1 ] = ngxData ; } else { ngxDataset . series . push ( ngxData ) ; } } series . push ( ngxDataset ) ; } dyfiData . series = series ; return dyfiData ; } param cdiData translateCdi ( cdiData ) { if ( cdiData === null ) { return null ; } const parser = new DOMParser ( ) ; const xmlDoc = parser . parseFromString ( cdiData , 'text/xml' ) ; const data = xmlDoc . getElementsByTagName ( 'location' ) ; const responsesArray = [ ] ; let locationName , locations , location , node , nodeName , nodeValue ; for ( let x = 0 ; x < data . length ; x ++ ) { locationName = data [ x ] . getAttribute ( 'name' ) ; locations = data [ x ] . childNodes ; location = { id : x , zip : '' } ; for ( let i = 0 ; i < locations . length ; i ++ ) { node = locations [ i ] ; nodeName = node . nodeName ; nodeValue = node . textContent ; if ( nodeName === 'name' || nodeName === 'state' || nodeName === 'country' || nodeName === 'zip' ) { location [ nodeName ] = nodeValue ; } else if ( nodeName === 'cdi' || nodeName === 'dist' || nodeName === 'lat' || nodeName === 'lon' ) { location [ nodeName ] = parseFloat ( nodeValue ) ; } else if ( nodeName === 'nresp' ) { location [ nodeName ] = parseInt ( nodeValue , 10 ) ; } } if ( locationName . length === 5 ) { location . country = 'United States of America' ; location . zip = locationName ; } else { locationName = locationName . split ( '::' ) ; location . state = locationName [ 1 ] ; location . country = locationName [ 2 ] ; } responsesArray . push ( location ) ; } return responsesArray ; } /**
     * Error handler for http requests.
     */ private handleError ( ) { return ( error ) : Observable < any > => { this . error = error ; return of ( null ) ; } ; } }