- add bar component wit d3.js
- new dataset-by-station-selector.component with angular/material/dialog - zoom.componentn: disable button at lasst zoom level
This commit is contained in:
parent
363cdb0681
commit
427b7b9c91
25 changed files with 1840 additions and 55 deletions
20
notes.txt
20
notes.txt
|
@ -191,3 +191,23 @@ https://www.npmjs.com/package/@fortawesome/angular-fontawesome
|
|||
npm install @fortawesome/fontawesome-svg-core
|
||||
npm install @fortawesome/free-solid-svg-icons
|
||||
npm install @fortawesome/angular-fontawesome@latest
|
||||
|
||||
|
||||
|
||||
=========================================== d3 ============================
|
||||
|
||||
npm install d3 --save
|
||||
npm install @types/d3 --save-dev
|
||||
|
||||
npx @angular/cli generate component bar --skip-tests
|
||||
CREATE src/app/bar/bar.component.html (18 bytes)
|
||||
CREATE src/app/bar/bar.component.ts (263 bytes)
|
||||
CREATE src/app/bar/bar.component.css (0 bytes)
|
||||
UPDATE src/app/app.module.ts (3039 bytes)
|
||||
|
||||
|
||||
|
||||
|
||||
========================================== dialog =========================
|
||||
npm install --save @angular/material @angular/cdk
|
||||
|
||||
|
|
1319
package-lock.json
generated
1319
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -24,6 +24,7 @@
|
|||
"@babel/plugin-proposal-decorators": "^7.14.5",
|
||||
"@babel/preset-env": "^7.14.8",
|
||||
"@babel/preset-typescript": "^7.14.5",
|
||||
"@types/d3": "^7.0.0",
|
||||
"angular2-template-loader": "^0.6.2",
|
||||
"babel-loader": "^8.2.2",
|
||||
"css-loader": "^6.2.0",
|
||||
|
@ -45,8 +46,10 @@
|
|||
"webpack-merge": "^5.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/cdk": "^12.2.5",
|
||||
"@angular/core": "^12.1.4",
|
||||
"@angular/forms": "^12.1.4",
|
||||
"@angular/material": "^12.2.5",
|
||||
"@angular/platform-browser": "^12.1.4",
|
||||
"@angular/platform-browser-dynamic": "^12.1.4",
|
||||
"@angular/router": "^12.2.3",
|
||||
|
@ -61,6 +64,7 @@
|
|||
"babel-plugin-transform-typescript-metadata": "^0.3.2",
|
||||
"bulma": "^0.9.3",
|
||||
"core-js": "^3.16.0",
|
||||
"d3": "^7.0.1",
|
||||
"leaflet": "^1.7.1",
|
||||
"rxjs": "^7.3.0",
|
||||
"zone.js": "^0.11.4"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { BarComponent } from './components/bar/bar.component';
|
||||
|
||||
//neu
|
||||
import { DashboardComponent } from './dashboard/dashboard.component';
|
||||
|
@ -12,7 +13,8 @@ const routes: Routes = [
|
|||
{ path: '', redirectTo: '/map', pathMatch: 'full' },
|
||||
{ path: 'dashboard', component: DashboardComponent },
|
||||
// { path: 'detail/:id', component: HeroDetailComponent },
|
||||
{ path: 'map', component: MapViewComponent }
|
||||
{ path: 'map', component: MapViewComponent },
|
||||
{ path: 'bar', component: BarComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
<a class="navbar-item" routerLink="/map" routerLinkActive="is-active">
|
||||
Map
|
||||
</a>
|
||||
<a class="navbar-item" routerLink="/bar" routerLinkActive="is-active">
|
||||
Bar
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<!-- <div class="navbar-item">
|
||||
|
|
|
@ -19,27 +19,30 @@ import { StationService } from "./services/station.service";
|
|||
import { MessagesComponent } from './messages/messages.component';
|
||||
import { MessageService } from "./services/message.service";
|
||||
import { MapService } from '../common/components/services/map.service';
|
||||
import { BarComponent } from './components/bar/bar.component';
|
||||
// import { LocateService } from '@helgoland/map';
|
||||
// import { MapCache } from '@helgoland/map';
|
||||
|
||||
|
||||
// siehe https://52north.github.io/helgoland-toolbox/additional-documentation/how-tos/integrate-a-map-component.html
|
||||
// https://52north.github.io/helgoland-toolbox/components/LocateControlComponent.html#source
|
||||
|
||||
// import {
|
||||
// DatasetApiInterface, ApiV3InterfaceService, SplittedDataDatasetApiInterface, DatasetApiV3Connector, HelgolandServicesConnector
|
||||
// } from '@helgoland/core';
|
||||
// import { HelgolandCoreModule } from "@helgoland/core";
|
||||
// import { HelgolandMapModule } from '@helgoland/map';
|
||||
|
||||
// import 'core-js';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { DatasetByStationSelectorComponent } from './components/dataset-by-station-selector/dataset-by-station-selector.component';
|
||||
// import { MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material';
|
||||
|
||||
@NgModule({
|
||||
// declarations: The components, directives, and pipes that belong to this NgModule.
|
||||
declarations: [AppComponent, MapComponent, DashboardComponent, MessagesComponent, MapViewComponent],
|
||||
declarations: [AppComponent, MapComponent, DashboardComponent, MessagesComponent, MapViewComponent, BarComponent, DatasetByStationSelectorComponent],
|
||||
entryComponents: [
|
||||
DatasetByStationSelectorComponent
|
||||
],
|
||||
// imports: Other modules whose exported classes are needed by component templates declared in this NgModule.
|
||||
imports: [BrowserModule, HttpClientModule, AppRoutingModule, ComponentsModule],
|
||||
imports: [BrowserModule, HttpClientModule, AppRoutingModule, ComponentsModule, BrowserAnimationsModule, MatDialogModule],
|
||||
providers: [
|
||||
MarkerService, PopupService, HttpService, DatasetApiService, StationService, MessageService, MapService
|
||||
MarkerService, PopupService, HttpService, DatasetApiService, StationService, MessageService, MapService,
|
||||
|
||||
// {
|
||||
// provide: DatasetApiInterface,
|
||||
// useClass: SplittedDataDatasetApiInterface,
|
||||
|
|
0
src/app/components/bar/bar.component.css
Normal file
0
src/app/components/bar/bar.component.css
Normal file
2
src/app/components/bar/bar.component.html
Normal file
2
src/app/components/bar/bar.component.html
Normal file
|
@ -0,0 +1,2 @@
|
|||
<h2>Bar Chart</h2>
|
||||
<figure id="bar"></figure>
|
75
src/app/components/bar/bar.component.ts
Normal file
75
src/app/components/bar/bar.component.ts
Normal file
|
@ -0,0 +1,75 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import * as d3 from 'd3';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bar',
|
||||
templateUrl: './bar.component.html',
|
||||
styleUrls: ['./bar.component.css']
|
||||
})
|
||||
export class BarComponent implements OnInit {
|
||||
|
||||
private data = [
|
||||
{ "Framework": "Vue", "Stars": "166443", "Released": "2014" },
|
||||
{ "Framework": "React", "Stars": "150793", "Released": "2013" },
|
||||
{ "Framework": "Angular", "Stars": "62342", "Released": "2016" },
|
||||
{ "Framework": "Backbone", "Stars": "27647", "Released": "2010" },
|
||||
{ "Framework": "Ember", "Stars": "21471", "Released": "2011" },
|
||||
];
|
||||
private svg: any;
|
||||
private margin = 50;
|
||||
private width = 750 - (this.margin * 2);
|
||||
private height = 400 - (this.margin * 2);
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.createSvg();
|
||||
this.drawBars(this.data);
|
||||
}
|
||||
|
||||
private createSvg(): void {
|
||||
this.svg = d3.select("figure#bar")
|
||||
.append("svg")
|
||||
.attr("width", this.width + (this.margin * 2))
|
||||
.attr("height", this.height + (this.margin * 2))
|
||||
.append("g")
|
||||
.attr("transform", "translate(" + this.margin + "," + this.margin + ")");
|
||||
}
|
||||
|
||||
private drawBars(data: any[]): void {
|
||||
// Create the X-axis band scale
|
||||
const x = d3.scaleBand()
|
||||
.range([0, this.width])
|
||||
.domain(data.map(d => d.Framework))
|
||||
.padding(0.2);
|
||||
|
||||
// Draw the X-axis on the DOM
|
||||
this.svg.append("g")
|
||||
.attr("transform", "translate(0," + this.height + ")")
|
||||
.call(d3.axisBottom(x))
|
||||
.selectAll("text")
|
||||
.attr("transform", "translate(-10,0)rotate(-45)")
|
||||
.style("text-anchor", "end");
|
||||
|
||||
// Create the Y-axis band scale
|
||||
const y = d3.scaleLinear()
|
||||
.domain([0, 200000])
|
||||
.range([this.height, 0]);
|
||||
|
||||
// Draw the Y-axis on the DOM
|
||||
this.svg.append("g")
|
||||
.call(d3.axisLeft(y));
|
||||
|
||||
// Create and fill the bars
|
||||
this.svg.selectAll("bars")
|
||||
.data(data)
|
||||
.enter()
|
||||
.append("rect")
|
||||
.attr("x", (d: any) => x(d.Framework))
|
||||
.attr("y", (d: any) => y(d.Stars))
|
||||
.attr("width", x.bandwidth())
|
||||
.attr("height",(d: any) => this.height - y(d.Stars))
|
||||
.attr("fill", "#d04a35");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<!-- <div class="item" *ngFor="let timeseries of phenomenonMatchedList" (click)="toggle(timeseries)">
|
||||
<div *ngIf="counter">
|
||||
{{counter}} timeseries are loading...
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
*ngIf="timeseries.parameters.category.label && timeseries.parameters.category.label != timeseries.parameters.phenomenon.label">({{timeseries.parameters.category.label}})</span>
|
||||
<div class="additionalInfo" *ngIf="timeseries.lastValue">
|
||||
<span>{{timeseries.lastValue.value}}</span>
|
||||
<span>{{timeseries.uom}}</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- <h1 mat-dialog-title>{{platform?.label}}</h1>
|
||||
<mat-dialog-content>
|
||||
<span>test</span>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions>
|
||||
|
||||
<button mat-raised-button mat-dialog-close>close</button>
|
||||
</mat-dialog-actions> -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h2 mat-dialog-title>{{platform?.label}}</h2>
|
||||
|
||||
<mat-dialog-content >
|
||||
|
||||
|
||||
<input matInput
|
||||
placeholder="Course Description"
|
||||
formControlName="description">
|
||||
|
||||
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions>
|
||||
<button class="mat-raised-button"
|
||||
(click)="close()">
|
||||
Close
|
||||
</button>
|
||||
<button class="mat-raised-button mat-primary">Save</button>
|
||||
</mat-dialog-actions>
|
|
@ -0,0 +1,13 @@
|
|||
:host {
|
||||
.item {
|
||||
&+.item {
|
||||
padding-top: 10px;
|
||||
}
|
||||
&.error {
|
||||
display: none;
|
||||
}
|
||||
label {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { GeomonPlatform } from './../../../shared/models/platform';
|
||||
import { DatasetApiService } from './../../services/dataset-api.service';
|
||||
// https://github.com/52North/helgoland-toolbox/blob/fe6af1b9df0e5d78eeec236e4690aeb7dc92119b/libs/selector/src/lib/dataset-by-station-selector/dataset-by-station-selector.component.ts#L20
|
||||
import { GeomonTimeseries, GeomonDataset } from './../../../shared/models/dataset';
|
||||
import { Station } from './../../../shared/models/station';
|
||||
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
|
||||
// https://material.angular.io/components/dialog/overview
|
||||
// https://blog.angular-university.io/angular-material-dialog/
|
||||
// https://github.com/angular-university/angular-material-course/blob/3-dialog-finished/src/app/course-dialog/course-dialog.component.html
|
||||
|
||||
export class SelectableDataset extends GeomonTimeseries {
|
||||
public selected: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'gba-dataset-by-station-selector',
|
||||
templateUrl: './dataset-by-station-selector.component.html',
|
||||
styleUrls: ['./dataset-by-station-selector.component.scss']
|
||||
})
|
||||
export class DatasetByStationSelectorComponent implements OnInit {
|
||||
|
||||
@Input()
|
||||
public station: Station;//GeomonPlatform;
|
||||
|
||||
public platform: GeomonPlatform;
|
||||
|
||||
@Input()
|
||||
public url: string;
|
||||
|
||||
@Input()
|
||||
public defaultSelected = false;
|
||||
|
||||
@Input()
|
||||
public phenomenonId: string;
|
||||
|
||||
@Output()
|
||||
public onSelectionChanged: EventEmitter<SelectableDataset[]> = new EventEmitter<SelectableDataset[]>();
|
||||
|
||||
public phenomenonMatchedList: SelectableDataset[] = [];
|
||||
public othersList: SelectableDataset[] = [];
|
||||
|
||||
public counter: number;
|
||||
|
||||
constructor(
|
||||
protected datasetApiService: DatasetApiService,
|
||||
private dialogRef: MatDialogRef<DatasetByStationSelectorComponent>,
|
||||
) { }
|
||||
|
||||
public ngOnInit() {
|
||||
this.datasetApiService.getPlatform(this.station.id, 'https://geomon.geologie.ac.at/52n-sos-webapp/api/')
|
||||
.subscribe((platform) => {
|
||||
this.platform = platform;
|
||||
this.counter = 0;
|
||||
|
||||
this.platform.datasetIds.forEach(id => {
|
||||
this.counter++;
|
||||
this.datasetApiService.getDataset( id, this.url, { type: 'timeseries' })
|
||||
.subscribe((result) => {
|
||||
this.prepareResult(result as SelectableDataset, this.defaultSelected);
|
||||
this.counter--;
|
||||
}, (error) => {
|
||||
this.counter--;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public toggle(timeseriesDataset: SelectableDataset) {
|
||||
timeseriesDataset.selected = !timeseriesDataset.selected;
|
||||
this.updateSelection();
|
||||
}
|
||||
|
||||
protected prepareResult(result: SelectableDataset, selection: boolean) {
|
||||
result.selected = selection;
|
||||
if (this.phenomenonId) {
|
||||
if (result.parameters.phenomenon.id === this.phenomenonId) {
|
||||
this.phenomenonMatchedList.push(result);
|
||||
} else {
|
||||
this.othersList.push(result);
|
||||
}
|
||||
} else {
|
||||
this.phenomenonMatchedList.push(result);
|
||||
}
|
||||
this.updateSelection();
|
||||
}
|
||||
|
||||
private updateSelection() {
|
||||
const selection = this.phenomenonMatchedList.filter((entry) => entry.selected);
|
||||
this.onSelectionChanged.emit(selection);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
<div class="stations-menu">
|
||||
<h2>Stations</h2>
|
||||
<a class="station" *ngFor="let station of stations" routerLink="/detail/{{station.id}}">
|
||||
{{ station.properties.label }}
|
||||
{{ station.label }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
|
@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
|
|||
// import { StationService } from '../services/station.service';
|
||||
import { DatasetApiService } from '../services/dataset-api.service';
|
||||
import { Station } from '../../shared/models/station';
|
||||
import { GeomonPlatform } from '../../shared/models/platform';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
|
@ -10,7 +11,7 @@ import { Station } from '../../shared/models/station';
|
|||
})
|
||||
export class DashboardComponent implements OnInit {
|
||||
|
||||
public stations: Station[] = [];
|
||||
public stations: GeomonPlatform[] = [];
|
||||
|
||||
constructor(private datasetApiService: DatasetApiService) { }
|
||||
|
||||
|
@ -21,9 +22,9 @@ export class DashboardComponent implements OnInit {
|
|||
getStations(): void {
|
||||
// this.stationService.getStations()
|
||||
// .subscribe(stations => this.stations = stations);
|
||||
this.datasetApiService.getStations('https://geomon.geologie.ac.at/52n-sos-webapp/api/')
|
||||
this.datasetApiService.getPlatforms('https://geomon.geologie.ac.at/52n-sos-webapp/api/')
|
||||
.subscribe((stations) => {
|
||||
this.stations = stations
|
||||
this.stations = stations;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6,5 +6,4 @@
|
|||
<div [attr.id]="mapId" class="map-container mapDesktop">
|
||||
<gba-locate-button [mapId]="mapId"></gba-locate-button>
|
||||
<gba-zoom-control [mapId]="mapId"></gba-zoom-control>
|
||||
|
||||
</div>
|
|
@ -1,11 +1,12 @@
|
|||
// https://github.com/52North/helgoland-toolbox/blob/c2c2eda20353c469a7aa4a6a118a810723af6622/libs/map/src/lib/selector/station-map-selector/station-map-selector.component.ts
|
||||
import { Component, AfterViewInit, OnChanges, SimpleChanges, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { Component, AfterViewInit, OnChanges, SimpleChanges, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { Control, FeatureGroup, geoJSON, circleMarker, FitBoundsOptions, LatLngBoundsExpression } from 'leaflet';
|
||||
import { MarkerService } from '../services/marker.service';
|
||||
import { DatasetApiService } from '../services/dataset-api.service';
|
||||
import { BaseMapComponent } from './base-map.component';
|
||||
import { PopupService } from '../services/popup.service';
|
||||
import { MapService } from '../../common/components/services/map.service';
|
||||
import { ZoomControlComponent } from '../../common/components/zoom-control/zoom.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-map',
|
||||
|
@ -17,6 +18,8 @@ export class MapComponent
|
|||
extends BaseMapComponent
|
||||
implements OnChanges, AfterViewInit {
|
||||
|
||||
@ViewChild(ZoomControlComponent) zoom:ZoomControlComponent;
|
||||
|
||||
|
||||
/**
|
||||
* @input The serviceUrl, where the selection should be loaded.
|
||||
|
@ -54,6 +57,7 @@ export class MapComponent
|
|||
|
||||
ngAfterViewInit(): void {
|
||||
this.initMap();
|
||||
this.map.on("zoomend zoomlevelschange", this.zoom._updateDisabled, this.zoom);
|
||||
// this.markerService.makeCapitalMarkers(this.map);
|
||||
// this.markerService.makeCapitalCircleMarkers(this.map);
|
||||
this.datasetApiService.getStations('https://geomon.geologie.ac.at/52n-sos-webapp/api/')
|
||||
|
@ -74,7 +78,7 @@ export class MapComponent
|
|||
marker.on('click', () => {
|
||||
this.onSelected.emit(station);
|
||||
});
|
||||
marker.bindPopup(this.popupService.makeCapitalPopup(station.properties));
|
||||
// marker.bindPopup(this.popupService.makeCapitalPopup(station.properties));
|
||||
}
|
||||
});
|
||||
this.markerFeatureGroup.addTo(this.map);
|
||||
|
|
|
@ -11,7 +11,10 @@ import { HttpService } from './http.service';
|
|||
import { HttpRequestOptions } from '../../shared/models/http-requests';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { MessageService } from './message.service';
|
||||
import { GeomonPlatform } from '../../shared/models/platform';
|
||||
import { Dataset, GeomonTimeseries } from '../../shared/models/dataset';
|
||||
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
// @Injectable({
|
||||
// providedIn: 'root'
|
||||
|
@ -33,12 +36,60 @@ export class DatasetApiService {
|
|||
}
|
||||
|
||||
public getStations(apiUrl: string, params?: any, options?: HttpRequestOptions): Observable<Station[]> {
|
||||
const url = this.createRequestUrl(apiUrl, 'features');
|
||||
const url = this.createRequestUrl(apiUrl, 'features'); //https://geomon.geologie.ac.at/52n-sos-webapp/api/features
|
||||
let stations = this.requestApi<Station[]>(url, params, options);
|
||||
this.messageService.add('StationService: fetched stations');
|
||||
return stations;
|
||||
}
|
||||
|
||||
public getFeature(
|
||||
id: string,
|
||||
apiUrl: string,
|
||||
params?: any,
|
||||
options?: HttpRequestOptions
|
||||
): Observable<Station> {
|
||||
const url = this.createRequestUrl(apiUrl, 'features', id);
|
||||
return this.requestApi<Station>(url, params, options);
|
||||
}
|
||||
|
||||
public getPlatforms(apiUrl: string, params?: any, options?: HttpRequestOptions): Observable<GeomonPlatform[]> {
|
||||
// const url = this.createRequestUrl(apiUrl, 'platforms');
|
||||
// return this.requestApi<GeomonPlatform[]>(url, params, options);
|
||||
return this.getStations(apiUrl, params, options).pipe(map(res => res.map(f => this.createGeomonPlatform(f))));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public getPlatform(
|
||||
id: string,
|
||||
apiUrl: string,
|
||||
params?: any,
|
||||
options?: HttpRequestOptions
|
||||
): Observable<GeomonPlatform> {
|
||||
// const url = this.createRequestUrl(apiUrl, 'platforms', id);
|
||||
// return this.requestApi<GeomonPlatform>(url, params, options);
|
||||
return this.getFeature(id, apiUrl,params, options).pipe(map(res => this.createGeomonPlatform(res)));
|
||||
}
|
||||
|
||||
public getDataset(id: string, apiUrl: string, params?: any, options?: HttpRequestOptions): Observable<GeomonTimeseries> {
|
||||
const url = this.createRequestUrl(apiUrl, 'datasets', id);
|
||||
return this.requestApi<GeomonTimeseries>(url, params, options);
|
||||
//.pipe(
|
||||
// map((res) => this.prepareDataset(res, apiUrl))
|
||||
// );
|
||||
}
|
||||
|
||||
//#region Helper method
|
||||
|
||||
protected createGeomonPlatform(feature: Station): GeomonPlatform {
|
||||
const datasetIds = [];
|
||||
for (const key in feature.properties.datasets) {
|
||||
if (feature.properties.datasets.hasOwnProperty(key)) {
|
||||
datasetIds.push(key);
|
||||
}
|
||||
}
|
||||
return new GeomonPlatform(feature.id, feature.properties.label, datasetIds, feature.geometry);
|
||||
}
|
||||
|
||||
protected createRequestUrl(apiUrl: string, endpoint: string, id?: string) {
|
||||
// TODO Check whether apiUrl ends with slash
|
||||
|
@ -63,4 +114,5 @@ export class DatasetApiService {
|
|||
return headers;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { ParameterFilter, Station } from '@helgoland/core';
|
||||
import { ParameterFilter } from '@helgoland/core';
|
||||
import { GeomonPlatform } from './../../../shared/models/platform';
|
||||
import { LayerOptions } from '@helgoland/map';
|
||||
import { Marker, MapOptions, Control, icon, LatLngBoundsExpression } from 'leaflet';
|
||||
// optional, to adapt leaflet markers
|
||||
|
||||
import { Station } from '../../../shared/models/station';
|
||||
import { DatasetByStationSelectorComponent } from './../../components/dataset-by-station-selector/dataset-by-station-selector.component';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
|
||||
// optional, to adapt leaflet markers
|
||||
Marker.prototype.options.icon = icon({
|
||||
iconRetinaUrl: 'assets/img/marker-icon-2x.png',
|
||||
iconUrl: 'assets/img/marker-icon.png',
|
||||
|
@ -16,6 +21,8 @@ Marker.prototype.options.icon = icon({
|
|||
shadowSize: [41, 41]
|
||||
});
|
||||
|
||||
const DIALOG_MAX_WIDTH = '95%';
|
||||
|
||||
@Component({
|
||||
selector: 'gba-map-view',
|
||||
templateUrl: './map-view.component.html',
|
||||
|
@ -23,7 +30,9 @@ Marker.prototype.options.icon = icon({
|
|||
})
|
||||
export class MapViewComponent implements OnInit {
|
||||
|
||||
constructor() {
|
||||
constructor(
|
||||
private dialog: MatDialog,
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
|
@ -56,7 +65,16 @@ export class MapViewComponent implements OnInit {
|
|||
};
|
||||
|
||||
public onStationSelected(station: Station) {
|
||||
console.log('Clicked station: ' + station.properties.label);
|
||||
// console.log('Clicked station: ' + station.properties.label);
|
||||
const dialogRef = this.dialog.open(DatasetByStationSelectorComponent, {
|
||||
height: '400px',
|
||||
width: '600px',
|
||||
maxWidth: DIALOG_MAX_WIDTH ,
|
||||
hasBackdrop: true, //Here line to add
|
||||
// panelClass: 'custom-dialog-container'
|
||||
});
|
||||
dialogRef.componentInstance.station = station;
|
||||
dialogRef.componentInstance.url = this.providerUrl;
|
||||
}
|
||||
|
||||
public onMapInitialized(newItem: string) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<div class="gba-control-zoom btn-group-vertical map-control">
|
||||
<button type="button" class="button is-light is-small" (click)="zoomIn()">
|
||||
<button #inputPlus type="button" class="button is-light is-small" (click)="zoomIn()">
|
||||
<fa-icon [icon]="faPlus"></fa-icon>
|
||||
</button>
|
||||
<button type="button" class="button is-light is-small" (click)="zoomOut()">
|
||||
<button #inputMinus type="button" class="button is-light is-small" (click)="zoomOut()">
|
||||
<fa-icon [icon]="faMinus"></fa-icon>
|
||||
</button>
|
||||
</div>
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
import { Component, Input, ElementRef, ViewChild } from '@angular/core';
|
||||
import { MapService } from '../services/map.service';
|
||||
import { faPlus, faMinus } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
|
@ -17,6 +17,9 @@ export class ZoomControlComponent {
|
|||
*/
|
||||
@Input() public mapId: string;
|
||||
|
||||
@ViewChild('inputPlus') private _inputPlus:ElementRef;
|
||||
@ViewChild('inputMinus') private _inpuMinus:ElementRef;
|
||||
|
||||
constructor(
|
||||
protected mapService: MapService
|
||||
) {
|
||||
|
@ -31,4 +34,28 @@ export class ZoomControlComponent {
|
|||
let map = this.mapService.getMap(this.mapId);
|
||||
map.zoomOut();
|
||||
}
|
||||
|
||||
_updateDisabled() {
|
||||
let map = this.mapService.getMap(this.mapId);
|
||||
// let className = 'leaflet-disabled';
|
||||
|
||||
// this._inputPlus.nativeElement.classList.remove(className);
|
||||
this._inputPlus.nativeElement.disabled = false;
|
||||
this._inputPlus.nativeElement.setAttribute('aria-disabled', 'false');
|
||||
|
||||
// this._inpuMinus.nativeElement.classList.remove(className);
|
||||
this._inpuMinus.nativeElement.disabled = false;
|
||||
this._inpuMinus.nativeElement.setAttribute('aria-disabled', 'false');
|
||||
|
||||
if (map.getZoom() === map.getMinZoom()) {
|
||||
// this._inpuMinus.nativeElement.classList.add(className);
|
||||
this._inpuMinus.nativeElement.disabled = true;
|
||||
this._inpuMinus.nativeElement.setAttribute('aria-disabled', 'true');
|
||||
}
|
||||
if (map.getZoom() === map.getMaxZoom()) {
|
||||
// this._inputPlus.nativeElement.classList.add(className);
|
||||
this._inputPlus.nativeElement.disabled = true;
|
||||
this._inputPlus.nativeElement.setAttribute('aria-disabled', 'true');
|
||||
}
|
||||
}
|
||||
}
|
80
src/shared/models/dataset.ts
Normal file
80
src/shared/models/dataset.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
import { GeomonPlatform } from "./platform";
|
||||
|
||||
export class Dataset {
|
||||
public id: string;
|
||||
public label: string;
|
||||
public url: string;
|
||||
public uom: string;
|
||||
public internalId: string;
|
||||
public firstValue: FirstLastValue;
|
||||
public lastValue: FirstLastValue;
|
||||
public referenceValues: ReferenceValue[];
|
||||
public datasetType: any;
|
||||
public platformType: any;
|
||||
public seriesParameters?: any;
|
||||
public renderingHints: RenderingHints;
|
||||
public parameters: any;
|
||||
}
|
||||
|
||||
export class GeomonDataset {
|
||||
public internalId: string;
|
||||
|
||||
constructor(
|
||||
public id: string,
|
||||
public url: string,
|
||||
public label: string
|
||||
) {
|
||||
// this.internalId = new InternalIdHandler().createInternalId(url, id);
|
||||
}
|
||||
}
|
||||
|
||||
export class GeomonTimeseries extends GeomonDataset {
|
||||
|
||||
constructor(
|
||||
public id: string,
|
||||
public url: string,
|
||||
public label: string,
|
||||
public uom: string,
|
||||
public platform: GeomonPlatform,
|
||||
public firstValue: FirstLastValue,
|
||||
public lastValue: FirstLastValue,
|
||||
public referenceValues: ReferenceValue[],
|
||||
public renderingHints: RenderingHints,
|
||||
public parameters: ParameterConstellation,
|
||||
) {
|
||||
super(id, url, label);
|
||||
}
|
||||
}
|
||||
|
||||
export class ParameterConstellation {
|
||||
public service: Parameter;
|
||||
public offering: Parameter;
|
||||
public feature: Parameter; //Feature;
|
||||
public procedure: Parameter;
|
||||
public phenomenon: Parameter;
|
||||
public category: Parameter;
|
||||
}
|
||||
interface Parameter {
|
||||
id: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export class FirstLastValue {
|
||||
public timestamp: number;
|
||||
public value: number;
|
||||
}
|
||||
|
||||
export class ReferenceValue {
|
||||
public referenceValueId: string;
|
||||
public label: string;
|
||||
public lastValue: FirstLastValue;
|
||||
public color?: string;
|
||||
public visible?: boolean;
|
||||
}
|
||||
|
||||
export interface RenderingHints {
|
||||
chartType: string;
|
||||
properties: {
|
||||
color: string;
|
||||
};
|
||||
}
|
10
src/shared/models/platform.ts
Normal file
10
src/shared/models/platform.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
export class GeomonPlatform {
|
||||
|
||||
constructor(
|
||||
public id: string,
|
||||
public label: string,
|
||||
public datasetIds: string[],
|
||||
public geometry?: GeoJSON.GeometryObject
|
||||
) { }
|
||||
|
||||
}
|
|
@ -10,25 +10,32 @@ export interface Station {
|
|||
export interface StationProperties {
|
||||
id: string;
|
||||
label: string;
|
||||
// timeseries: TimeseriesCollection | Timeseries;
|
||||
datasets: Dataset;
|
||||
}
|
||||
|
||||
export interface Dataset
|
||||
{
|
||||
id: string;
|
||||
label: string;
|
||||
href: string,
|
||||
domainId: string;
|
||||
}
|
||||
// export class TimeseriesCollection {
|
||||
// [key: string]: ParameterConstellation;
|
||||
// }
|
||||
|
||||
interface Timeseries {
|
||||
id: string;
|
||||
label: string;
|
||||
url: string;
|
||||
uom: string;
|
||||
internalId: string;
|
||||
// firstValue;
|
||||
// lastValue;
|
||||
// referenceValues;
|
||||
station: Station;
|
||||
// parameters;
|
||||
// statusIntervals?;
|
||||
// hasData = false;
|
||||
// public renderingHints;
|
||||
}
|
||||
// interface Timeseries {
|
||||
// id: string;
|
||||
// label: string;
|
||||
// url: string;
|
||||
// uom: string;
|
||||
// internalId: string;
|
||||
// // firstValue;
|
||||
// // lastValue;
|
||||
// // referenceValues;
|
||||
// station: Station;
|
||||
// // parameters;
|
||||
// // statusIntervals?;
|
||||
// // hasData = false;
|
||||
// // public renderingHints;
|
||||
// }
|
|
@ -1,3 +1,8 @@
|
|||
// @import '~@angular/material';
|
||||
// @import '~@angular/cdk/overlay-prebuilt.css';
|
||||
|
||||
@import '~@angular/material/prebuilt-themes/purple-green.css';
|
||||
|
||||
.leaflet-pane {
|
||||
z-index: 28;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue