- remove d3.js and add chart.js

- add extra chartjs.module
- add extra diagram-view component for binding properties to chartjs chart
This commit is contained in:
Arno Kaimbacher 2021-09-23 15:12:22 +02:00
parent 92d0e94582
commit 5f657dc9e4
18 changed files with 265 additions and 1330 deletions

View file

@ -206,8 +206,19 @@ CREATE src/app/bar/bar.component.css (0 bytes)
UPDATE src/app/app.module.ts (3039 bytes)
npm uninstall d3 @types/d3 --save
========================================== dialog =========================
npm install --save @angular/material @angular/cdk
npx @angular/cli generate service app-router --skip-tests
CREATE src/app/app-router.service.ts (138 bytes)
=============================== chart.js ======================================
npm install --save chart.js

1241
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,6 @@
"@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",
@ -63,8 +62,8 @@
"@ngx-translate/http-loader": "^6.0.0",
"babel-plugin-transform-typescript-metadata": "^0.3.2",
"bulma": "^0.9.3",
"chart.js": "^3.5.1",
"core-js": "^3.16.0",
"d3": "^7.0.1",
"leaflet": "^1.7.1",
"rxjs": "^7.3.0",
"zone.js": "^0.11.4"

View file

@ -1,6 +1,6 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { BarComponent } from './components/bar/bar.component';
import { DiagramViewComponent } from './views/diagram-view/diagram-view.component';
//neu
import { DashboardComponent } from './dashboard/dashboard.component';
@ -11,10 +11,11 @@ import { MapViewComponent } from './views/map-view/map-view.component';
const routes: Routes = [
{ path: '', redirectTo: '/map', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
// { path: 'detail/:id', component: HeroDetailComponent },
{ path: 'map', component: MapViewComponent },
{ path: 'bar', component: BarComponent }
{ path: 'diagram', component: DiagramViewComponent }
];
@NgModule({

View file

@ -27,7 +27,7 @@
<a class="navbar-item" routerLink="/map" routerLinkActive="is-active">
Map
</a>
<a class="navbar-item" routerLink="/bar" routerLinkActive="is-active">
<a class="navbar-item" routerLink="/diagram" routerLinkActive="is-active">
Bar
</a>
</div>

View file

@ -9,6 +9,7 @@ import { DashboardComponent } from './dashboard/dashboard.component';
import { MapViewComponent } from "./views/map-view/map-view.component";
import { ComponentsModule } from '../../src/common/components/components.module';
import { GraphjsModule } from '../../src/common/graphjs/graphjs.module';
import { HttpClientModule, HttpClient } from '@angular/common/http'; //for http requests
import { MarkerService } from './services/marker.service';
@ -20,7 +21,7 @@ import { MessagesComponent } from './messages/messages.component';
import { MessageService } from "./services/message.service";
import { DatasetService } from "./services/dataset.service";
import { MapService } from '../common/components/services/map.service';
import { BarComponent } from './components/bar/bar.component';
import { DiagramViewComponent } from './views/diagram-view/diagram-view.component';
// import { LocateService } from '@helgoland/map';
// import { MapCache } from '@helgoland/map';
@ -29,17 +30,18 @@ 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';
import { MatListModule } from '@angular/material/list';
import {MatBadgeModule} from '@angular/material/badge';
import { InternalIdHandler } from '../common/components/services/internal-id-handler.service';
@NgModule({
// declarations: The components, directives, and pipes that belong to this NgModule.
declarations: [AppComponent, MapComponent, DashboardComponent, MessagesComponent, MapViewComponent, BarComponent, DatasetByStationSelectorComponent],
declarations: [AppComponent, MapComponent, DashboardComponent, MessagesComponent, MapViewComponent, DiagramViewComponent, DatasetByStationSelectorComponent],
// entryComponents: [
// DatasetByStationSelectorComponent
// ],
// imports: Other modules whose exported classes are needed by component templates declared in this NgModule.
imports: [BrowserModule, HttpClientModule, AppRoutingModule, ComponentsModule, BrowserAnimationsModule, MatDialogModule, MatListModule],
imports: [BrowserModule, HttpClientModule, AppRoutingModule, ComponentsModule, GraphjsModule, BrowserAnimationsModule, MatDialogModule, MatListModule, MatBadgeModule],
providers: [
MarkerService, PopupService, HttpService, DatasetApiService, StationService, MessageService, MapService,DatasetService, InternalIdHandler

View file

@ -1,2 +0,0 @@
<h2>Bar Chart</h2>
<figure id="bar"></figure>

View file

@ -1,75 +0,0 @@
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");
}
}

View file

@ -55,8 +55,9 @@
</div>
</div>
</div> -->
<mat-selection-list>
<mat-list-option *ngFor="let timeseries of phenomenonMatchedList" color="primary" [value]="timeseries" [selected]="timeseries.selected">
<mat-selection-list (selectionChange)="adjustSelection($event)">
<mat-list-option *ngFor="let timeseries of phenomenonMatchedList" color="primary" [value]="timeseries"
[selected]="timeseries.selected">
<div mat-line>
{{ timeseries.parameters.phenomenon.label }}
</div>
@ -80,5 +81,7 @@
Close
</button>
<div style="flex: 1"></div>
<button class="mat-raised-button mat-primary">Diagram</button>
<button mat-raised-button mat-dialog-close [matBadge]="datasetService.datasetIds.length" (click)="appRouter.toDiagram()">
Diagram
</button>
</mat-dialog-actions>

View file

@ -6,8 +6,10 @@ import { GeomonTimeseries, GeomonDataset } from './../../../shared/models/datase
import { Station } from './../../../shared/models/station';
import { MatDialogRef } from '@angular/material/dialog';
import { MatSelectionListChange } from '@angular/material/list';
import { DatasetService } from '../../services/dataset.service';
import { AppRouterService } from './../../services/app-router.service';
// https://material.angular.io/components/dialog/overview
// https://blog.angular-university.io/angular-material-dialog/
@ -49,7 +51,8 @@ export class DatasetByStationSelectorComponent implements OnInit {
constructor(
protected datasetApiService: DatasetApiService,
private dialogRef: MatDialogRef<DatasetByStationSelectorComponent>,
public datasetService : DatasetService<GeomonTimeseries>
public datasetService : DatasetService<GeomonTimeseries>,
public appRouter: AppRouterService,
) { }
public ngOnInit() {
@ -101,8 +104,18 @@ export class DatasetByStationSelectorComponent implements OnInit {
this.onSelectionChanged.emit(selection);
}
close() {
public close() {
this.dialogRef.close();
}
public adjustSelection(change: MatSelectionListChange) {
const id = (change.option.value as SelectableDataset).internalId;
if (change.option.selected) {
this.datasetService.addDataset(id, change.option.value as GeomonTimeseries);
} else {
this.datasetService.removeDataset(id);
}
}
}

View file

@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AppRouterService {
private router: Router
constructor(router: Router) {
this.router = router;
}
public toDiagram() {
this.router.navigate(['diagram'])
}
}

View file

@ -0,0 +1,3 @@
<!-- <h2>Bar Chart</h2>
<canvas id="line-chart" width="800" height="450"></canvas> -->
<geomon-timeseries-chart></geomon-timeseries-chart>

View file

@ -0,0 +1,61 @@
import { Component, OnInit } from '@angular/core';
// import * as d3 from 'd3';
import { DatasetService } from '../../services/dataset.service';
import { AppRouterService } from '../../services/app-router.service';
import { GeomonTimeseries, GeomonDataset } from '../../../shared/models/dataset';
@Component({
selector: 'app-bar',
templateUrl: './diagram-view.component.html',
styleUrls: ['./diagram-view.component.css']
})
export class DiagramViewComponent implements OnInit {
public datasetIds: string[] = [];
public selectedIds: string[] = [];
public datasetOptions: Map<string, GeomonTimeseries> = new Map();
public diagramLoading: boolean;
public overviewLoading: boolean;
// public diagramConfig: DiagramConfig = {
// overviewVisible: true,
// yaxisVisible: this.d3diagramOptions.yaxis,
// yaxisModifier: true,
// hoverstyle: this.d3diagramOptions.hoverStyle
// };
constructor(
public datasetService: DatasetService<GeomonTimeseries>,
public appRouter: AppRouterService,) { }
ngOnInit(): void {
// this.createSvg();
// this.drawBars(this.data);
this.setDatasets();
}
private setDatasets() {
this.datasetIds = this.datasetService.datasetIds;
this.datasetOptions = this.datasetService.datasetService;
}
public clearSelection() {
this.selectedIds = [];
}
public removeAllTimeseries() {
this.datasetService.removeAllDatasets();
}
public deleteTimeseries(internalId: string) {
this.datasetService.removeDataset(internalId);
}
}

View file

@ -0,0 +1,3 @@
<div #geomon_timeseries>
<canvas id="line-chart" width="800" height="450"></canvas>
</div>

View file

@ -0,0 +1,83 @@
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
// import * as d3 from 'd3';
import { Chart, registerables } from 'chart.js';
@Component({
selector: 'geomon-timeseries-chart',
templateUrl: './geomon-timeseries-chart.component.html',
styleUrls: ['./geomon-timeseries-chart.component.scss']
})
export class GeomonTimeseriesChartComponent implements OnInit {
@ViewChild('geomon_timeseries', { static: true })
public d3Elem: ElementRef;
constructor() { }
ngOnInit(): void {
// this.createSvg();
// this.drawBars(this.data);
Chart.register(...registerables);
this.drawBars();
}
private drawBars(): void {
let lineChart = document.getElementById("line-chart") as HTMLCanvasElement;
new Chart(lineChart, {
type: 'line',
data: {
labels: [1500, 1600, 1700, 1750, 1800, 1850, 1900, 1950, 1999, 2050],
datasets: [{
data: [86, 114, 106, 106, 107, 111, 133, 221, 783, 2478],
label: "Africa",
borderColor: "#3e95cd",
fill: false
}, {
data: [282, 350, 411, 502, 635, 809, 947, 1402, 3700, 5267],
label: "Asia",
borderColor: "#8e5ea2",
fill: false
}, {
data: [168, 170, 178, 190, 203, 276, 408, 547, 675, 734],
label: "Europe",
borderColor: "#3cba9f",
fill: false
}, {
data: [40, 20, 10, 16, 24, 38, 74, 167, 508, 784],
label: "Latin America",
borderColor: "#e8c3b9",
fill: false
}, {
data: [6, 3, 2, 2, 7, 26, 82, 172, 312, 433],
label: "North America",
borderColor: "#c45850",
fill: false
}
]
},
// options: {
// title: {
// display: true,
// text: 'World population per region (in millions)'
// }
// }
});
}
/**
* Function to generate uuid for a diagram
*/
private uuidv4(): string {
return this.s4() + this.s4() + '-' + this.s4() + '-' + this.s4() + '-' + this.s4() + '-' + this.s4() + this.s4() + this.s4();
}
/**
* Function to generate components of the uuid for a diagram
*/
private s4(): string {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
}

View file

@ -0,0 +1,25 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { GeomonTimeseriesChartComponent } from './geomon-timeseries-chart/geomon-timeseries-chart.component';
// import { ZoomControlComponent } from './zoom-control/zoom.component';
@NgModule({
imports: [
CommonModule
],
declarations: [
GeomonTimeseriesChartComponent,
],
exports: [
GeomonTimeseriesChartComponent
],
providers: [
]
})
export class GraphjsModule { }