import {
AfterViewInit,
Component,
DoCheck,
Input,
IterableDiffer,
IterableDiffers,
OnInit,
ViewEncapsulation,
} from '@angular/core';
import {
ColorService,
DatasetOptions,
HelgolandServicesConnector,
InternalIdHandler,
SumValuesService,
Time,
TimezoneService,
} from '@helgoland/core';
import { TranslateService } from '@ngx-translate/core';
import { D3TimeseriesGraphComponent } from '../d3-timeseries-graph/d3-timeseries-graph.component';
import { D3GraphHelperService } from '../helper/d3-graph-helper.service';
import { D3GraphId } from '../helper/d3-graph-id.service';
import { D3TimeFormatLocaleService } from '../helper/d3-time-format-locale.service';
import { InternalDataEntry } from '../model/d3-general';
import { D3Graphs } from './../helper/d3-graphs.service';
import { RangeCalculationsService } from './../helper/range-calculations.service';
export interface AdditionalData {
linkedDatasetId?: string;
yaxisLabel?: string;
datasetOptions?: DatasetOptions;
internalId: string;
data: AdditionalDataEntry[];
}
export interface AdditionalDataEntry {
timestamp: number;
value: number;
}
@Component({
selector: 'n52-extended-data-d3-timeseries-graph',
templateUrl: '../d3-timeseries-graph/d3-timeseries-graph.component.html',
styleUrls: ['../d3-timeseries-graph/d3-timeseries-graph.component.scss'],
providers: [D3GraphId],
encapsulation: ViewEncapsulation.None
})
export class ExtendedDataD3TimeseriesGraphComponent extends D3TimeseriesGraphComponent implements DoCheck, AfterViewInit, OnInit {
@Input()
public additionalData: AdditionalData[] = [];
private additionalDataDiffer: IterableDiffer<AdditionalData>;
constructor(
protected iterableDiffers: IterableDiffers,
protected datasetIdResolver: InternalIdHandler,
protected timeSrvc: Time,
protected timeFormatLocaleService: D3TimeFormatLocaleService,
protected colorService: ColorService,
protected translateService: TranslateService,
protected timezoneSrvc: TimezoneService,
protected sumValues: SumValuesService,
protected rangeCalc: RangeCalculationsService,
protected graphHelper: D3GraphHelperService,
protected graphService: D3Graphs,
protected graphId: D3GraphId,
protected servicesConnector: HelgolandServicesConnector
) {
super(
iterableDiffers,
datasetIdResolver,
timeSrvc,
timeFormatLocaleService,
colorService,
translateService,
timezoneSrvc,
sumValues,
rangeCalc,
graphHelper,
graphService,
graphId,
servicesConnector
);
}
public ngOnInit(): void {
this.additionalDataDiffer = this.iterableDiffers.find(this.additionalData).create();
}
public ngDoCheck() {
super.ngDoCheck();
const additionalDataChanges = this.additionalDataDiffer.diff(this.additionalData);
if (additionalDataChanges && this.additionalData && this.graph) {
additionalDataChanges.forEachRemovedItem((removedItem) => {
const id = this.generateAdditionalInternalId(removedItem.item);
const spliceIdx = this.preparedData.findIndex((entry) => entry.internalId === id);
if (spliceIdx >= 0) {
this.preparedData.splice(spliceIdx, 1);
}
});
this.redrawCompleteGraph();
}
}
public redrawCompleteGraph() {
this.prepareAdditionalData();
super.redrawCompleteGraph();
}
public ngAfterViewInit(): void {
super.ngAfterViewInit();
}
protected timeIntervalChanges(): void {
if (this.datasetMap.size > 0) {
super.timeIntervalChanges();
} else {
this.redrawCompleteGraph();
}
}
protected prepareYAxes() {
super.prepareYAxes();
this.additionalData.forEach(entry => {
const id = this.generateAdditionalInternalId(entry);
this.createYAxisForId(id);
});
}
private prepareAdditionalData() {
if (this.additionalData) {
this.additionalData.forEach(entry => {
if ((entry.linkedDatasetId || entry.yaxisLabel) && entry.data && entry.data.length > 0) {
const options = entry.datasetOptions || this.datasetOptions.get(entry.linkedDatasetId);
const dataset = this.datasetMap.get(entry.linkedDatasetId);
const prepDataIdx = this.preparedData.findIndex(e => e.internalId.indexOf(entry.linkedDatasetId) > -1 || e.internalId.indexOf(entry.internalId) > -1);
let dataEntry: InternalDataEntry;
if (prepDataIdx === -1) {
dataEntry = {
internalId: this.generateAdditionalInternalId(entry),
hoverId: `hov-${Math.random().toString(36).substr(2, 9)}`,
options,
data: options.visible ? entry.data.map(e => ({ timestamp: e.timestamp, value: e.value })) : [],
axisOptions: {
uom: dataset ? dataset.uom : entry.yaxisLabel,
label: dataset ? dataset.label : entry.yaxisLabel,
zeroBased: options.zeroBasedYAxis,
yAxisRange: options.yAxisRange,
autoRangeSelection: options.autoRangeSelection,
separateYAxis: options.separateYAxis
},
referenceValueData: [],
visible: options.visible
};
if (dataset) {
dataEntry.axisOptions.parameters = {
feature: dataset.parameters.feature,
phenomenon: dataset.parameters.phenomenon,
offering: dataset.parameters.offering
};
}
this.preparedData.push(dataEntry);
} else {
dataEntry = this.preparedData[prepDataIdx];
dataEntry.axisOptions.uom = dataset ? dataset.uom : entry.yaxisLabel;
dataEntry.axisOptions.label = dataset ? dataset.label : entry.yaxisLabel;
dataEntry.data = options.visible ? entry.data.map(e => ({ timestamp: e.timestamp, value: e.value })) : [];
}
this.processData(dataEntry);
} else {
console.warn('Please check the additional entry, it needs at least a \'linkedDatasetId\' or a \'yaxisLabel\' property and a \'data\' property: ', entry);
}
});
}
}
private generateAdditionalInternalId(entry: AdditionalData): string {
return entry.linkedDatasetId ? entry.linkedDatasetId + 'add' : entry.internalId + 'add';
}
}