diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index bda6653..6c2faf1 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -36,6 +36,7 @@ import {MatBadgeModule} from '@angular/material/badge';
import { TimeService } from '../common/core/time/time.service';
import { InternalIdHandler } from '../common/components/services/internal-id-handler.service';
+import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
@NgModule({
// declarations: The components, directives, and pipes that belong to this NgModule.
@@ -44,7 +45,9 @@ import { InternalIdHandler } from '../common/components/services/internal-id-han
// DatasetByStationSelectorComponent
// ],
// imports: Other modules whose exported classes are needed by component templates declared in this NgModule.
- imports: [BrowserModule, HttpClientModule, AppRoutingModule, ComponentsModule, GraphjsModule, BrowserAnimationsModule, MatDialogModule, MatListModule, MatBadgeModule],
+ imports: [
+ BrowserModule, HttpClientModule, AppRoutingModule, ComponentsModule, GraphjsModule, BrowserAnimationsModule, MatDialogModule, MatListModule, MatBadgeModule,
+ FontAwesomeModule],
providers: [
MarkerService, PopupService, HttpService, DatasetApiService, StationService, MessageService, MapService,DatasetService, InternalIdHandler, TimeService
diff --git a/src/app/components/legend-entry/legend-entry.component.html b/src/app/components/legend-entry/legend-entry.component.html
index 5dfc2f1..7590e1b 100644
--- a/src/app/components/legend-entry/legend-entry.component.html
+++ b/src/app/components/legend-entry/legend-entry.component.html
@@ -1,6 +1,6 @@
+ [ngClass]="{'selected': selected}" (click)="toggleSelection();">
@@ -36,6 +36,11 @@
+
+
+
+
+
diff --git a/src/app/components/legend-entry/legend-entry.component.ts b/src/app/components/legend-entry/legend-entry.component.ts
index 9979cb7..1605094 100644
--- a/src/app/components/legend-entry/legend-entry.component.ts
+++ b/src/app/components/legend-entry/legend-entry.component.ts
@@ -6,6 +6,8 @@ import { TimeInterval } from '../../../shared/models/timespan';
import { DatasetApiService } from '../../services/dataset-api.service';
import { InternalIdHandler, InternalDatasetId } from '../../../common/components/services/internal-id-handler.service';
import { DatasetOptions } from '../../../shared/models/options';
+import { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
+
@Component({
selector: 'geomon-legend-entry',
templateUrl: './legend-entry.component.html',
@@ -18,6 +20,9 @@ export class LegendEntryComponent {
@Output()
public onSelectDate: EventEmitter = new EventEmitter();
+ faEye = faEye;
+ faEyeSlash= faEyeSlash;
+
// public firstValue: FirstLastValue;
// public lastValue: FirstLastValue;
public hasData = true;
diff --git a/src/common/graphjs/geomon-timeseries-chart/geomon-timeseries-chart.component.scss b/src/common/graphjs/geomon-timeseries-chart/geomon-timeseries-chart.component.scss
index 392e9b5..487449c 100644
--- a/src/common/graphjs/geomon-timeseries-chart/geomon-timeseries-chart.component.scss
+++ b/src/common/graphjs/geomon-timeseries-chart/geomon-timeseries-chart.component.scss
@@ -16,5 +16,5 @@
#line-chart {
- border: 1px solid black;
+ // border: 1px solid black;
}
\ No newline at end of file
diff --git a/src/common/graphjs/geomon-timeseries-chart/geomon-timeseries-chart.component.ts b/src/common/graphjs/geomon-timeseries-chart/geomon-timeseries-chart.component.ts
index aa2c565..941d0d1 100644
--- a/src/common/graphjs/geomon-timeseries-chart/geomon-timeseries-chart.component.ts
+++ b/src/common/graphjs/geomon-timeseries-chart/geomon-timeseries-chart.component.ts
@@ -1,4 +1,6 @@
-import { Input, Component, AfterViewInit, ViewChild, ElementRef, SimpleChanges, DoCheck, IterableDiffer} from '@angular/core';
+import {
+ Input, Component, AfterViewInit, ViewChild, ElementRef, SimpleChanges, DoCheck, IterableDiffer, IterableDiffers
+} from '@angular/core';
// import * as d3 from 'd3';
import { Chart, registerables } from 'chart.js';
@@ -19,6 +21,7 @@ import zoomPlugin from 'chartjs-plugin-zoom';
Chart.register(zoomPlugin);
import { InternalIdHandler, InternalDatasetId } from '../../../common/components/services/internal-id-handler.service';
+import { InternalDataEntry } from '../../../shared/models/chart';
// interface Color {
// borderColor: string,
// pointBackgroundColor: string
@@ -71,6 +74,7 @@ export class GeomonTimeseriesChartComponent implements AfterViewInit, DoCheck {
// data types
protected datasetMap: Map = new Map();
protected listOfUoms: string[] = [];
+ protected preparedData: InternalDataEntry[] = [];
// private loadingData: Set = new Set();
@@ -87,36 +91,40 @@ export class GeomonTimeseriesChartComponent implements AfterViewInit, DoCheck {
private selectedDatasetIdsDiffer: IterableDiffer;
constructor(
+ protected iterableDiffers: IterableDiffers,
protected datasetIdResolver: InternalIdHandler,
protected datasetApiService: DatasetApiService,
protected timeService: TimeService,
public datasetService: DatasetService,
- ) { }
+ ) {
+ this.selectedDatasetIdsDiffer = this.iterableDiffers.find([]).create();
+ }
public ngDoCheck(): void {
- // const selectedDatasetIdsChanges = this.selectedDatasetIdsDiffer.diff(this.selectedDatasetIds);
- // if (selectedDatasetIdsChanges) {
- // selectedDatasetIdsChanges.forEachAddedItem((addedItem) => {
- // this.setSelectedId(addedItem.item);
- // });
- // selectedDatasetIdsChanges.forEachRemovedItem((removedItem) => {
- // this.removeSelectedId(removedItem.item);
- // });
- // }
+ const selectedDatasetIdsChanges = this.selectedDatasetIdsDiffer.diff(this.selectedDatasetIds);
+ if (selectedDatasetIdsChanges) {
+ selectedDatasetIdsChanges.forEachAddedItem((addedItem) => {
+ this.setSelectedId(addedItem.item);
+ });
+ selectedDatasetIdsChanges.forEachRemovedItem((removedItem) => {
+ this.removeSelectedId(removedItem.item);
+ });
+ }
}
protected setSelectedId(internalId: string): void {
- // const internalEntry = this.preparedData.find((e) => e.internalId === internalId);
- // if (internalEntry) { internalEntry.selected = true; }
- // this.redrawCompleteGraph();
+ const internalEntry = this.preparedData.find((e) => e.internalId === internalId);
+ if (internalEntry) { internalEntry.selected = true; }
+ this.redrawCompleteGraph();
}
protected removeSelectedId(internalId: string): void {
- // const internalEntry = this.preparedData.find((e) => e.internalId === internalId);
- // if (internalEntry) { internalEntry.selected = false; }
+ const internalEntry = this.preparedData.find((e) => e.internalId === internalId);
+ if (internalEntry) { internalEntry.selected = false; }
+ this.redrawCompleteGraph();
}
- ngAfterViewInit(): void { // this.createSvg();
+ ngAfterViewInit(): void {
this.canvas = document.getElementById("line-chart") as HTMLCanvasElement;
@@ -210,7 +218,7 @@ export class GeomonTimeseriesChartComponent implements AfterViewInit, DoCheck {
if (rawdata.valueBeforeTimespan) { rawdata.values.unshift(rawdata.valueBeforeTimespan); }
if (rawdata.valueAfterTimespan) { rawdata.values.push(rawdata.valueAfterTimespan); }
- const data = this.generalizeData(rawdata, this.width, this.timespan);
+ // const data = this.generalizeData(rawdata, this.width, this.timespan);
let grouped_items = groupBy(rawdata.values, function (b: TimeValueTuple) {
@@ -303,19 +311,99 @@ export class GeomonTimeseriesChartComponent implements AfterViewInit, DoCheck {
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
+
+ const datasetIdx = this.preparedData.findIndex((e) => e.internalId === dataset.internalId);
let datasetOptions = this.datasetOptions.get(dataset.internalId);
datasetOptions.color = color;
- var newDataset = {
- label: dataset.label,
- // backgroundColor: 'rgba(99, 255, 132, 0.2)',
- backgroundColor: color,
- borderColor: color, //'rgba(99, 255, 132, 1)',
- borderWidth: 1,
+
+ let dataEntry: InternalDataEntry = {
+ internalId: dataset.internalId,
+ selected: this.selectedDatasetIds.indexOf(dataset.internalId) >= 0,
+ // data: datasetOptions.visible ? data.values.map(d => ({ timestamp: d[0], value: d[1] })) : [],
data: values,
+ options: datasetOptions,
+ axisOptions: {
+ uom: dataset.uom,
+ label: dataset.label,
+ zeroBased: datasetOptions.zeroBasedYAxis,
+ // yAxisRange: options.yAxisRange,
+ autoRangeSelection: datasetOptions.autoRangeSelection,
+ separateYAxis: datasetOptions.separateYAxis,
+ parameters: {
+ feature: dataset.parameters.feature,
+ phenomenon: dataset.parameters.phenomenon,
+ offering: dataset.parameters.offering
+ }
+ },
+ referenceValueData: [],
+ visible: datasetOptions.visible,
+ // bar: barConfig
+ };
+
+ if (datasetIdx >= 0) {
+ this.preparedData[datasetIdx] = dataEntry;
+ } else {
+ this.preparedData.push(dataEntry);
}
- // You add the newly created dataset to the list of `data`
- chart.data.datasets.push(newDataset);
- chart.options.scales.x.ticks.callback = (val, index) => {
+
+ this.processData(dataEntry);
+ // this.redrawCompleteGraph();
+
+ // var newDataset = {
+ // label: dataEntry.axisOptions.label,
+ // selected: dataEntry.selected,
+ // backgroundColor: color,
+ // borderColor: color,
+ // borderWidth: 1,
+ // data: values,
+ // }
+ // // You add the newly created dataset to the list of `data`
+ // chart.data.datasets.push(newDataset);
+ // chart.options.scales.x.ticks.callback = (val, index) => {
+ // // // Hide the label of every 2nd dataset
+ // // return xLabels.includes(val.toString()) ? val : null;
+ // // return index % 2 === 0 ? (val) : '';
+ // let valTime = moment(val, "DD/MM HH:mm").format("HH:mm");
+ // if (valTime == "08:00" || valTime == "18:00"){
+ // return val;
+ // } else {
+ // return null;
+ // }
+
+ // }
+ // chart.options.scales.y.ticks.callback = (value, index, values) => {
+ // return value + '°';
+ // }
+
+ chart.update();
+ this.width = this.calculateWidth();
+ }
+
+ private processData(dataEntry: InternalDataEntry, datasetIndex?: number): void {
+
+ let dataset;
+
+ if (datasetIndex != null) {
+ dataset = this.lineChart.data.datasets[datasetIndex];
+ dataset.label = dataEntry.axisOptions.label;
+ dataset.borderWidth = dataEntry.selected ? 4 : 1;
+ // dataset.hidden = dataEntry.selected;
+ } else {
+ dataset = {
+ label: dataEntry.axisOptions.label,
+ // selected: dataEntry.selected,
+ // backgroundColor: 'rgba(99, 255, 132, 0.2)',
+ backgroundColor: dataEntry.options.color,
+ borderColor: dataEntry.options.color, //'rgba(99, 255, 132, 1)',
+ borderWidth: 1,
+ data: dataEntry.data,
+ };
+ this.lineChart.data.datasets.push(dataset);
+ }
+
+ // You add the newly created dataset to the list of `data`
+ // this.lineChart.data.datasets.push(newDataset);
+ this.lineChart.options.scales.x.ticks.callback = (val, index) => {
// // Hide the label of every 2nd dataset
// return xLabels.includes(val.toString()) ? val : null;
// return index % 2 === 0 ? (val) : '';
@@ -327,12 +415,17 @@ export class GeomonTimeseriesChartComponent implements AfterViewInit, DoCheck {
}
}
- chart.options.scales.y.ticks.callback = (value, index, values) => {
+ this.lineChart.options.scales.y.ticks.callback = (value, index, values) => {
return value + '°';
}
-
- chart.update();
- this.width = this.calculateWidth();
+ }
+
+ private redrawCompleteGraph(): void {
+ this.preparedData.forEach((dataEntry: InternalDataEntry, index) => {
+
+ this.processData(dataEntry, index);
+ });
+ this.lineChart.update();
}
private initChart(): void {
@@ -388,6 +481,9 @@ export class GeomonTimeseriesChartComponent implements AfterViewInit, DoCheck {
},
mode: 'xy',
}
+ },
+ legend: {
+ display: false
}
},
scales: {
diff --git a/src/shared/models/chart.ts b/src/shared/models/chart.ts
new file mode 100644
index 0000000..b5aceb3
--- /dev/null
+++ b/src/shared/models/chart.ts
@@ -0,0 +1,40 @@
+import { DatasetOptions } from "./options";
+import { Duration, unitOfTime } from 'moment';
+
+export interface DataEntry {
+ timestamp: number;
+ value: number;
+ xDiagCoord?: number;
+ yDiagCoord?: number;
+}
+
+export interface InternalDataEntry {
+ internalId: string;
+ // hoverId: string;
+ data: number[];
+ selected?: boolean;
+ options: DatasetOptions;
+ bar?: {
+ startOf: unitOfTime.StartOf;
+ period: Duration;
+ };
+ axisOptions: {
+ uom: string;
+ label?: string;
+ zeroBased?: boolean;
+ // yAxisRange?: MinMaxRange;
+ autoRangeSelection?: boolean;
+ separateYAxis?: boolean;
+ parameters?: {
+ feature?: { id: string, label: string };
+ phenomenon?: { id: string, label: string };
+ offering?: { id: string, label: string };
+ };
+ };
+ referenceValueData: {
+ id: string;
+ color: string;
+ data: DataEntry[];
+ }[];
+ visible: boolean;
+}
\ No newline at end of file