@helgoland/core
Version:
1,751 lines (1,724 loc) • 211 kB
JavaScript
import { Injectable, Inject, InjectionToken, Optional, Pipe, NgModule, EventEmitter, Input, HostListener, Output } from '@angular/core';
import { HttpClient, HttpHandler, HttpClientModule, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable, of, forkJoin } from 'rxjs';
import { DatePipe } from '@angular/common';
import { TranslateService } from '@ngx-translate/core';
import moment from 'moment';
import { plainToClass, deserialize, deserializeArray } from 'class-transformer';
import { map } from 'rxjs/operators';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class ColorService {
/**
* Creates a random color and return it as a hex string.
* @return {?}
*/
getColor() {
return this.getRandomColor();
}
/**
* Converts a hex string and opacity in percent to RGBA color as string.
* @param {?} hex
* @param {?} opacity
* @return {?}
*/
convertHexToRGBA(hex, opacity) {
hex = hex.replace('#', '');
/** @type {?} */
const r = parseInt(hex.substring(0, 2), 16);
/** @type {?} */
const g = parseInt(hex.substring(2, 4), 16);
/** @type {?} */
const b = parseInt(hex.substring(4, 6), 16);
return 'rgba(' + r + ',' + g + ',' + b + ',' + opacity / 100 + ')';
}
/**
* @return {?}
*/
getRandomColor() {
/** @type {?} */
const letters = '0123456789ABCDEF';
/** @type {?} */
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
}
ColorService.decorators = [
{ type: Injectable },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {number} */
const DatasetApiVersion = {
V1: 0,
V2: 1,
};
DatasetApiVersion[DatasetApiVersion.V1] = 'V1';
DatasetApiVersion[DatasetApiVersion.V2] = 'V2';
class DatasetApiMapping {
/**
* @param {?} http
*/
constructor(http) {
this.http = http;
this.cache = new Map();
}
/**
* @param {?} apiUrl
* @return {?}
*/
getApiVersion(apiUrl) {
return new Observable((observer) => {
if (this.cache.has(apiUrl)) {
this.confirmVersion(observer, this.cache.get(apiUrl));
}
else {
this.http.get(apiUrl).subscribe((result) => {
/** @type {?} */
let version = DatasetApiVersion.V1;
result.forEach((entry) => {
if (entry.id === 'platforms') {
version = DatasetApiVersion.V2;
}
});
this.cache.set(apiUrl, version);
this.confirmVersion(observer, version);
});
}
});
}
/**
* @param {?} observer
* @param {?} version
* @return {?}
*/
confirmVersion(observer, version) {
observer.next(version);
observer.complete();
}
}
DatasetApiMapping.decorators = [
{ type: Injectable },
];
/** @nocollapse */
DatasetApiMapping.ctorParameters = () => [
{ type: HttpClient }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class StatusIntervalResolverService {
constructor() { }
/**
* @param {?} value
* @param {?} statusIntervals
* @return {?}
*/
getMatchingInterval(value, statusIntervals) {
if (value && statusIntervals) {
return statusIntervals.find((interval) => {
/** @type {?} */
const upper = interval.upper ? parseFloat(interval.upper) : Number.MAX_VALUE;
/** @type {?} */
const lower = interval.lower ? parseFloat(interval.lower) : Number.MIN_VALUE;
if (lower <= value && value < upper) {
return true;
}
});
}
}
}
StatusIntervalResolverService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
StatusIntervalResolverService.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const HTTP_SERVICE_INTERCEPTORS = new InjectionToken('HTTP_SERVICE_INTERCEPTORS');
class HttpService {
/**
* @param {?} httpHandler
* @param {?} interceptors
*/
constructor(httpHandler, interceptors) {
this.httpHandler = httpHandler;
/** @type {?} */
let handler = {
handle: (req, options) => httpHandler.handle(req)
};
if (interceptors) {
handler = interceptors.reduceRight((next, interceptor) => ({
handle: (req, options) => interceptor.intercept(req, options, next)
}), handler);
}
this.handler = handler;
}
/**
* @param {?=} options
* @return {?}
*/
client(options = {}) {
return new HttpClient({
handle: (req) => this.handler.handle(req, options)
});
}
}
HttpService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
HttpService.ctorParameters = () => [
{ type: HttpHandler },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [HTTP_SERVICE_INTERCEPTORS,] }] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const INTERNAL_ID_SEPERATOR = '__';
/**
* Service to generate or resolve internal dataset IDs
*/
class InternalIdHandler {
/**
* Generates an internal id for the given dataset.
* @param {?} dataset The dataset for which the internal id will be generated and saved.
* @return {?}
*/
generateInternalId(dataset) {
dataset.internalId = dataset.url + INTERNAL_ID_SEPERATOR + dataset.id;
}
/**
* Resolves the internal ID to the url and the API specific dataset id.
* @param {?} internalId The internal id as string
* @return {?} Construct of url and API id
*/
resolveInternalId(internalId) {
/** @type {?} */
const split = internalId.split(INTERNAL_ID_SEPERATOR);
if (split.length !== 2) {
console.error('InternalID ' + internalId + ' is not resolvable');
}
else {
return {
url: split[0],
id: split[1]
};
}
}
}
InternalIdHandler.decorators = [
{ type: Injectable },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* LocalStorage save objects with a given key
*
* @export
*/
class LocalStorage {
constructor() {
this.localStorageEnabled = false;
if (typeof (Storage) !== 'undefined') {
this.localStorageEnabled = true;
}
}
/**
* Saves the object with the key in the local storage
*
* \@memberof LocalStorage
* @param {?} key
* @param {?} object
* @return {?} successfull saving
*/
save(key, object) {
if (this.localStorageEnabled) {
localStorage.setItem(key, JSON.stringify(object));
return true;
}
return false;
}
/**
* loads the object with for the key
*
* \@memberof LocalStorage
* @template T
* @param {?} key
* @return {?} the object if exists, else null
*/
load(key) {
if (this.localStorageEnabled) {
/** @type {?} */
const result = localStorage.getItem(key);
if (result) {
return JSON.parse(result);
}
return null;
}
}
/**
* loads an array of objects for the key
*
* \@memberof LocalStorage
* @template T
* @param {?} key
* @return {?} the array of objects if exists, else null
*/
loadArray(key) {
if (this.localStorageEnabled) {
/** @type {?} */
const result = localStorage.getItem(key);
if (result) {
return JSON.parse(result);
}
return null;
}
}
/**
* load a textual string for the given key
*
* \@memberof LocalStorage
* @param {?} key
* @return {?} the string if exists, else null
*/
loadTextual(key) {
if (this.localStorageEnabled) {
/** @type {?} */
const result = localStorage.getItem(key);
if (result) {
return result;
}
}
return null;
}
}
LocalStorage.decorators = [
{ type: Injectable },
];
/** @nocollapse */
LocalStorage.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
const ID = 'helgoland-notifier';
/** @type {?} */
const TIME_IN_MS = 3000;
class NotifierService {
constructor() {
/** @type {?} */
const notifierElement = document.getElementById(ID);
if (!notifierElement) {
/** @type {?} */
const node = document.createElement('div');
node.id = ID;
node.className = 'hide';
/** @type {?} */
const textNode = document.createTextNode('');
node.appendChild(textNode);
document.body.appendChild(node);
}
}
/**
* @param {?} text
* @return {?}
*/
notify(text) {
clearTimeout(this.notifierTimeout);
/** @type {?} */
const notifierElement = document.getElementById(ID);
notifierElement.innerHTML = text;
notifierElement.className = notifierElement.className.replace('hide', 'show');
this.notifierTimeout = setTimeout(() => {
notifierElement.className = notifierElement.className.replace('show', 'hide');
}, TIME_IN_MS);
}
}
NotifierService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
NotifierService.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class DateProxyPipe {
/**
* @param {?} translate
*/
constructor(translate) {
this.translate = translate;
}
/**
* @param {?} value
* @param {?=} pattern
* @return {?}
*/
transform(value, pattern = 'mediumDate') {
/** @type {?} */
const builtinDatePipe = new DatePipe(this.translate.currentLang || 'en');
try {
return builtinDatePipe.transform(value, pattern);
}
catch (error) {
console.error(error);
return new DatePipe('en').transform(value, pattern);
}
}
}
DateProxyPipe.decorators = [
{ type: Pipe, args: [{
name: 'dateI18n',
pure: false
},] },
];
/** @nocollapse */
DateProxyPipe.ctorParameters = () => [
{ type: TranslateService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class SumValuesService {
constructor() { }
/**
* @param {?} startOf
* @param {?} period
* @param {?} data
* @return {?}
*/
sum(startOf, period, data) {
/** @type {?} */
const result = [];
if (data.length === 0) {
return result;
}
/** @type {?} */
let currentBucketStart = moment(data[0][0]).startOf(startOf);
/** @type {?} */
let currentBucketEnd = moment(currentBucketStart).add(period).subtract(1, 'millisecond');
/** @type {?} */
let bucketVals = [];
for (let i = 0; i < data.length; i++) {
/** @type {?} */
const time = moment(data[i][0]);
/** @type {?} */
const value = data[i][1];
while (!(currentBucketStart.isSameOrBefore(time) && currentBucketEnd.isSameOrAfter(time))) {
if (bucketVals.length > 0) {
/** @type {?} */
let sum = 0;
/** @type {?} */
let hasValues = false;
bucketVals.forEach(e => {
if (typeof e === 'number') {
sum += e;
hasValues = true;
}
});
result.push([currentBucketStart.unix() * 1000, hasValues ? sum : 'NaN']);
}
else {
result.push([currentBucketStart.unix() * 1000, 'NaN']);
}
bucketVals = [];
currentBucketStart = currentBucketStart.add(period);
currentBucketEnd = currentBucketEnd.add(period);
}
bucketVals.push(value);
}
return result;
}
}
SumValuesService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
SumValuesService.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @abstract
*/
class TimeInterval {
}
class Timespan extends TimeInterval {
/**
* @param {?} from
* @param {?=} to
*/
constructor(from, to) {
super();
this.from = from;
if (to) {
this.to = to;
}
else {
this.to = from;
}
}
}
class BufferedTime extends TimeInterval {
/**
* @param {?} timestamp
* @param {?} bufferInterval
*/
constructor(timestamp, bufferInterval) {
super();
this.timestamp = timestamp;
this.bufferInterval = bufferInterval;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {string} */
const DefinedTimespan = {
LASTHOUR: 'last_hour',
TODAY: 'today',
YESTERDAY: 'yesterday',
TODAY_YESTERDAY: 'today_yesterday',
CURRENT_WEEK: 'current_week',
LAST_WEEK: 'last_week',
CURRENT_MONTH: 'current_month',
LAST_MONTH: 'last_month',
CURRENT_YEAR: 'current_year',
LAST_YEAR: 'last_year',
};
class DefinedTimespanService {
constructor() {
this.intervals = new Map();
this.intervals.set(DefinedTimespan.LASTHOUR, () => {
/** @type {?} */
const from = moment().subtract(1, 'hours').unix() * 1000;
/** @type {?} */
const to = moment().unix() * 1000;
return new Timespan(from, to);
});
this.intervals.set(DefinedTimespan.TODAY, () => {
/** @type {?} */
const from = moment().startOf('day').unix() * 1000;
/** @type {?} */
const to = moment().endOf('day').unix() * 1000;
return new Timespan(from, to);
});
this.intervals.set(DefinedTimespan.YESTERDAY, () => {
/** @type {?} */
const from = moment().subtract(1, 'days').startOf('day').unix() * 1000;
/** @type {?} */
const to = moment().subtract(1, 'days').endOf('day').unix() * 1000;
return new Timespan(from, to);
});
this.intervals.set(DefinedTimespan.TODAY_YESTERDAY, () => {
/** @type {?} */
const from = moment().subtract(1, 'days').startOf('day').unix() * 1000;
/** @type {?} */
const to = moment().endOf('day').unix() * 1000;
return new Timespan(from, to);
});
this.intervals.set(DefinedTimespan.CURRENT_WEEK, () => {
/** @type {?} */
const from = moment().startOf('isoWeek').unix() * 1000;
/** @type {?} */
const to = moment().endOf('isoWeek').unix() * 1000;
return new Timespan(from, to);
});
this.intervals.set(DefinedTimespan.LAST_WEEK, () => {
/** @type {?} */
const from = moment().subtract(1, 'weeks').startOf('isoWeek').unix() * 1000;
/** @type {?} */
const to = moment().subtract(1, 'weeks').endOf('isoWeek').unix() * 1000;
return new Timespan(from, to);
});
this.intervals.set(DefinedTimespan.CURRENT_MONTH, () => {
/** @type {?} */
const from = moment().startOf('month').unix() * 1000;
/** @type {?} */
const to = moment().endOf('month').unix() * 1000;
return new Timespan(from, to);
});
this.intervals.set(DefinedTimespan.LAST_MONTH, () => {
/** @type {?} */
const from = moment().subtract(1, 'months').startOf('month').unix() * 1000;
/** @type {?} */
const to = moment().subtract(1, 'months').endOf('month').unix() * 1000;
return new Timespan(from, to);
});
this.intervals.set(DefinedTimespan.CURRENT_YEAR, () => {
/** @type {?} */
const from = moment().startOf('year').unix() * 1000;
/** @type {?} */
const to = moment().endOf('year').unix() * 1000;
return new Timespan(from, to);
});
this.intervals.set(DefinedTimespan.LAST_YEAR, () => {
/** @type {?} */
const from = moment().subtract(1, 'years').startOf('year').unix() * 1000;
/** @type {?} */
const to = moment().subtract(1, 'years').endOf('year').unix() * 1000;
return new Timespan(from, to);
});
}
/**
* @param {?} intervalDescriber
* @return {?}
*/
getInterval(intervalDescriber) {
if (this.intervals.has(intervalDescriber)) {
return this.intervals.get(intervalDescriber)();
}
}
}
DefinedTimespanService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
DefinedTimespanService.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class Time {
/**
* @param {?} localStorage
*/
constructor(localStorage) {
this.localStorage = localStorage;
}
/**
* @param {?} timespan
* @param {?} date
* @return {?}
*/
centerTimespan(timespan, date) {
/** @type {?} */
const halfduration = this.getDuration(timespan).asMilliseconds() / 2;
/** @type {?} */
const from = moment(date).subtract(halfduration).unix() * 1000;
/** @type {?} */
const to = moment(date).add(halfduration).unix() * 1000;
return new Timespan(from, to);
}
/**
* @param {?} timespan
* @param {?} duration
* @return {?}
*/
centerTimespanWithDuration(timespan, duration) {
/** @type {?} */
const half = duration.asMilliseconds() / 2;
/** @type {?} */
const center = this.getCenterOfTimespan(timespan);
return new Timespan(center - half, center + half);
}
/**
* @param {?} timespan
* @return {?}
*/
getCenterOfTimespan(timespan) {
return timespan.from + (timespan.to - timespan.from) / 2;
}
/**
* @param {?} timespan
* @return {?}
*/
stepBack(timespan) {
/** @type {?} */
const duration = this.getDuration(timespan);
/** @type {?} */
const from = moment(timespan.from).subtract(duration).unix() * 1000;
/** @type {?} */
const to = moment(timespan.to).subtract(duration).unix() * 1000;
return new Timespan(from, to);
}
/**
* @param {?} timespan
* @return {?}
*/
stepForward(timespan) {
/** @type {?} */
const duration = this.getDuration(timespan);
/** @type {?} */
const from = moment(timespan.from).add(duration).unix() * 1000;
/** @type {?} */
const to = moment(timespan.to).add(duration).unix() * 1000;
return new Timespan(from, to);
}
/**
* @param {?} timeInterval
* @param {?} from
* @param {?} to
* @return {?}
*/
overlaps(timeInterval, from, to) {
/** @type {?} */
const timespan = this.createTimespanOfInterval(timeInterval);
if (timespan.from <= to && timespan.to >= from) {
return true;
}
return false;
}
/**
* @param {?} timeInterval
* @return {?}
*/
createTimespanOfInterval(timeInterval) {
if (timeInterval instanceof Timespan) {
return timeInterval;
}
else if (timeInterval instanceof BufferedTime) {
/** @type {?} */
const duration = moment.duration(timeInterval.bufferInterval / 2);
/** @type {?} */
const from = moment(timeInterval.timestamp).subtract(duration).unix() * 1000;
/** @type {?} */
const to = moment(timeInterval.timestamp).add(duration).unix() * 1000;
return new Timespan(from, to);
}
else {
console.error('Wrong time interval!');
}
}
/**
* @param {?} timespan
* @param {?} factor
* @return {?}
*/
getBufferedTimespan(timespan, factor) {
/** @type {?} */
const durationMillis = this.getDuration(timespan).asMilliseconds();
/** @type {?} */
const from = moment(timespan.from).subtract(durationMillis * factor).unix() * 1000;
/** @type {?} */
const to = moment(timespan.to).add(durationMillis * factor).unix() * 1000;
return new Timespan(from, to);
}
/**
* @param {?} param
* @param {?} timespan
* @return {?}
*/
saveTimespan(param, timespan) {
this.localStorage.save(param, timespan);
}
/**
* @param {?} param
* @return {?}
*/
loadTimespan(param) {
/** @type {?} */
const json = this.localStorage.load(param);
if (json) {
return plainToClass(Timespan, json);
}
return null;
}
/**
* @return {?}
*/
initTimespan() {
/** @type {?} */
const now = new Date();
/** @type {?} */
const start = moment(now).startOf('day').unix() * 1000;
/** @type {?} */
const end = moment(now).endOf('day').unix() * 1000;
return new Timespan(start, end);
}
/**
* @param {?} timespan
* @return {?}
*/
getDuration(timespan) {
/** @type {?} */
const from = moment(timespan.from);
/** @type {?} */
const to = moment(timespan.to);
return moment.duration(to.diff(from));
}
}
Time.decorators = [
{ type: Injectable },
];
/** @nocollapse */
Time.ctorParameters = () => [
{ type: LocalStorage }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class HelgolandCoreModule {
}
HelgolandCoreModule.decorators = [
{ type: NgModule, args: [{
declarations: [
DateProxyPipe
],
imports: [
HttpClientModule
],
exports: [
DateProxyPipe
],
providers: [
ColorService,
DatasetApiMapping,
DefinedTimespanService,
InternalIdHandler,
LocalStorage,
NotifierService,
StatusIntervalResolverService,
SumValuesService,
HttpService,
Time
]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @abstract
*/
class ApiInterface {
/**
* @param {?} apiUrl
* @param {?} endpoint
* @param {?=} id
* @return {?}
*/
createRequestUrl(apiUrl, endpoint, id) {
/** @type {?} */
let requestUrl = apiUrl + endpoint;
if (id) {
requestUrl += '/' + id;
}
return requestUrl;
}
/**
* @param {?} timespan
* @return {?}
*/
createRequestTimespan(timespan) {
return encodeURI(moment(timespan.from).format() + '/' + moment(timespan.to).format());
}
/**
* @param {?} token
* @return {?}
*/
createBasicAuthHeader(token) {
/** @type {?} */
const headers = new HttpHeaders();
if (token) {
return headers.set('Authorization', token);
}
return headers;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
// unsupported: template constraints.
/**
* @abstract
* @template T
*/
class DatasetService {
constructor() {
this.datasetIds = [];
this.datasetOptions = new Map();
this.datasetIdsChanged = new EventEmitter();
}
/**
* Adds the dataset to the selection
*
* @param {?} internalId
* @param {?=} options
* @return {?} Successfull added the dataset.
*/
addDataset(internalId, options) {
if (this.datasetIds.indexOf(internalId) < 0) {
this.datasetIds.push(internalId);
if (options) {
this.datasetOptions.set(internalId, options);
}
else {
this.datasetOptions.set(internalId, this.createStyles(internalId));
}
this.saveState();
}
else if (options instanceof Array) {
/** @type {?} */
const temp = (/** @type {?} */ (this.datasetOptions.get(internalId)));
options.forEach((e) => temp.push(e));
this.saveState();
}
this.datasetIdsChanged.emit(this.datasetIds);
return of(true);
}
/**
* @return {?}
*/
removeAllDatasets() {
this.datasetIds.length = 0;
this.datasetOptions.clear();
this.datasetIdsChanged.emit(this.datasetIds);
this.saveState();
}
/**
* @param {?} internalId
* @return {?}
*/
removeDataset(internalId) {
/** @type {?} */
const datasetIdx = this.datasetIds.indexOf(internalId);
if (datasetIdx > -1) {
this.datasetIds.splice(datasetIdx, 1);
this.datasetOptions.delete(internalId);
}
this.datasetIdsChanged.emit(this.datasetIds);
this.saveState();
}
/**
* @return {?}
*/
hasDatasets() {
return this.datasetIds.length > 0;
}
/**
* @param {?} id
* @return {?}
*/
hasDataset(id) {
return this.datasetIds.indexOf(id) >= 0;
}
/**
* @param {?} options
* @param {?} internalId
* @return {?}
*/
updateDatasetOptions(options, internalId) {
this.datasetOptions.set(internalId, options);
this.saveState();
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
// unsupported: template constraints.
/**
* @abstract
* @template T
*/
class RenderingHintsDatasetService extends DatasetService {
/**
* @param {?} api
*/
constructor(api) {
super();
this.api = api;
}
/**
* @param {?} internalId
* @param {?=} options
* @return {?}
*/
addDataset(internalId, options) {
return new Observable((observer) => {
if (options) {
this.datasetIds.push(internalId);
this.datasetOptions.set(internalId, options);
observer.next(true);
observer.complete();
this.datasetIdsChanged.emit(this.datasetIds);
}
else if (this.datasetIds.indexOf(internalId) < 0) {
this.api.getSingleTimeseriesByInternalId(internalId).subscribe((timeseries) => this.addLoadedDataset(timeseries, observer), (error) => {
this.api.getDatasetByInternalId(internalId).subscribe((dataset) => this.addLoadedDataset(dataset, observer));
});
}
});
}
/**
* @param {?} dataset
* @param {?} observer
* @return {?}
*/
addLoadedDataset(dataset, observer) {
this.datasetIds.push(dataset.internalId);
this.datasetOptions.set(dataset.internalId, this.createOptionsOfRenderingHints(dataset));
observer.next(true);
observer.complete();
this.datasetIdsChanged.emit(this.datasetIds);
this.saveState();
}
/**
* @param {?} dataset
* @return {?}
*/
createOptionsOfRenderingHints(dataset) {
/** @type {?} */
const options = /** @type {?} */ (this.createStyles(dataset.internalId));
if (dataset.renderingHints) {
if (dataset.renderingHints.properties && dataset.renderingHints.properties.color) {
options.color = dataset.renderingHints.properties.color;
}
switch (dataset.renderingHints.chartType) {
case 'line':
this.handleLineRenderingHints(/** @type {?} */ (dataset.renderingHints), options);
break;
case 'bar':
this.handleBarRenderingHints(/** @type {?} */ (dataset.renderingHints), options);
break;
default:
break;
}
}
return /** @type {?} */ (options);
}
/**
* @param {?} lineHints
* @param {?} options
* @return {?}
*/
handleLineRenderingHints(lineHints, options) {
if (lineHints.properties.width) {
options.lineWidth = Math.round(parseFloat(lineHints.properties.width));
}
}
/**
* @param {?} barHints
* @param {?} options
* @return {?}
*/
handleBarRenderingHints(barHints, options) {
if (barHints.properties.width) {
options.lineWidth = Math.round(parseFloat(barHints.properties.width));
}
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class UriParameterCoder {
/**
* @param {?} key
* @return {?}
*/
encodeKey(key) {
return encodeURIComponent(key);
}
/**
* @param {?} value
* @return {?}
*/
encodeValue(value) {
return encodeURIComponent(value);
}
/**
* @param {?} key
* @return {?}
*/
decodeKey(key) {
return key;
}
/**
* @param {?} value
* @return {?}
*/
decodeValue(value) {
return value;
}
}
/**
* @abstract
*/
class DatasetApiInterface extends ApiInterface {
/**
* @param {?} httpService
* @param {?} translate
*/
constructor(httpService, translate) {
super();
this.httpService = httpService;
this.translate = translate;
}
/**
* @template T
* @param {?} url
* @param {?=} params
* @param {?=} options
* @return {?}
*/
requestApi(url, params = {}, options = {}) {
return this.httpService.client(options).get(url, {
params: this.prepareParams(params),
headers: this.createBasicAuthHeader(options.basicAuthToken)
});
}
/**
* @param {?} params
* @return {?}
*/
prepareParams(params) {
if (this.translate && this.translate.currentLang) {
params["locale"] = this.translate.currentLang;
}
/** @type {?} */
let httpParams = new HttpParams({
encoder: new UriParameterCoder()
});
Object.getOwnPropertyNames(params)
.forEach((key) => httpParams = httpParams.set(key, params[key]));
return httpParams;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class ParameterConstellation {
}
class FirstLastValue {
}
class ReferenceValue {
}
class DatasetParameterConstellation extends ParameterConstellation {
}
class Dataset {
}
class Timeseries {
constructor() {
this.hasData = false;
}
}
class TimeseriesData {
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class DatasetImplApiInterface extends DatasetApiInterface {
/**
* @param {?} httpservice
* @param {?} internalDatasetId
* @param {?} translate
*/
constructor(httpservice, internalDatasetId, translate) {
super(httpservice, translate);
this.httpservice = httpservice;
this.internalDatasetId = internalDatasetId;
this.translate = translate;
}
/**
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getServices(apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'services');
if (params) {
params.expanded = true;
}
else {
params = { expanded: true };
}
return this.requestApi(url, params, options).pipe(map((result) => {
result.forEach((entry) => entry.apiUrl = apiUrl);
return result;
}));
}
/**
* @param {?} id
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getService(id, apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'services', id);
return this.requestApi(url, params, options).pipe(map((result) => {
result.apiUrl = apiUrl;
return result;
}));
}
/**
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getStations(apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'stations');
return this.requestApi(url, params, options);
}
/**
* @param {?} id
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getStation(id, apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'stations', id);
return this.requestApi(url, params, options);
}
/**
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getTimeseries(apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'timeseries');
return new Observable((observer) => {
this.requestApiTexted(url, params, options).subscribe((result) => {
/** @type {?} */
const timeseriesList = deserializeArray(Timeseries, result);
timeseriesList.forEach((entry) => {
entry.url = apiUrl;
this.internalDatasetId.generateInternalId(entry);
});
observer.next(timeseriesList);
}, (error) => observer.error(error), () => observer.complete());
});
}
/**
* @param {?} apiUrl
* @param {?} ids
* @param {?} timespan
* @param {?=} options
* @return {?}
*/
getTimeseriesData(apiUrl, ids, timespan, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'timeseries/getData');
return new Observable((observer) => {
this.requestApiTextedPost(url, {
timespan: this.createRequestTimespan(timespan),
timeseries: ids
}, options).subscribe((result) => {
/** @type {?} */
const timeseriesList = [];
for (const id in result) {
if (id) {
timeseriesList.push({
id: id,
url: apiUrl,
data: result[id].values
});
}
}
observer.next(timeseriesList);
}, (error) => observer.error(error), () => observer.complete());
});
}
/**
* @param {?} id
* @param {?} apiUrl
* @param {?=} params
* @return {?}
*/
getSingleTimeseries(id, apiUrl, params) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'timeseries', id);
return this.requestApiTexted(url, params).pipe(map((result) => {
/** @type {?} */
const timeseries = deserialize(Timeseries, result);
timeseries.url = apiUrl;
this.internalDatasetId.generateInternalId(timeseries);
return timeseries;
}));
}
/**
* @param {?} internalId
* @param {?=} params
* @return {?}
*/
getSingleTimeseriesByInternalId(internalId, params) {
/** @type {?} */
const resolvedId = this.internalDatasetId.resolveInternalId(internalId);
return this.getSingleTimeseries(resolvedId.id, resolvedId.url, params);
}
/**
* @param {?} id
* @param {?} apiUrl
* @return {?}
*/
getTimeseriesExtras(id, apiUrl) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'timeseries', id);
return this.requestApi(url + '/extras');
}
/**
* @template T
* @param {?} id
* @param {?} apiUrl
* @param {?} timespan
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getTsData(id, apiUrl, timespan, params = {}, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'timeseries', id) + '/getData';
params.timespan = this.createRequestTimespan(timespan);
return this.requestApi(url, params, options).pipe(map((res) => {
if (params.expanded) {
res = res[id];
}
return res;
}));
}
/**
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getCategories(apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'categories');
return this.requestApi(url, params, options);
}
/**
* @param {?} id
* @param {?} apiUrl
* @param {?=} params
* @return {?}
*/
getCategory(id, apiUrl, params) {
// const url = this.createRequestUrl(apiUrl, 'categories', id);
throw new Error('Not implemented');
// return this.requestApi(url, params)
// .map(this.extractData);
}
/**
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getPhenomena(apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'phenomena');
return this.requestApi(url, params, options);
}
/**
* @param {?} id
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getPhenomenon(id, apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'phenomena', id);
return this.requestApi(url, params, options);
}
/**
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getOfferings(apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'offerings');
return this.requestApi(url, params, options);
}
/**
* @param {?} id
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getOffering(id, apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'offerings', id);
return this.requestApi(url, params, options);
}
/**
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getFeatures(apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'features');
return this.requestApi(url, params, options);
}
/**
* @param {?} id
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getFeature(id, apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'features', id);
return this.requestApi(url, params, options);
}
/**
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getProcedures(apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'procedures');
return this.requestApi(url, params, options);
}
/**
* @param {?} id
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getProcedure(id, apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'procedures', id);
return this.requestApi(url, params, options);
}
/**
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getPlatforms(apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'platforms');
return this.requestApi(url, params, options);
}
/**
* @param {?} id
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getPlatform(id, apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'platforms', id);
return this.requestApi(url, params, options);
}
/**
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getDatasets(apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'datasets');
return this.requestApi(url, params, options).pipe(map((list) => list.map((entry) => this.prepareDataset(entry, apiUrl))));
}
/**
* @param {?} id
* @param {?} apiUrl
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getDataset(id, apiUrl, params, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'datasets', id);
return this.requestApi(url, params, options).pipe(map((res) => this.prepareDataset(res, apiUrl)));
}
/**
* @param {?} internalId
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getDatasetByInternalId(internalId, params, options) {
/** @type {?} */
const resolvedId = this.internalDatasetId.resolveInternalId(internalId);
return this.getDataset(resolvedId.id, resolvedId.url, params, options);
}
/**
* @template T
* @param {?} id
* @param {?} apiUrl
* @param {?} timespan
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getData(id, apiUrl, timespan, params = {}, options) {
/** @type {?} */
const url = this.createRequestUrl(apiUrl, 'datasets', id) + '/data';
params.timespan = this.createRequestTimespan(timespan);
return this.requestApi(url, params, options);
}
/**
* @param {?} url
* @param {?=} params
* @param {?=} options
* @return {?}
*/
requestApiTexted(url, params = {}, options = {}) {
return this.httpservice.client(options).get(url, {
params: this.prepareParams(params),
responseType: 'text'
});
}
/**
* @param {?} url
* @param {?=} params
* @param {?=} options
* @return {?}
*/
requestApiTextedPost(url, params = {}, options = {}) {
return this.httpservice.client().post(url, params, {
responseType: 'json'
});
}
/**
* @param {?} datasetObj
* @param {?} apiUrl
* @return {?}
*/
prepareDataset(datasetObj, apiUrl) {
/** @type {?} */
const dataset = deserialize(Dataset, JSON.stringify(datasetObj));
dataset.url = apiUrl;
this.internalDatasetId.generateInternalId(dataset);
if (dataset.seriesParameters) {
dataset.parameters = dataset.seriesParameters;
delete dataset.seriesParameters;
}
return dataset;
}
}
DatasetImplApiInterface.decorators = [
{ type: Injectable },
];
/** @nocollapse */
DatasetImplApiInterface.ctorParameters = () => [
{ type: HttpService },
{ type: InternalIdHandler },
{ type: TranslateService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class SplittedDataDatasetApiInterface extends DatasetImplApiInterface {
/**
* @param {?} httpservice
* @param {?} internalDatasetId
* @param {?} translate
*/
constructor(httpservice, internalDatasetId, translate) {
super(httpservice, internalDatasetId, translate);
this.httpservice = httpservice;
this.internalDatasetId = internalDatasetId;
this.translate = translate;
}
/**
* @template T
* @param {?} id
* @param {?} apiUrl
* @param {?} timespan
* @param {?=} params
* @param {?=} options
* @return {?}
*/
getTsData(id, apiUrl, timespan, params = {}, options) {
/** @type {?} */
const maxTimeExtent = moment.duration(1, 'year').asMilliseconds();
if ((timespan.to - timespan.from) > maxTimeExtent) {
/** @type {?} */
const requests = [];
/** @type {?} */
let start = moment(timespan.from).startOf('year');
/** @type {?} */
let end = moment(timespan.from).endOf('year');
while (start.isBefore(moment(timespan.to))) {
/** @type {?} */
const chunkSpan = new Timespan(start.unix() * 1000, end.unix() * 1000);
requests.push(super.getTsData(id, apiUrl, chunkSpan, params, options));
start = end.add(1, 'millisecond');
end = moment(start).endOf('year');
}
return forkJoin(requests).pipe(map((entry) => {
return entry.reduce((previous, current) => {
/** @type {?} */
const next = {
referenceValues: {},
values: previous.values.concat(current.values)
};
for (const key in previous.referenceValues) {
if (previous.referenceValues.hasOwnProperty(key)) {
next.referenceValues[key] = previous.referenceValues[key].concat(current.referenceValues[key]);
}
}
return next;
});
}));
}
else {
return super.getTsData(id, apiUrl, timespan, params, options);
}
}
}
SplittedDataDatasetApiInterface.decorators = [
{ type: Injectable },
];
/** @nocollapse */
SplittedDataDatasetApiInterface.ctorParameters = () => [
{ type: HttpService },
{ type: InternalIdHandler },
{ type: TranslateService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @abstract
*/
class LanguageChangNotifier {
/**
* @param {?} translate
*/
constructor(translate) {
this.translate = translate;
this.translate.onLangChange.subscribe(() => this.languageChanged());
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @abstract
*/
class LocalSelectorComponent {
/**
* @param {?} translate
*/
constructor(translate) {
this.translate = translate;
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
if (changes["languageList"]) {
this.setCurrentLang();
}
}
/**
* @param {?} lang
* @return {?}
*/
setLanguage(lang) {
this.translate.use(lang.code);
this.setCurrentLang();
}
/**
* @return {?}
*/
setCurrentLang() {
this.currentLang = this.languageList.find((e) => e.code === this.translate.currentLang);
}
}
LocalSelectorComponent.propDecorators = {
languageList: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
// unsupported: template constraints.
/**
* @template T
*/
class ReferenceValues {
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class Station {
}
class TimeseriesCollection {
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {string} */
const PlatformTypes = {
stationary: 'stationary',
mobile: 'mobile',
mobileInsitu: 'mobile_insitu',
};
/** @enum {string} */
const ValueTypes = {
quantity: 'quantity',
quantityProfile: 'quantity-profile',
};
/** @enum {number} */
const DatasetTypes = {
measurement: 0,
};
DatasetTypes[DatasetTypes.measurement] = 'measurement';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class Filter {
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* Options for each dataset.
*
* @export
*/
class DatasetOption