Mise à jours du dashboard
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
"src/manifest.webmanifest"
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/chartist/dist/index.scss",
|
||||
"src/styles/styles.scss"
|
||||
],
|
||||
"scripts": [],
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||
<huapp-full-layout></huapp-full-layout>
|
||||
<!--
|
||||
<div class="p-5">
|
||||
<router-outlet><huapp-spinner></huapp-spinner></router-outlet>
|
||||
</div>
|
||||
<huapp-layout-header></huapp-layout-header>
|
||||
<router-outlet><huapp-spinner></huapp-spinner></router-outlet>
|
||||
<huapp-layout-footer></huapp-layout-footer>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="container page auth-page">
|
||||
<div class="container content auth-page">
|
||||
<div class="row">
|
||||
<div class="col-md-6 offset-md-3 col-xs-12">
|
||||
<h1 class="text-xs-center">{{ title }}</h1>
|
||||
|
||||
@@ -50,6 +50,7 @@ export class AuthComponent implements OnInit, OnDestroy {
|
||||
firstname: '',
|
||||
lastname: '',
|
||||
phone: '',
|
||||
licence: '',
|
||||
password: ['', Validators.required],
|
||||
confirmPassword: ''
|
||||
}, { validators: this.checkPasswords });
|
||||
@@ -98,6 +99,7 @@ export class AuthComponent implements OnInit, OnDestroy {
|
||||
this._user = user$.subscribe({
|
||||
next: () => this.router.navigateByUrl('/'),
|
||||
error: (err) => {
|
||||
console.log(err);
|
||||
this.errors = err;
|
||||
this.isSubmitting = false;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<!-- Numero Column -->
|
||||
<ng-container matColumnDef="weight">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header class="{{tableHeader[0].active}}"> {{tableHeader[0].name}} </th>
|
||||
<th mat-cell *matCellDef="let element;" class="text-right pl-3 pr-3">{{element.weight}}</th>
|
||||
<th mat-cell *matCellDef="let element;" class="text-end pl-3 pr-3">{{element.weight}}</th>
|
||||
</ng-container>
|
||||
<!-- range_ Column -->
|
||||
<ng-container matColumnDef="range_1">
|
||||
|
||||
+7
-8
@@ -3,8 +3,7 @@
|
||||
<mat-card-title>Aéronefs</mat-card-title>
|
||||
<mat-card-subtitle>Nombre total de sauts par avions</mat-card-subtitle>
|
||||
<div class="barchrt">
|
||||
<x-chartist class="" [data]="barChartAeronef.data" [type]="barChartAeronef.type" [options]="barChartAeronef.options" [responsiveOptions]="barChartAeronef.responsiveOptions"
|
||||
[events]="barChartAeronef.events"> </x-chartist>
|
||||
<x-chartist [configuration]="barChartAeronef"></x-chartist>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr>
|
||||
@@ -13,18 +12,18 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th>
|
||||
<th class="text-right">Total</th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-mono">
|
||||
<tbody class="font-monospace">
|
||||
<tr *ngFor='let values of seriesRow; let i=index'>
|
||||
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="text-right">
|
||||
<th class="{{seriesColor[i]}} text-end"> ● {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
|
||||
</td>
|
||||
<th class="{{seriesColor[i]}} text-right">
|
||||
<th class="{{seriesColor[i]}} text-end">
|
||||
<span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template>
|
||||
</th>
|
||||
|
||||
+116
-100
@@ -1,10 +1,11 @@
|
||||
import { Component, OnInit} from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { ChartistModule, Configuration } from 'ng-chartist';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { BackendService } from 'src/app/core/services';
|
||||
import { ReduceRow } from 'src/app/core/models';
|
||||
import { BackendService, AeronefsService } from 'src/app/core/services';
|
||||
import { chartBar, AeronefByImat, AeronefByYear } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -12,117 +13,132 @@ import { ReduceRow } from 'src/app/core/models';
|
||||
selector: 'huapp-aeronefs-bar',
|
||||
templateUrl: './aeronefs-bar.component.html'
|
||||
})
|
||||
export class AeronefsBarComponent implements OnInit {
|
||||
rows: Object[] = [] as Array<Object>;
|
||||
export class AeronefsBarComponent implements OnInit, OnDestroy {
|
||||
private _aeronefByImat: Subscription = new Subscription();
|
||||
private _aeronefByYear: Subscription = new Subscription();
|
||||
aeronefByImat!: Array<AeronefByImat>;
|
||||
aeronefByYear!: Array<AeronefByYear>;
|
||||
aeronefByImatCount = 0;
|
||||
aeronefByYearCount = 0;
|
||||
seriesName: string[] = [];
|
||||
seriesValue: any[] = [];
|
||||
seriesColor: string[] = this._dataService.getChartColors();
|
||||
seriesHeader: string[] = [];
|
||||
seriesRow: any[] = [];
|
||||
barChartAeronef: Configuration = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {},
|
||||
responsiveOptions: []
|
||||
};
|
||||
barChartAeronef: Configuration = chartBar;
|
||||
|
||||
constructor(private _dataService: BackendService) { }
|
||||
|
||||
loadDataByDate() {
|
||||
return this._dataService
|
||||
.getAeronefsByDate(2)
|
||||
.subscribe((res) => {
|
||||
this.seriesName.forEach((name: string) => {
|
||||
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
|
||||
});
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
res["rows"].forEach((row: ReduceRow) => {
|
||||
let year = row.key[1].toString();
|
||||
let avion = row.key[0];
|
||||
this.seriesRow[this.seriesName.indexOf(avion)][this.seriesHeader.indexOf(year)] = row.value;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
constructor(
|
||||
private aeronefsService: AeronefsService,
|
||||
private _dataService: BackendService
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
return this._dataService
|
||||
.getAeronefs()
|
||||
.subscribe((res) => {
|
||||
this.rows = res["rows"]
|
||||
this.rows.forEach((row: ReduceRow) => {
|
||||
this.seriesName.push(row.key[0] + ' ' + row.key[1]);
|
||||
this.seriesValue.push([row.value]);
|
||||
});
|
||||
this.barChartAeronef = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": this.seriesName,
|
||||
"series": this.seriesValue
|
||||
this._loadAeronefByImat();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._aeronefByImat.unsubscribe();
|
||||
this._aeronefByYear.unsubscribe();
|
||||
}
|
||||
|
||||
private _loadAeronefByImat(): void {
|
||||
const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat();
|
||||
this._aeronefByImat = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
|
||||
this.aeronefByImat = aggregate;
|
||||
this.aeronefByImatCount = aggregate.length;
|
||||
this.aeronefByImat.forEach((row) => {
|
||||
this.seriesName.push(`${row._id.aeronef} ${row._id.imat}`);
|
||||
this.seriesValue.push(row.count);
|
||||
});
|
||||
this.barChartAeronef = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": this.seriesName,
|
||||
"series": this.seriesValue
|
||||
},
|
||||
options: {
|
||||
chartPadding: {
|
||||
top: 15,
|
||||
right: 20,
|
||||
bottom: 0,
|
||||
left: 20
|
||||
},
|
||||
options: {
|
||||
chartPadding: {
|
||||
top: 15,
|
||||
right: 20,
|
||||
bottom: 0,
|
||||
left: 20
|
||||
seriesBarDistance: 15,
|
||||
horizontalBars: true,
|
||||
axisX: {
|
||||
onlyInteger: true,
|
||||
position: 'end',
|
||||
labelOffset: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
seriesBarDistance: 15,
|
||||
horizontalBars: true,
|
||||
showGrid: true,
|
||||
offset: 20
|
||||
},
|
||||
axisY: {
|
||||
showGrid: false,
|
||||
offset: 0,
|
||||
labelInterpolationFnc: function(): string {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
height: (this.seriesName.length*20)
|
||||
},
|
||||
responsiveOptions: [
|
||||
['screen and (min-width: 1024px)', {
|
||||
axisX: {
|
||||
position: 'end',
|
||||
labelOffset: {
|
||||
x: -5,
|
||||
y: 0
|
||||
},
|
||||
showGrid: true,
|
||||
labelInterpolationFnc: function(value: number, index: number): string {
|
||||
return index % 1 === 0 ? `${value}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (min-width: 641px) and (max-width: 1024px)', {
|
||||
seriesBarDistance: 10,
|
||||
axisY: {
|
||||
offset: 30
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (max-width: 640px)', {
|
||||
seriesBarDistance: 5,
|
||||
axisY: {
|
||||
offset: 20
|
||||
},
|
||||
axisY: {
|
||||
showGrid: false,
|
||||
offset: 0,
|
||||
labelInterpolationFnc: function(): string {
|
||||
return '';
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
|
||||
}
|
||||
},
|
||||
height: (this.seriesName.length*20)
|
||||
},
|
||||
responsiveOptions: [
|
||||
['screen and (min-width: 1024px)', {
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: number, index: number): string {
|
||||
return index % 1 === 0 ? `${value}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (min-width: 641px) and (max-width: 1024px)', {
|
||||
seriesBarDistance: 10,
|
||||
axisY: {
|
||||
offset: 30
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (max-width: 640px)', {
|
||||
seriesBarDistance: 5,
|
||||
axisY: {
|
||||
offset: 20
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
};
|
||||
return this.loadDataByDate();
|
||||
}
|
||||
}]
|
||||
]
|
||||
};
|
||||
this._loadAeronefByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadAeronefByYear(): void {
|
||||
let values: Array<number> = [];
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
this.seriesHeader.forEach(() => {
|
||||
values.push(0);
|
||||
});
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<AeronefByYear>> = this.aeronefsService.getAllByDate();
|
||||
this._aeronefByYear = dropzones$.subscribe((aggregate: Array<AeronefByYear>) => {
|
||||
this.aeronefByYear = aggregate;
|
||||
this.aeronefByYearCount = aggregate.length;
|
||||
this.aeronefByYear.forEach((row: AeronefByYear) => {
|
||||
let aeronef: string = row._id.aeronef;
|
||||
let imat: string = row._id.imat;
|
||||
let year: string = row._id.year.toString();
|
||||
this.seriesRow[this.seriesName.indexOf(`${aeronef} ${imat}`)][this.seriesHeader.indexOf(year)] = row.count;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<mat-card-title>Aéronefs</mat-card-title>
|
||||
<mat-card-subtitle>Nombre total de sauts par avions</mat-card-subtitle>
|
||||
<div class="piechart">
|
||||
<x-chartist [configuration]="donuteChartModel"> </x-chartist>
|
||||
<x-chartist [configuration]="donuteAeronefs"></x-chartist>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr>
|
||||
@@ -12,18 +12,18 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th>
|
||||
<th class="text-right">Total</th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor='let values of seriesRow; let i=index'>
|
||||
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="text-mono text-right">
|
||||
<th class="{{seriesColor[i]}} text-end"> ● {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="font-monospace text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
|
||||
</td>
|
||||
<th class="{{seriesColor[i]}} text-right">
|
||||
<th class="{{seriesColor[i]}} text-end">
|
||||
<span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template>
|
||||
</th>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Component, OnInit} from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { ChartistModule, Configuration } from 'ng-chartist';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { BackendService, AeronefsService, UserService } from 'src/app/core/services';
|
||||
import { Aeronef, AeronefByImat } from 'src/app/core/models';
|
||||
import { Aeronef, AeronefByImat, AeronefByYear, chartPieDonute } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -13,110 +13,49 @@ import { Aeronef, AeronefByImat } from 'src/app/core/models';
|
||||
selector: 'huapp-aeronefs',
|
||||
templateUrl: './aeronefs.component.html'
|
||||
})
|
||||
export class AeronefsComponent implements OnInit {
|
||||
private _aeronefs: Subscription = new Subscription();
|
||||
aggregate!: Array<AeronefByImat>
|
||||
aeronefs!: Array<Aeronef>;
|
||||
aeronefsCount = 0;
|
||||
export class AeronefsComponent implements OnInit, OnDestroy {
|
||||
private _aeronefByImat: Subscription = new Subscription();
|
||||
private _aeronefByYear: Subscription = new Subscription();
|
||||
aeronefByImat!: Array<AeronefByImat>;
|
||||
aeronefByYear!: Array<AeronefByYear>;
|
||||
aeronefByImatCount = 0;
|
||||
aeronefByYearCount = 0;
|
||||
rows: Object[] = [] as Array<Object>;
|
||||
seriesName: string[] = [];//= ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"];
|
||||
seriesValue: number[] = [];
|
||||
seriesColor: string[] = this._dataService.getChartColors(); //["blue", "red", "turquoise", "orange", "cyan", "purple-dark", "megna", "raspberry"];
|
||||
seriesHeader: string[] = [];
|
||||
seriesRow: any[] = [];
|
||||
donuteChartModel: Configuration = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
startAngle: 270,
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
donuteAeronefs: Configuration = chartPieDonute;
|
||||
|
||||
constructor(
|
||||
private aeronefsService: AeronefsService,
|
||||
private _dataService: BackendService
|
||||
) { }
|
||||
|
||||
/*loadDataByDate() {
|
||||
return this._dataService
|
||||
.getAeronefsByDate(2)
|
||||
.subscribe((res) => {
|
||||
this.seriesName.forEach((name: string) => {
|
||||
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
|
||||
});
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
res["rows"].forEach((row: ReduceRow) => {
|
||||
let year = row.key[1].toString();
|
||||
let avion = row.key[0];
|
||||
this.seriesRow[this.seriesName.indexOf(avion)][this.seriesHeader.indexOf(year)] = row.value;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}*/
|
||||
|
||||
ngOnInit() {
|
||||
this.loadAeronefs();
|
||||
return this._dataService
|
||||
.getAeronefs()
|
||||
.subscribe((res) => {
|
||||
console.log(res);
|
||||
/* this.rows = res["rows"]
|
||||
var labels: string[] = [];
|
||||
var series: number[] = [];
|
||||
this.rows.forEach((row: ReduceRow) => {
|
||||
this.seriesName.push(row.key[0] + ' ' + row.key[1]);
|
||||
this.seriesValue.push(row.value);
|
||||
//console.log(row.key, row.value);
|
||||
labels.push(row.value.toString());
|
||||
series.push(row.value);
|
||||
});
|
||||
this.donuteChartModel = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": labels,
|
||||
"series": series
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
startAngle: 270,
|
||||
showLabel: true
|
||||
}
|
||||
//,
|
||||
// events: <ChartEvent>{
|
||||
// draw: (data) => {
|
||||
// //this.donuteChartModel.data = data;
|
||||
// console.log(data);
|
||||
// }
|
||||
// }
|
||||
};
|
||||
return this.loadDataByDate(); */
|
||||
});
|
||||
this._loadAeronefByImat();
|
||||
}
|
||||
|
||||
loadAeronefs() {
|
||||
ngOnDestroy() {
|
||||
this._aeronefByImat.unsubscribe();
|
||||
this._aeronefByYear.unsubscribe();
|
||||
}
|
||||
|
||||
private _loadAeronefByImat(): void {
|
||||
const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat();
|
||||
this._aeronefs = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
|
||||
this.aggregate = aggregate;
|
||||
this.aeronefsCount = aggregate.length;
|
||||
this._aeronefByImat = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
|
||||
this.aeronefByImat = aggregate;
|
||||
this.aeronefByImatCount = aggregate.length;
|
||||
var labels: string[] = [];
|
||||
var series: number[] = [];
|
||||
this.aggregate.forEach((row) => {
|
||||
this.seriesName.push(row._id.aeronef + ' ' + row._id.imat);
|
||||
this.aeronefByImat.forEach((row) => {
|
||||
this.seriesName.push(`${row._id.aeronef} ${row._id.imat}`);
|
||||
this.seriesValue.push(row.count);
|
||||
labels.push(row.count.toString());
|
||||
//labels.push(row._id.aeronef + ' ' + row._id.imat);
|
||||
series.push(row.count);
|
||||
});
|
||||
this.donuteChartModel = {
|
||||
this.donuteAeronefs = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": labels,
|
||||
@@ -130,6 +69,29 @@ export class AeronefsComponent implements OnInit {
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
this._loadAeronefByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadAeronefByYear(): void {
|
||||
let values: Array<number> = [];
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
this.seriesHeader.forEach(() => {
|
||||
values.push(0);
|
||||
});
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<AeronefByYear>> = this.aeronefsService.getAllByDate();
|
||||
this._aeronefByYear = dropzones$.subscribe((aggregate: Array<AeronefByYear>) => {
|
||||
this.aeronefByYear = aggregate;
|
||||
this.aeronefByYearCount = aggregate.length;
|
||||
this.aeronefByYear.forEach((row: AeronefByYear) => {
|
||||
let aeronef: string = row._id.aeronef;
|
||||
let imat: string = row._id.imat;
|
||||
let year: string = row._id.year.toString();
|
||||
this.seriesRow[this.seriesName.indexOf(`${aeronef} ${imat}`)][this.seriesHeader.indexOf(year)] = row.count;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -3,7 +3,7 @@
|
||||
<mat-card-title>Modèles de voile</mat-card-title>
|
||||
<mat-card-subtitle>Nombre total de sauts par modèle</mat-card-subtitle>
|
||||
<div class="piechart">
|
||||
<x-chartist [configuration]="donuteCanopyModel"> </x-chartist>
|
||||
<x-chartist [configuration]="donuteCanopies"></x-chartist>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr>
|
||||
@@ -12,18 +12,18 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th>
|
||||
<th class="text-right">Total</th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-mono">
|
||||
<tbody class="font-monospace">
|
||||
<tr *ngFor='let values of seriesRow; let i=index'>
|
||||
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="text-right">
|
||||
<th class="{{seriesColor[i]}} text-end"> ● {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
|
||||
</td>
|
||||
<th class="{{seriesColor[i]}} text-right">
|
||||
<th class="{{seriesColor[i]}} text-end">
|
||||
<span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template>
|
||||
</th>
|
||||
|
||||
+48
-83
@@ -1,13 +1,12 @@
|
||||
import { Component, OnInit} from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { ChartistModule, Configuration } from 'ng-chartist';
|
||||
|
||||
import { Observable, Observer, Subscription } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { BackendService, CanopiesService } from 'src/app/core/services';
|
||||
import { Canopy, CanopyBySize, ReduceRow } from 'src/app/core/models';
|
||||
import { Canopy, CanopyModelBySize, CanopyModelByYear, chartPieDonute } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -15,106 +14,49 @@ import { Canopy, CanopyBySize, ReduceRow } from 'src/app/core/models';
|
||||
selector: 'huapp-canopy-models',
|
||||
templateUrl: './canopy-models.component.html'
|
||||
})
|
||||
export class CanopyModelsComponent implements OnInit {
|
||||
private _canopies: Subscription = new Subscription();
|
||||
aggregate!: Array<CanopyBySize>
|
||||
canopies!: Array<Canopy>;
|
||||
canopiesCount = 0;
|
||||
export class CanopyModelsComponent implements OnInit, OnDestroy {
|
||||
private _canopyBySize: Subscription = new Subscription();
|
||||
private _canopyByYear: Subscription = new Subscription();
|
||||
canopyBySize!: Array<CanopyModelBySize>;
|
||||
canopyByYear!: Array<CanopyModelByYear>;
|
||||
canopyBySizeCount = 0;
|
||||
canopyByYearCount = 0;
|
||||
rows: Object[] = [] as Array<Object>;
|
||||
seriesName: string[] = [];
|
||||
seriesValue: number[] = [];
|
||||
seriesColor: string[] = this._dataService.getChartColors();
|
||||
seriesHeader: string[] = [];
|
||||
seriesRow: any[] = [];
|
||||
donuteCanopyModel: Configuration = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
startAngle: 270,
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
donuteCanopies: Configuration = chartPieDonute;
|
||||
|
||||
constructor(
|
||||
private canopiesService: CanopiesService,
|
||||
private _dataService: BackendService
|
||||
) { }
|
||||
|
||||
/*
|
||||
loadDataByDate() {
|
||||
return this._dataService
|
||||
.getCanopyModelsByDate(2)
|
||||
.subscribe((res) => {
|
||||
this.seriesName.forEach((name: string) => {
|
||||
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
|
||||
});
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
res["rows"].forEach((row: ReduceRow) => {
|
||||
let year = row.key[1].toString();
|
||||
let voile = row.key[0];
|
||||
this.seriesRow[this.seriesName.indexOf(voile)][this.seriesHeader.indexOf(year)] = row.value;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
ngOnInit() {
|
||||
this.loadCanopies();
|
||||
/*
|
||||
return this._dataService
|
||||
.getCanopyModels()
|
||||
.subscribe((res) => {
|
||||
this.rows = res["rows"]
|
||||
var labels: string[] = [];
|
||||
var series: number[] = [];
|
||||
this.rows.forEach((row: ReduceRow) => {
|
||||
this.seriesName.push(row.key);
|
||||
this.seriesValue.push(row.value);
|
||||
labels.push(row.value.toString());
|
||||
series.push(row.value);
|
||||
});
|
||||
this.donuteCanopyModel = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": labels,
|
||||
"series": series
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
donutSolid: true,
|
||||
startAngle: 270,
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
return this.loadDataByDate();
|
||||
});
|
||||
*/
|
||||
this._loadCanopyModelBySize();
|
||||
}
|
||||
|
||||
loadCanopies() {
|
||||
const canopies$: Observable<Array<CanopyBySize>> = this.canopiesService.getAllBySize();
|
||||
this._canopies = canopies$.subscribe((aggregate: Array<CanopyBySize>) => {
|
||||
this.aggregate = aggregate;
|
||||
//this.canopies = canopies;
|
||||
this.canopiesCount = aggregate.length;
|
||||
ngOnDestroy() {
|
||||
this._canopyBySize.unsubscribe();
|
||||
this._canopyByYear.unsubscribe();
|
||||
}
|
||||
|
||||
private _loadCanopyModelBySize(): void {
|
||||
const canopies$: Observable<Array<CanopyModelBySize>> = this.canopiesService.getAllModelBySize();
|
||||
this._canopyBySize = canopies$.subscribe((aggregate: Array<CanopyModelBySize>) => {
|
||||
this.canopyBySize = aggregate;
|
||||
this.canopyBySizeCount = aggregate.length;
|
||||
var labels: string[] = [];
|
||||
var series: number[] = [];
|
||||
this.aggregate.forEach((row) => {
|
||||
this.seriesName.push(row._id.canopy + ' ' + row._id.taille);
|
||||
this.canopyBySize.forEach((row) => {
|
||||
this.seriesName.push(`${row._id.taille.toString()} - ${row._id.voile}`);
|
||||
this.seriesValue.push(row.count);
|
||||
labels.push(row.count.toString());
|
||||
series.push(row.count);
|
||||
});
|
||||
this.donuteCanopyModel = {
|
||||
this.donuteCanopies = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": labels,
|
||||
@@ -128,6 +70,29 @@ export class CanopyModelsComponent implements OnInit {
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
this._loadCanopyModelByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadCanopyModelByYear(): void {
|
||||
let values: Array<number> = [];
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
this.seriesHeader.forEach(() => {
|
||||
values.push(0);
|
||||
});
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<CanopyModelByYear>> = this.canopiesService.getAllModelByYear();
|
||||
this._canopyByYear = dropzones$.subscribe((aggregate: Array<CanopyModelByYear>) => {
|
||||
this.canopyByYear = aggregate;
|
||||
this.canopyByYearCount = aggregate.length;
|
||||
this.canopyByYear.forEach((row: CanopyModelByYear) => {
|
||||
let voile: string = row._id.voile;
|
||||
let taille: string = row._id.taille.toString();
|
||||
let year: string = row._id.year.toString();
|
||||
this.seriesRow[this.seriesName.indexOf(`${taille} - ${voile}`)][this.seriesHeader.indexOf(year)] = row.count;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+7
-9
@@ -3,9 +3,7 @@
|
||||
<mat-card-title>Taille de voile</mat-card-title>
|
||||
<mat-card-subtitle>Nombre total de sauts par taille</mat-card-subtitle>
|
||||
<div class="piechart">
|
||||
<x-chartist class="" [data]="donuteChartSize.data" [type]="donuteChartSize.type"
|
||||
[options]="donuteChartSize.options" [responsiveOptions]="donuteChartSize.responsiveOptions"
|
||||
[events]="donuteChartSize.events"> </x-chartist>
|
||||
<x-chartist [configuration]="donuteCanopiesSize"></x-chartist>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr>
|
||||
@@ -14,18 +12,18 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th>
|
||||
<th class="text-right">Total</th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-mono">
|
||||
<tbody class="font-monospace">
|
||||
<tr *ngFor='let values of seriesRow; let i=index'>
|
||||
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="text-right">
|
||||
<th class="{{seriesColor[i]}} text-end"> ● {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
|
||||
</td>
|
||||
<th class="{{seriesColor[i]}} text-right">
|
||||
<th class="{{seriesColor[i]}} text-end">
|
||||
<span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template>
|
||||
</th>
|
||||
|
||||
+74
-64
@@ -1,10 +1,12 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { ChartistModule, Configuration } from 'ng-chartist';
|
||||
|
||||
import { BackendService } from 'src/app/core/services';
|
||||
import { ReduceRow } from 'src/app/core/models';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { BackendService, CanopiesService } from 'src/app/core/services';
|
||||
import { chartPieDonute, CanopyBySize, CanopyByYear, ReduceRow } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -12,76 +14,84 @@ import { ReduceRow } from 'src/app/core/models';
|
||||
selector: 'huapp-canopy-sizes',
|
||||
templateUrl: './canopy-sizes.component.html'
|
||||
})
|
||||
export class CanopySizesComponent implements OnInit {
|
||||
export class CanopySizesComponent implements OnInit, OnDestroy {
|
||||
private _canopyBySize: Subscription = new Subscription();
|
||||
private _canopyByYear: Subscription = new Subscription();
|
||||
canopyBySize!: Array<CanopyBySize>;
|
||||
canopyByYear!: Array<CanopyByYear>;
|
||||
canopyBySizeCount = 0;
|
||||
canopyByYearCount = 0;
|
||||
rows: Object[] = [] as Array<Object>;
|
||||
seriesName: string[] = [];
|
||||
seriesValue: number[] = [];
|
||||
seriesColor: string[] = this._dataService.getChartColors();
|
||||
seriesHeader: string[] = [];
|
||||
seriesRow: any[] = [];
|
||||
donuteChartSize: Configuration = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
startAngle: 0,
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
donuteCanopiesSize: Configuration = chartPieDonute;
|
||||
|
||||
constructor(private _dataService: BackendService) { }
|
||||
|
||||
loadDataByDate() {
|
||||
return this._dataService
|
||||
.getCanopySizesByDate(2)
|
||||
.subscribe((res) => {
|
||||
this.seriesName.forEach((name: string) => {
|
||||
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
|
||||
});
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
res["rows"].forEach((row: ReduceRow) => {
|
||||
let year = row.key[1].toString();
|
||||
let size = row.key[0];
|
||||
this.seriesRow[this.seriesName.indexOf(size)][this.seriesHeader.indexOf(year)] = row.value;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
constructor(
|
||||
private canopiesService: CanopiesService,
|
||||
private _dataService: BackendService
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
return this._dataService
|
||||
.getCanopySizes()
|
||||
.subscribe((res) => {
|
||||
this.rows = res["rows"]
|
||||
var labels: string[] = [];
|
||||
var series: number[] = [];
|
||||
this.rows.forEach((row: ReduceRow) => {
|
||||
this.seriesName.push(row.key);
|
||||
this.seriesValue.push(row.value);
|
||||
labels.push(row.value.toString());
|
||||
series.push(row.value);
|
||||
});
|
||||
this.donuteChartSize = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": labels,
|
||||
"series": series
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
donutSolid: true,
|
||||
startAngle: 330,
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
return this.loadDataByDate();
|
||||
this._loadCanopyBySize();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._canopyBySize.unsubscribe();
|
||||
this._canopyByYear.unsubscribe();
|
||||
}
|
||||
|
||||
private _loadCanopyBySize(): void {
|
||||
const canopies$: Observable<Array<CanopyBySize>> = this.canopiesService.getAllBySize();
|
||||
this._canopyBySize = canopies$.subscribe((aggregate: Array<CanopyBySize>) => {
|
||||
this.canopyBySize = aggregate;
|
||||
this.canopyBySizeCount = aggregate.length;
|
||||
var labels: string[] = [];
|
||||
var series: number[] = [];
|
||||
this.canopyBySize.forEach((row) => {
|
||||
this.seriesName.push(row._id.taille.toString());
|
||||
this.seriesValue.push(row.count);
|
||||
labels.push(row.count.toString());
|
||||
series.push(row.count);
|
||||
});
|
||||
this.donuteCanopiesSize = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": labels,
|
||||
"series": series
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
startAngle: 330,
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
this._loadCanopyByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadCanopyByYear(): void {
|
||||
let values: Array<number> = [];
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
this.seriesHeader.forEach(() => {
|
||||
values.push(0);
|
||||
});
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<CanopyByYear>> = this.canopiesService.getAllByYear();
|
||||
this._canopyByYear = dropzones$.subscribe((aggregate: Array<CanopyByYear>) => {
|
||||
this.canopyByYear = aggregate;
|
||||
this.canopyByYearCount = aggregate.length;
|
||||
this.canopyByYear.forEach((row: CanopyByYear) => {
|
||||
let taille: string = row._id.taille.toString();
|
||||
let year: string = row._id.year.toString();
|
||||
this.seriesRow[this.seriesName.indexOf(taille)][this.seriesHeader.indexOf(year)] = row.count;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<mat-card-title>Les drop zones</mat-card-title>
|
||||
<mat-card-subtitle>Nombre total de sauts par DZ</mat-card-subtitle>
|
||||
<div class="piechart">
|
||||
<x-chartist [configuration]="donuteDropZones"> </x-chartist>
|
||||
<x-chartist [configuration]="donuteDropZones"></x-chartist>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr>
|
||||
|
||||
+76
-95
@@ -1,10 +1,12 @@
|
||||
import { Component, OnInit, Input, Output } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy, Input, Output } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { ChartistModule, Configuration } from 'ng-chartist';
|
||||
|
||||
import { BackendService } from 'src/app/core/services';
|
||||
import { DropZone, ReduceRow} from 'src/app/core/models';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { BackendService, DropZonesService } from 'src/app/core/services';
|
||||
import { chartBar, chartPieDonute, DropZone, DropZoneByOaci, DropZoneByYear } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -12,63 +14,86 @@ import { DropZone, ReduceRow} from 'src/app/core/models';
|
||||
selector: 'huapp-drop-zones-bar',
|
||||
templateUrl: './drop-zones-bar.component.html'
|
||||
})
|
||||
export class DropZonesBarComponent implements OnInit {
|
||||
export class DropZonesBarComponent implements OnInit, OnDestroy {
|
||||
private _dropzoneByOaci: Subscription = new Subscription();
|
||||
private _dropzoneByYear: Subscription = new Subscription();
|
||||
dropzoneByOaci!: Array<DropZoneByOaci>;
|
||||
dropzoneByYear!: Array<DropZoneByYear>;
|
||||
dropzoneByOaciCount = 0;
|
||||
dropzoneByYearCount = 0;
|
||||
dropzones: Object[] = [] as Array<Object>;
|
||||
seriesName: string[] = [];//= ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"];
|
||||
seriesName: string[] = [];
|
||||
seriesValue: number[] = [];
|
||||
seriesColor: string[] = this._dataService.getChartColors();
|
||||
seriesHeader: string[] = [];
|
||||
seriesRow: any[] = [];
|
||||
donuteDropZones: Configuration = {
|
||||
type: 'Pie',
|
||||
/*
|
||||
data: {
|
||||
"labels": ["261", "45", "178", "16", "13", "11", "4", "2"],
|
||||
"series": [261, 45, 178, 16, 13, 11, 4, 2]
|
||||
},
|
||||
*/
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
startAngle: 270,
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
barChartDropZones: Configuration = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {},
|
||||
responsiveOptions: []
|
||||
};
|
||||
donuteDropZones: Configuration = chartPieDonute;
|
||||
barChartDropZones: Configuration = chartBar;
|
||||
|
||||
constructor(private _dataService: BackendService) { }
|
||||
constructor(
|
||||
private dropzonesService: DropZonesService,
|
||||
private _dataService: BackendService
|
||||
) { }
|
||||
|
||||
loadDataByDate() {
|
||||
return this._dataService
|
||||
.getDropZonesByDate(2)
|
||||
.subscribe((res) => {
|
||||
console.log(res["rows"]);
|
||||
this.seriesName.forEach((name: string) => {
|
||||
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
|
||||
ngOnInit() {
|
||||
this._loadDropZoneByOaci();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._dropzoneByOaci.unsubscribe();
|
||||
this._dropzoneByYear.unsubscribe();
|
||||
}
|
||||
|
||||
private _loadDropZoneByOaci(): void {
|
||||
const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci();
|
||||
this._dropzoneByOaci = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
|
||||
this.dropzoneByOaci = aggregate;
|
||||
this.dropzoneByOaciCount = aggregate.length;
|
||||
var labels: string[] = [];
|
||||
var series: number[] = [];
|
||||
this.dropzoneByOaci.forEach((row) => {
|
||||
this.seriesName.push(`${row._id.oaci} - ${row._id.lieu}`);
|
||||
this.seriesValue.push(row.count);
|
||||
labels.push(row.count.toString());
|
||||
series.push(row.count);
|
||||
});
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
res["rows"].forEach((row: ReduceRow) => {
|
||||
let year = row.key[1].toString();
|
||||
let lieu = row.key[0];
|
||||
this.seriesRow[this.seriesName.indexOf(lieu)][this.seriesHeader.indexOf(year)] = row.value;
|
||||
//console.log(row.key, row.value);
|
||||
this.donuteDropZones = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": labels,
|
||||
"series": series
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 50,
|
||||
startAngle: 270,
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
this._loadDropZoneByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadDropZoneByYear(): void {
|
||||
let values: Array<number> = [];
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
this.seriesHeader.forEach(() => {
|
||||
values.push(0);
|
||||
});
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<DropZoneByYear>> = this.dropzonesService.getAllByDate();
|
||||
this._dropzoneByYear = dropzones$.subscribe((aggregate: Array<DropZoneByYear>) => {
|
||||
this.dropzoneByYear = aggregate;
|
||||
this.dropzoneByYearCount = aggregate.length;
|
||||
this.dropzoneByYear.forEach((row: DropZoneByYear) => {
|
||||
let lieu: string = row._id.lieu;
|
||||
let oaci: string = row._id.oaci;
|
||||
let year: string = row._id.year.toString();
|
||||
this.seriesRow[this.seriesName.indexOf(`${oaci} - ${lieu}`)][this.seriesHeader.indexOf(year)] = row.count;
|
||||
});
|
||||
//console.log(this.seriesName);
|
||||
//console.log(this.seriesHeader);
|
||||
//console.log(this.seriesRow);
|
||||
this.barChartDropZones = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
@@ -121,50 +146,6 @@ export class DropZonesBarComponent implements OnInit {
|
||||
}]
|
||||
]
|
||||
};
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
return this._dataService
|
||||
.getDropZones()
|
||||
.subscribe((res) => {
|
||||
//console.log('ngOnInit');
|
||||
//console.log(res["rows"]);
|
||||
this.dropzones = res["rows"]
|
||||
var labels: string[] = [];
|
||||
var series: number[] = [];
|
||||
this.dropzones.forEach((dropzone: DropZone) => {
|
||||
this.seriesName.push(dropzone.key);
|
||||
this.seriesValue.push(dropzone.value);
|
||||
//console.log(dropzone.key, dropzone.value);
|
||||
labels.push(dropzone.value.toString());
|
||||
series.push(dropzone.value);
|
||||
});
|
||||
this.donuteDropZones = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": labels,
|
||||
"series": series
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
donutSolid: true,
|
||||
startAngle: 270,
|
||||
showLabel: true
|
||||
}
|
||||
/*,
|
||||
events: <ChartEvent>{
|
||||
draw: (data) => {
|
||||
//this.donuteDropZones.data = data;
|
||||
console.log(data);
|
||||
}
|
||||
}
|
||||
*/
|
||||
};
|
||||
return this.loadDataByDate();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<mat-card-title>Les drop zones</mat-card-title>
|
||||
<mat-card-subtitle>Nombre total de sauts par DZ</mat-card-subtitle>
|
||||
<div class="piechart">
|
||||
<x-chartist [configuration]="donuteDropZones"> </x-chartist>
|
||||
<x-chartist [configuration]="donuteDropZones"></x-chartist>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr>
|
||||
@@ -12,18 +12,18 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th>
|
||||
<th class="text-right">Total</th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-mono">
|
||||
<tbody class="font-monospace">
|
||||
<tr *ngFor='let values of seriesRow; let i=index'>
|
||||
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="text-right">
|
||||
<th class="{{seriesColor[i]}} text-end"> ✹ {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
|
||||
</td>
|
||||
<th class="{{seriesColor[i]}} text-right">
|
||||
<th class="{{seriesColor[i]}} text-end">
|
||||
<span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template>
|
||||
</th>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Component, OnInit, Input, Output } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy, Input, Output } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { ChartistModule, Configuration } from 'ng-chartist';
|
||||
|
||||
import { Observable, Observer, Subscription } from 'rxjs';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { BackendService, DropZonesService } from 'src/app/core/services';
|
||||
import { DropZone, DropZoneByOaci, ReduceRow} from 'src/app/core/models';
|
||||
import { DropZoneByOaci, DropZoneByYear, chartPieDonute} from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -14,156 +14,43 @@ import { DropZone, DropZoneByOaci, ReduceRow} from 'src/app/core/models';
|
||||
selector: 'huapp-drop-zones',
|
||||
templateUrl: './drop-zones.component.html'
|
||||
})
|
||||
export class DropZonesComponent implements OnInit {
|
||||
private _dropzones: Subscription = new Subscription();
|
||||
aggregate!: Array<DropZoneByOaci>
|
||||
dropzones!: Array<DropZone>;
|
||||
dropzonesCount = 0;
|
||||
seriesName: string[] = [];//= ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"];
|
||||
export class DropZonesComponent implements OnInit, OnDestroy {
|
||||
private _dropzoneByOaci: Subscription = new Subscription();
|
||||
private _dropzoneByYear: Subscription = new Subscription();
|
||||
dropzoneByOaci!: Array<DropZoneByOaci>;
|
||||
dropzoneByYear!: Array<DropZoneByYear>;
|
||||
dropzoneByOaciCount = 0;
|
||||
dropzoneByYearCount = 0;
|
||||
seriesName: string[] = [];
|
||||
seriesValue: number[] = [];
|
||||
seriesColor: string[] = this._dataService.getChartColors();
|
||||
seriesHeader: string[] = [];
|
||||
seriesRow: any[] = [];
|
||||
donuteDropZones: Configuration = {
|
||||
type: 'Pie',
|
||||
/*
|
||||
data: {
|
||||
"labels": ["261", "45", "178", "16", "13", "11", "4", "2"],
|
||||
"series": [261, 45, 178, 16, 13, 11, 4, 2]
|
||||
},
|
||||
*/
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
startAngle: 270,
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
barChartDropZones: Configuration = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {
|
||||
seriesBarDistance: 5,
|
||||
high: 170,
|
||||
axisX: {
|
||||
showGrid: false,
|
||||
offset: 20
|
||||
},
|
||||
axisY: {
|
||||
showGrid: true,
|
||||
offset: 40
|
||||
},
|
||||
height: 207
|
||||
},
|
||||
responsiveOptions: [
|
||||
['screen and (min-width: 1024px)', {
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: number, index: number): string {
|
||||
return index % 1 === 0 ? `${value}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (min-width: 641px) and (max-width: 1024px)', {
|
||||
seriesBarDistance: 10,
|
||||
axisY: {
|
||||
offset: 30
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (max-width: 640px)', {
|
||||
seriesBarDistance: 5,
|
||||
axisY: {
|
||||
offset: 20
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
};
|
||||
donuteDropZones: Configuration = chartPieDonute;
|
||||
|
||||
constructor(
|
||||
private dropzonesService: DropZonesService,
|
||||
private _dataService: BackendService
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.loadDropZones();
|
||||
/*
|
||||
return this._dataService
|
||||
.getDropZones()
|
||||
.subscribe((res) => {
|
||||
this.dropzones = res["rows"]
|
||||
var labels: string[] = [];
|
||||
var series: number[] = [];
|
||||
this.dropzones.forEach((dropzone: DropZone) => {
|
||||
this.seriesName.push(dropzone.key);
|
||||
this.seriesValue.push(dropzone.value);
|
||||
labels.push(dropzone.value.toString());
|
||||
series.push(dropzone.value);
|
||||
});
|
||||
this.donuteDropZones = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": labels,
|
||||
"series": series
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 40,
|
||||
donutSolid: true,
|
||||
startAngle: 270,
|
||||
showLabel: true
|
||||
}
|
||||
,
|
||||
// events: <ChartEvent>{
|
||||
// draw: (data) => {
|
||||
// //this.donuteDropZones.data = data;
|
||||
// console.log(data);
|
||||
// }
|
||||
// }
|
||||
};
|
||||
return this._dataService
|
||||
.getDropZonesByDate(2)
|
||||
.subscribe((res) => {
|
||||
this.seriesName.forEach((name: string) => {
|
||||
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
|
||||
});
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
res["rows"].forEach((row: ReduceRow) => {
|
||||
let year = row.key[1].toString();
|
||||
let lieu = row.key[0];
|
||||
this.seriesRow[this.seriesName.indexOf(lieu)][this.seriesHeader.indexOf(year)] = row.value;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
});
|
||||
*/
|
||||
this._loadDropZoneByOaci();
|
||||
}
|
||||
|
||||
loadDropZones() {
|
||||
ngOnDestroy() {
|
||||
this._dropzoneByOaci.unsubscribe();
|
||||
this._dropzoneByYear.unsubscribe();
|
||||
}
|
||||
|
||||
private _loadDropZoneByOaci(): void {
|
||||
const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci();
|
||||
this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
|
||||
this.aggregate = aggregate;
|
||||
//this.dropzones = dropzones;
|
||||
this.dropzonesCount = aggregate.length;
|
||||
this._dropzoneByOaci = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
|
||||
this.dropzoneByOaci = aggregate;
|
||||
this.dropzoneByOaciCount = aggregate.length;
|
||||
var labels: string[] = [];
|
||||
var series: number[] = [];
|
||||
this.aggregate.forEach((row) => {
|
||||
this.seriesName.push(row._id.lieu + ' ' + row._id.oaci);
|
||||
this.dropzoneByOaci.forEach((row) => {
|
||||
this.seriesName.push(`${row._id.oaci} - ${row._id.lieu}`);
|
||||
this.seriesValue.push(row.count);
|
||||
labels.push(row.count.toString());
|
||||
series.push(row.count);
|
||||
@@ -182,6 +69,29 @@ export class DropZonesComponent implements OnInit {
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
this._loadDropZoneByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadDropZoneByYear(): void {
|
||||
let values: Array<number> = [];
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
this.seriesHeader.forEach(() => {
|
||||
values.push(0);
|
||||
});
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<DropZoneByYear>> = this.dropzonesService.getAllByDate();
|
||||
this._dropzoneByYear = dropzones$.subscribe((aggregate: Array<DropZoneByYear>) => {
|
||||
this.dropzoneByYear = aggregate;
|
||||
this.dropzoneByYearCount = aggregate.length;
|
||||
this.dropzoneByYear.forEach((row: DropZoneByYear) => {
|
||||
let lieu: string = row._id.lieu;
|
||||
let oaci: string = row._id.oaci;
|
||||
let year: string = row._id.year.toString();
|
||||
this.seriesRow[this.seriesName.indexOf(`${oaci} - ${lieu}`)][this.seriesHeader.indexOf(year)] = row.count;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export * from './aeronefs/aeronefs.component';
|
||||
//export * from './aeronefs-bar/aeronefs-bar.component';
|
||||
export * from './aeronefs-bar/aeronefs-bar.component';
|
||||
export * from './canopy-models/canopy-models.component';
|
||||
//export * from './canopy-sizes/canopy-sizes.component';
|
||||
export * from './canopy-sizes/canopy-sizes.component';
|
||||
export * from './drop-zones/drop-zones.component';
|
||||
//export * from './drop-zones-bar/drop-zones-bar.component';
|
||||
//export * from './jumps-by-month/jumps-by-month.component';
|
||||
export * from './drop-zones-bar/drop-zones-bar.component';
|
||||
export * from './jumps-by-month/jumps-by-month.component';
|
||||
+17
-14
@@ -7,15 +7,18 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="barchrt">
|
||||
<x-chartist class="" [data]="barChartJumps.data" [type]="barChartJumps.type" [options]="barChartJumps.options" [responsiveOptions]="barChartJumps.responsiveOptions"
|
||||
<x-chartist [configuration]="barChartJumps"></x-chartist>
|
||||
<!--
|
||||
<x-chartist class="" [data]="barChartJumps.data" [type]="barChartJumps.type" [options]="barChartJumps.options" [responsiveOptions]="barChartJumps.responsiveOptions"
|
||||
[events]="barChartJumps.events"> </x-chartist>
|
||||
-->
|
||||
</div>
|
||||
<div class="text-center mt-3 mb-2">
|
||||
<div class="text-center my-3">
|
||||
<ul class="list-inline my-0">
|
||||
<li *ngFor='let name of seriesName; let i=index'>
|
||||
<h4 class="{{seriesColor[i]}} m-0">
|
||||
<i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i>{{name}}
|
||||
</h4>
|
||||
<li *ngFor='let name of seriesName; let i=index' class="list-inline-item me-lg-3 me-sm-2">
|
||||
<span class="{{seriesColor[i]}} fs-6 m-0">
|
||||
● {{name}}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -25,28 +28,28 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th>
|
||||
<th class="text-right">Total</th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor='let values of seriesRow; let i=index'>
|
||||
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="text-mono text-right">
|
||||
<th class="{{seriesColor[i]}} text-end"> ● {{seriesName[i]}} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="font-monospace text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
|
||||
</td>
|
||||
<th class="text-mono text-right">{{seriesRowTotal[i]}}</th>
|
||||
<th class="font-monospace text-end">{{seriesRowTotal[i]}}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th class="text-right">Total</th>
|
||||
<th *ngFor='let value of seriesColTotal; let i=index' class="text-mono text-right">
|
||||
<th class="text-end">Total</th>
|
||||
<th *ngFor='let value of seriesColTotal; let i=index' class="font-monospace text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
|
||||
</th>
|
||||
<th class="text-mono text-right">{{grandTotal}}</th>
|
||||
<th class="font-monospace text-end">{{grandTotal}}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
+103
-133
@@ -1,20 +1,26 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { ChartistModule, Configuration } from 'ng-chartist';
|
||||
|
||||
import { BackendService } from 'src/app/core/services';
|
||||
import { ReduceRow } from 'src/app/core/models';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { BackendService, JumpsService } from 'src/app/core/services';
|
||||
import { chartBar, JumpByDate, ReduceRow } from 'src/app/core/models';
|
||||
|
||||
declare var require: any;
|
||||
const data= require('./data.json');
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [MatCardModule, ChartistModule],
|
||||
imports: [CommonModule, MatCardModule, ChartistModule],
|
||||
selector: 'huapp-jumps-by-month',
|
||||
templateUrl: './jumps-by-month.component.html'
|
||||
})
|
||||
export class JumpsByMonthComponent implements OnInit {
|
||||
export class JumpsByMonthComponent implements OnInit, OnDestroy {
|
||||
private _jumpByDate: Subscription = new Subscription();
|
||||
jumpByDate!: Array<JumpByDate>;
|
||||
jumpByDateCount = 0;
|
||||
rows: Object[] = [] as Array<Object>;
|
||||
min: number = 0;
|
||||
max: number = 0;
|
||||
@@ -25,140 +31,104 @@ export class JumpsByMonthComponent implements OnInit {
|
||||
seriesColTotal: number[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
seriesName: String[] = []; // ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
seriesColor: String[] = this._dataService.getChartColors();
|
||||
barChartJumps: Configuration = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {
|
||||
seriesBarDistance: 5,
|
||||
high: 70,
|
||||
axisX: {
|
||||
showGrid: false,
|
||||
offset: 20
|
||||
},
|
||||
axisY: {
|
||||
showGrid: true,
|
||||
offset: 40
|
||||
},
|
||||
height: 300
|
||||
},
|
||||
responsiveOptions: [
|
||||
['screen and (min-width: 1024px)', {
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: number, index: number): string {
|
||||
return index % 1 === 0 ? `${value}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (min-width: 641px) and (max-width: 1024px)', {
|
||||
seriesBarDistance: 10,
|
||||
axisY: {
|
||||
offset: 30
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[0]}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (max-width: 640px)', {
|
||||
seriesBarDistance: 5,
|
||||
axisY: {
|
||||
offset: 20
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[0]}` : '';
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
};
|
||||
constructor(private _dataService: BackendService) { }
|
||||
barChartJumps: Configuration = chartBar;
|
||||
|
||||
constructor(
|
||||
private jumpsService: JumpsService,
|
||||
private _dataService: BackendService
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
return this._dataService
|
||||
.getJumpsByDate(2)
|
||||
.subscribe((res) => {
|
||||
//console.log(res["rows"]);
|
||||
this.rows = res["rows"]
|
||||
this.rows.forEach((row: ReduceRow) => {
|
||||
let year = row.key[0].toString();
|
||||
let month = row.key[1];
|
||||
if (this.seriesName.indexOf(year) < 0) {
|
||||
this.seriesName.push(year);
|
||||
if (row.key[0] < this.min || this.min == 0) {
|
||||
this.min = row.key[0];
|
||||
}
|
||||
if (row.key[0] > this.max) {
|
||||
this.max = row.key[0];
|
||||
}
|
||||
this.seriesRow.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
this._loadJumpByDate();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._jumpByDate.unsubscribe();
|
||||
}
|
||||
|
||||
private _loadJumpByDate() {
|
||||
let values: Array<number> = [];
|
||||
this.seriesHeader.forEach(() => {
|
||||
values.push(0);
|
||||
});
|
||||
const jumps$: Observable<Array<JumpByDate>> = this.jumpsService.getAllByDate();
|
||||
this._jumpByDate = jumps$.subscribe((aggregate: Array<JumpByDate>) => {
|
||||
this.jumpByDate = aggregate;
|
||||
this.jumpByDateCount = aggregate.length;
|
||||
console.log(this.jumpByDate);
|
||||
console.log(this.jumpByDateCount);
|
||||
this.jumpByDate.forEach((row) => {
|
||||
let year = row._id.year.toString();
|
||||
let month = row._id.month;
|
||||
if (this.seriesName.indexOf(year) < 0) {
|
||||
this.seriesName.push(year);
|
||||
if (row._id.year < this.min || this.min == 0) {
|
||||
this.min = row._id.year;
|
||||
}
|
||||
this.seriesRow[(this.seriesRow.length-1)][(month-1)] = row.value;
|
||||
this.seriesColTotal[(month-1)] += row.value;
|
||||
//console.log(row.key, row.value);
|
||||
});
|
||||
this.seriesRow.forEach((row: number[]) => {
|
||||
const total = row.reduce((partialSum, a) => partialSum + a, 0);
|
||||
this.seriesRowTotal.push(total);
|
||||
});
|
||||
console.log(this.seriesColTotal);
|
||||
this.grandTotal = this.seriesColTotal.reduce((partialSum, a) => partialSum + a, 0);
|
||||
//console.log(this.seriesRow, this.seriesName);
|
||||
this.barChartJumps = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": this.seriesHeader,
|
||||
"series": this.seriesRow
|
||||
if (row._id.year > this.max) {
|
||||
this.max = row._id.year;
|
||||
}
|
||||
this.seriesRow.push([...values]);
|
||||
}
|
||||
this.seriesRow[(this.seriesRow.length-1)][(month-1)] = row.count;
|
||||
this.seriesColTotal[(month-1)] += row.count;
|
||||
});
|
||||
this.seriesRow.forEach((row: number[]) => {
|
||||
const total = row.reduce((partialSum, a) => partialSum + a, 0);
|
||||
this.seriesRowTotal.push(total);
|
||||
});
|
||||
this.grandTotal = this.seriesColTotal.reduce((partialSum, a) => partialSum + a, 0);
|
||||
this.barChartJumps = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": this.seriesHeader,
|
||||
"series": this.seriesRow
|
||||
},
|
||||
options: {
|
||||
seriesBarDistance: 15,
|
||||
high: 70,
|
||||
axisX: {
|
||||
showGrid: false,
|
||||
offset: 20
|
||||
},
|
||||
options: {
|
||||
seriesBarDistance: 15,
|
||||
high: 70,
|
||||
axisY: {
|
||||
showGrid: true,
|
||||
offset: 40
|
||||
},
|
||||
height: 300
|
||||
},
|
||||
responsiveOptions: [
|
||||
['screen and (min-width: 1024px)', {
|
||||
axisX: {
|
||||
showGrid: false,
|
||||
labelInterpolationFnc: function(value: number, index: number): string {
|
||||
return index % 1 === 0 ? `${value}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (min-width: 641px) and (max-width: 1024px)', {
|
||||
seriesBarDistance: 10,
|
||||
axisY: {
|
||||
offset: 30
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[0]}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (max-width: 640px)', {
|
||||
seriesBarDistance: 5,
|
||||
axisY: {
|
||||
offset: 20
|
||||
},
|
||||
axisY: {
|
||||
showGrid: true,
|
||||
offset: 40
|
||||
},
|
||||
height: 300
|
||||
},
|
||||
responsiveOptions: [
|
||||
['screen and (min-width: 1024px)', {
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: number, index: number): string {
|
||||
return index % 1 === 0 ? `${value}` : '';
|
||||
}
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[0]}` : '';
|
||||
}
|
||||
}],
|
||||
['screen and (min-width: 641px) and (max-width: 1024px)', {
|
||||
seriesBarDistance: 10,
|
||||
axisY: {
|
||||
offset: 30
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[0]}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (max-width: 640px)', {
|
||||
seriesBarDistance: 5,
|
||||
axisY: {
|
||||
offset: 20
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[0]}` : '';
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
};
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}]
|
||||
]
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,27 @@
|
||||
<div *appShowAuthed="false">
|
||||
Not connected
|
||||
</div>
|
||||
<div>
|
||||
<huapp-aeronefs></huapp-aeronefs>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-sm-12">
|
||||
<huapp-jumps-by-month></huapp-jumps-by-month>
|
||||
</div>
|
||||
<div class="col-md-4 col-sm-12">
|
||||
<huapp-drop-zones></huapp-drop-zones>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<huapp-drop-zones></huapp-drop-zones>
|
||||
</div>
|
||||
<div>
|
||||
<huapp-canopy-models></huapp-canopy-models>
|
||||
<div class="row mt-sm-2 mt-lg-3">
|
||||
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">
|
||||
<huapp-canopy-sizes></huapp-canopy-sizes>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">
|
||||
<huapp-canopy-models></huapp-canopy-models>
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-4 col-sm-6 col-xs-12">
|
||||
<huapp-aeronefs-bar></huapp-aeronefs-bar>
|
||||
<!--
|
||||
<huapp-aeronefs></huapp-aeronefs>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<div fxLayout="row wrap">
|
||||
|
||||
@@ -5,18 +5,19 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
|
||||
import { Observable, Observer, Subscription } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
import { User, Errors, Aeronef, AeronefByImat, AeronefList, Canopy, CanopyBySize, DropZone, DropZoneByOaci } from 'src/app/core/models';
|
||||
import { User, Errors, Aeronef, AeronefByImat, Canopy, CanopyModelBySize, DropZone, DropZoneByYear } from 'src/app/core/models';
|
||||
import { AeronefsService, CanopiesService, DropZonesService, UserService } from 'src/app/core/services';
|
||||
import { ShowAuthedDirective } from 'src/app/components/shared/show-authed.directive';
|
||||
import { AeronefsComponent, DropZonesComponent, CanopyModelsComponent } from './dashboard-components';
|
||||
import { AeronefsBarComponent, DropZonesComponent, CanopyModelsComponent, CanopySizesComponent, JumpsByMonthComponent } from './dashboard-components';
|
||||
//import { JumpsByMonthComponent, AeronefsComponent, AeronefsBarComponent, DropZonesComponent, DropZonesBarComponent, CanopySizesComponent, CanopyModelsComponent} from './dashboard-components';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [
|
||||
ShowAuthedDirective,
|
||||
AeronefsBarComponent, DropZonesComponent, CanopyModelsComponent, CanopySizesComponent, JumpsByMonthComponent
|
||||
//AeronefsComponent, AeronefsBarComponent, DropZonesComponent, DropZonesBarComponent,
|
||||
//CanopySizesComponent, CanopyModelsComponent, JumpsByMonthComponent,
|
||||
AeronefsComponent, DropZonesComponent, CanopyModelsComponent, ShowAuthedDirective
|
||||
],
|
||||
selector: 'huapp-home',
|
||||
templateUrl: './home.component.html',
|
||||
@@ -32,13 +33,15 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
errors!: Errors;
|
||||
isAuthenticated = false;
|
||||
canModify = false;
|
||||
|
||||
aeronefAggregate!: Array<AeronefByImat>
|
||||
aeronefs!: Array<Aeronef>;
|
||||
aeronefsCount = 0;
|
||||
canopyAggregate!: Array<CanopyBySize>
|
||||
canopyAggregate!: Array<CanopyModelBySize>
|
||||
canopies!: Array<Canopy>;
|
||||
canopiesCount = 0;
|
||||
dropzoneAggregate!: Array<DropZoneByOaci>
|
||||
//dropzoneAggregate!: Array<DropZoneByOaci>
|
||||
dropzoneAggregate!: Array<DropZoneByYear>
|
||||
dropzones!: Array<DropZone>;
|
||||
dropzonesCount = 0;
|
||||
|
||||
@@ -46,10 +49,10 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private titleService: Title,
|
||||
private userService: UserService,
|
||||
private aeronefsService: AeronefsService,
|
||||
private canopiesService: CanopiesService,
|
||||
private dropzonesService: DropZonesService,
|
||||
private userService: UserService
|
||||
private dropzonesService: DropZonesService
|
||||
) {
|
||||
this._resetErrors();
|
||||
}
|
||||
@@ -64,51 +67,61 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
this.router.navigateByUrl('/login');
|
||||
return;
|
||||
}
|
||||
const currentUser$: Observable<User> = this.userService.currentUser.pipe(take(1));
|
||||
const currentUser$: Observable<User> = this.userService.currentUser;
|
||||
this._currentUser = currentUser$.subscribe((userData: User) => {
|
||||
this.canModify = userData.role === 'Admin';
|
||||
});
|
||||
});
|
||||
this.loadAeronefs();
|
||||
this.loadCanopies();
|
||||
this.loadDropzones();
|
||||
}
|
||||
/*
|
||||
this._loadAeronefs();
|
||||
this._loadCanopies();
|
||||
this._loadDropzones();
|
||||
*/
|
||||
|
||||
loadAeronefs() {
|
||||
const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat();
|
||||
this._aeronefs = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
|
||||
this.aeronefAggregate = aggregate;
|
||||
this.aeronefsCount = aggregate.length;
|
||||
console.log(this.aeronefs);
|
||||
console.log(this.aeronefsCount);
|
||||
});
|
||||
}
|
||||
loadCanopies() {
|
||||
const canopies$: Observable<Array<CanopyBySize>> = this.canopiesService.getAllBySize();
|
||||
this._canopies = canopies$.subscribe((aggregate: Array<CanopyBySize>) => {
|
||||
this.canopyAggregate = aggregate;
|
||||
this.canopiesCount = aggregate.length;
|
||||
// console.log(this.canopies);
|
||||
// console.log(this.canopiesCount);
|
||||
});
|
||||
}
|
||||
loadDropzones() {
|
||||
const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci();
|
||||
this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
|
||||
this.dropzoneAggregate = aggregate;
|
||||
this.dropzonesCount = aggregate.length;
|
||||
// console.log(this.dropzones);
|
||||
// console.log(this.dropzonesCount);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._currentUser.unsubscribe();
|
||||
/*
|
||||
this._aeronefs.unsubscribe();
|
||||
this._canopies.unsubscribe();
|
||||
this._dropzones.unsubscribe();
|
||||
*/
|
||||
}
|
||||
|
||||
private _resetErrors(): void {
|
||||
this.errors = { errors: {} };
|
||||
}
|
||||
|
||||
private _loadAeronefs(): void {
|
||||
const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat();
|
||||
this._aeronefs = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
|
||||
this.aeronefAggregate = aggregate;
|
||||
this.aeronefsCount = aggregate.length;
|
||||
console.log(this.aeronefAggregate);
|
||||
console.log(this.aeronefsCount);
|
||||
});
|
||||
}
|
||||
|
||||
private _loadCanopies(): void {
|
||||
const canopies$: Observable<Array<CanopyModelBySize>> = this.canopiesService.getAllModelBySize();
|
||||
this._canopies = canopies$.subscribe((aggregate: Array<CanopyModelBySize>) => {
|
||||
this.canopyAggregate = aggregate;
|
||||
this.canopiesCount = aggregate.length;
|
||||
console.log(this.canopyAggregate);
|
||||
console.log(this.canopiesCount);
|
||||
});
|
||||
}
|
||||
|
||||
private _loadDropzones(): void {
|
||||
//const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci();
|
||||
//this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
|
||||
const dropzones$: Observable<Array<DropZoneByYear>> = this.dropzonesService.getAllByDate();
|
||||
this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneByYear>) => {
|
||||
this.dropzoneAggregate = aggregate;
|
||||
this.dropzonesCount = aggregate.length;
|
||||
console.log(this.dropzoneAggregate);
|
||||
console.log(this.dropzonesCount);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<!-- Numero Column -->
|
||||
<ng-container matColumnDef="numero">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Numero </th>
|
||||
<td class="text-right pl-3 pr-3" mat-cell *matCellDef="let element">
|
||||
<td class="text-end pl-3 pr-3" mat-cell *matCellDef="let element">
|
||||
<ng-container *ngIf="element.numero"><a [routerLink]="['/jump', element.slug]">{{element.numero}}</a></ng-container>
|
||||
<ng-container *ngIf="!element.numero"><ngx-skeleton-loader [theme]="{width: '30px', height: '13px', marginBottom: '0px'}"></ngx-skeleton-loader></ng-container>
|
||||
</td>
|
||||
@@ -94,7 +94,7 @@
|
||||
<!-- Taille Column -->
|
||||
<ng-container matColumnDef="taille">
|
||||
<th class="pl-3" mat-header-cell *matHeaderCellDef> Taille </th>
|
||||
<td class="text-nowrap text-right pl-3 pr-3" mat-cell *matCellDef="let element">
|
||||
<td class="text-nowrap text-end pl-3 pr-3" mat-cell *matCellDef="let element">
|
||||
<ng-container *ngIf="element.taille">{{element.taille}}</ng-container>
|
||||
<ng-container *ngIf="!element.numero"><ngx-skeleton-loader [theme]="{width: '30px', height: '13px', marginBottom: '0px'}"></ngx-skeleton-loader></ng-container>
|
||||
</td>
|
||||
@@ -118,7 +118,7 @@
|
||||
<!-- Participants Column -->
|
||||
<ng-container matColumnDef="participants">
|
||||
<th class="pl-3" mat-header-cell *matHeaderCellDef> Participants </th>
|
||||
<td class="text-right pl-3 pr-3" mat-cell *matCellDef="let element">
|
||||
<td class="text-end pl-3 pr-3" mat-cell *matCellDef="let element">
|
||||
<ng-container *ngIf="element.participants">{{element.participants}}</ng-container>
|
||||
<ng-container *ngIf="!element.numero"><ngx-skeleton-loader [theme]="{width: '30px', height: '13px', marginBottom: '0px'}"></ngx-skeleton-loader></ng-container>
|
||||
</td>
|
||||
|
||||
@@ -1,7 +1,54 @@
|
||||
<huapp-layout-header></huapp-layout-header>
|
||||
<mat-toolbar color="primary" class="topbar">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="index.html">
|
||||
<span>
|
||||
<img src="assets/images/logo-light-icon.svg" alt="homepage" class="light-logo">
|
||||
</span>
|
||||
<span>
|
||||
<img src="assets/images/logo-light-text.svg" alt="homepage" class="light-logo">
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<button mat-icon-button (click)="snav.toggle()" value="sidebarclosed">
|
||||
<mat-icon fontIcon="menu"></mat-icon>
|
||||
</button>
|
||||
<span class="flex-spacer"></span>
|
||||
<ng-container *appShowAuthed="true">
|
||||
<span class="fw-light me-1">@{{ currentUser.username }}</span>
|
||||
<div class="position-relative">
|
||||
<button [matMenuTriggerFor]="profile" mat-icon-button>
|
||||
<img [src]="currentUser.image" alt="user" class="profile-pic">
|
||||
</button>
|
||||
<mat-menu #profile="matMenu">
|
||||
<button mat-menu-item [routerLink]="['/profile', currentUser.username]" routerLinkActive="active">
|
||||
<mat-icon fontIcon="account_circle" color="primary"></mat-icon> Mon compte
|
||||
</button>
|
||||
<button mat-menu-item routerLink="/settings" routerLinkActive="active">
|
||||
<mat-icon fontIcon="settings" color="primary"></mat-icon> Paramètres
|
||||
</button>
|
||||
<button mat-menu-item (click)="goToGitHub()">
|
||||
<mat-icon fontIcon="code" color="primary"></mat-icon> GitHub
|
||||
</button>
|
||||
<button mat-menu-item>
|
||||
<mat-icon fontIcon="notifications_off" color="primary"></mat-icon> Désactiver les notifications
|
||||
</button>
|
||||
<hr class="my-0" />
|
||||
<button mat-menu-item (click)="logout()">
|
||||
<mat-icon fontIcon="logout" color="warn"></mat-icon> Se déconnecter
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *appShowAuthed="false">
|
||||
<span>
|
||||
<button mat-button routerLink="/login" routerLinkActive="active">Se connecter</button>
|
||||
<button mat-button routerLink="/register" routerLinkActive="active">Créer un compte</button>
|
||||
</span>
|
||||
</ng-container>
|
||||
</mat-toolbar>
|
||||
<mat-sidenav-container class="app-sidenav-container" [style.marginTop.px]="mobileQuery.matches ? 0 : 0">
|
||||
<mat-sidenav #snav id="snav" class="dark-sidebar pl-xs" [mode]="mobileQuery.matches ? 'side' : 'over'" fixedTopGap="0" [opened]="mobileQuery.matches" [disableClose]="mobileQuery.matches" >
|
||||
<div *appShowAuthed="true">
|
||||
<mat-sidenav #snav id="snav" class="dark-sidebar pl-xs" [mode]="mobileQuery.matches ? 'side' : 'over'" fixedTopGap="0" [opened]="mobileQuery.matches" [disableClose]="mobileQuery.matches">
|
||||
<ng-container *appShowAuthed="true">
|
||||
<div class="user-profile" style="background-image: url('{{ currentUser.bg_image }}');">
|
||||
<div class="profile-img"> <img [src]="currentUser.image" alt="user"> </div>
|
||||
<div class="profile-text">
|
||||
@@ -48,8 +95,8 @@
|
||||
</mat-list-item>
|
||||
</div>
|
||||
</mat-nav-list>
|
||||
</div>
|
||||
<div *appShowAuthed="false">
|
||||
</ng-container>
|
||||
<ng-container *appShowAuthed="false">
|
||||
<div class="user-profile">
|
||||
<!-- <div class="profile-img"> <img src="/assets/images/users/user.jpg" alt="user"> </div> -->
|
||||
</div>
|
||||
@@ -78,7 +125,7 @@
|
||||
</mat-list-item>
|
||||
</div>
|
||||
</mat-nav-list>
|
||||
</div>
|
||||
</ng-container>
|
||||
<huapp-layout-footer></huapp-layout-footer>
|
||||
</mat-sidenav>
|
||||
<mat-sidenav-content class="page-wrapper">
|
||||
|
||||
@@ -20,10 +20,12 @@ import { UserService } from 'src/app/core/services';
|
||||
]
|
||||
})
|
||||
export class HeaderComponent implements OnInit, OnDestroy {
|
||||
|
||||
private _currentUser: Subscription = new Subscription();
|
||||
private _isAuthenticated: Subscription = new Subscription();
|
||||
private isAuthenticated = false;
|
||||
currentUser: User = {} as User;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private userService: UserService
|
||||
|
||||
@@ -19,6 +19,7 @@ export interface AeronefByImat {
|
||||
export interface AeronefByYear {
|
||||
_id: {
|
||||
aeronef: string,
|
||||
imat: string,
|
||||
year: number
|
||||
},
|
||||
count: number
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
export interface WeightSize {
|
||||
export interface CalcResult {
|
||||
weight: number;
|
||||
active?: string;
|
||||
ranges: Range[];
|
||||
jumps: number;
|
||||
minSize: number;
|
||||
minSize11: number;
|
||||
minSize21: number;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface WeightSizes {
|
||||
data: WeightSize[];
|
||||
export interface InputParams {
|
||||
jumps: number;
|
||||
weight: number;
|
||||
gear: number;
|
||||
current: number;
|
||||
}
|
||||
|
||||
export interface Range {
|
||||
@@ -18,6 +23,16 @@ export interface Range {
|
||||
value: number;
|
||||
}
|
||||
|
||||
export interface WeightSize {
|
||||
weight: number;
|
||||
active?: string;
|
||||
ranges: Range[];
|
||||
}
|
||||
|
||||
export interface WeightSizes {
|
||||
data: WeightSize[];
|
||||
}
|
||||
|
||||
export const weightSizes: WeightSize[] = [
|
||||
{active: '', weight: 60, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 175}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 161}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 147}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 133}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 124}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 115}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 107}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 97}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 89}] },
|
||||
{active: '', weight: 61, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 178}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 163}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 149}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 135}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 126}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 116}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 108}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 98}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 90}] },
|
||||
@@ -71,18 +86,3 @@ export const weightSizes: WeightSize[] = [
|
||||
{active: '', weight: 109, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 298}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 274}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 247}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 219}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 199}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 179}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 161}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 138}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 120}] },
|
||||
{active: '', weight: 110, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 300}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 276}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 249}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 220}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 201}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 180}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 162}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 138}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 120}] }
|
||||
]
|
||||
|
||||
export interface CalcResult {
|
||||
weight: number;
|
||||
jumps: number;
|
||||
minSize: number;
|
||||
minSize11: number;
|
||||
minSize21: number;
|
||||
error?: string;
|
||||
}
|
||||
export interface InputParams {
|
||||
jumps: number;
|
||||
weight: number;
|
||||
gear: number;
|
||||
current: number;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
import { Profile } from './profile.model';
|
||||
|
||||
export interface Canopy {
|
||||
canopy: string;
|
||||
voile: string;
|
||||
taille: number;
|
||||
author: Profile;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface CanopyModelBySize {
|
||||
_id: {
|
||||
voile: string,
|
||||
taille: number
|
||||
},
|
||||
count: number
|
||||
}
|
||||
|
||||
export interface CanopyModelByYear {
|
||||
_id: {
|
||||
voile: string,
|
||||
taille: number,
|
||||
year: number
|
||||
},
|
||||
count: number
|
||||
}
|
||||
|
||||
export interface CanopyBySize {
|
||||
_id: {
|
||||
canopy: string,
|
||||
taille: number
|
||||
},
|
||||
count: number
|
||||
@@ -18,7 +34,7 @@ export interface CanopyBySize {
|
||||
|
||||
export interface CanopyByYear {
|
||||
_id: {
|
||||
canopy: string,
|
||||
taille: number,
|
||||
year: number
|
||||
},
|
||||
count: number
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
import { Configuration } from 'ng-chartist';
|
||||
|
||||
export const chartPieDonute: Configuration = {
|
||||
type: 'Pie',
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {
|
||||
donut: true,
|
||||
height: 260,
|
||||
donutWidth: 46,
|
||||
startAngle: 270,
|
||||
showLabel: true
|
||||
}
|
||||
};
|
||||
|
||||
export const chartBar: Configuration = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {},
|
||||
responsiveOptions: []
|
||||
};
|
||||
/*
|
||||
export const chartBar: Configuration = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": [],
|
||||
"series": []
|
||||
},
|
||||
options: {
|
||||
seriesBarDistance: 5,
|
||||
high: 170,
|
||||
axisX: {
|
||||
showGrid: false,
|
||||
offset: 20
|
||||
},
|
||||
axisY: {
|
||||
showGrid: true,
|
||||
offset: 40
|
||||
},
|
||||
height: 207
|
||||
},
|
||||
responsiveOptions: [
|
||||
['screen and (min-width: 1024px)', {
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: number, index: number): string {
|
||||
return index % 1 === 0 ? `${value}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (min-width: 641px) and (max-width: 1024px)', {
|
||||
seriesBarDistance: 10,
|
||||
axisY: {
|
||||
offset: 30
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
|
||||
}
|
||||
}
|
||||
}],
|
||||
['screen and (max-width: 640px)', {
|
||||
seriesBarDistance: 5,
|
||||
axisY: {
|
||||
offset: 20
|
||||
},
|
||||
axisX: {
|
||||
labelInterpolationFnc: function(value: any, index: number): string {
|
||||
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
};
|
||||
*/
|
||||
@@ -19,6 +19,7 @@ export interface DropZoneByOaci {
|
||||
export interface DropZoneByYear {
|
||||
_id: {
|
||||
lieu: string,
|
||||
oaci: string,
|
||||
year: number
|
||||
},
|
||||
count: number
|
||||
|
||||
@@ -5,6 +5,7 @@ export * from './application-list-config.model';
|
||||
export * from './calculator.model';
|
||||
export * from './canopy.model';
|
||||
export * from './canopysize.model';
|
||||
export * from './chart.model';
|
||||
export * from './reducerow.model';
|
||||
export * from './dropzone.model';
|
||||
export * from './errors.model';
|
||||
|
||||
@@ -25,6 +25,14 @@ export interface Jump {
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface JumpByDate {
|
||||
_id: {
|
||||
month: number,
|
||||
year: number
|
||||
},
|
||||
count: number
|
||||
}
|
||||
|
||||
export interface JumpDoc {
|
||||
_id?: string;
|
||||
_rev?: string;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { Aeronef, AeronefByImat, AeronefList, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
|
||||
import { Aeronef, AeronefByImat, AeronefByYear } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AeronefsService {
|
||||
@@ -27,4 +26,9 @@ export class AeronefsService {
|
||||
*/
|
||||
}
|
||||
|
||||
getAllByDate(): Observable<Array<AeronefByYear>> {
|
||||
return this.apiService.get('/aeronefs/allByDate')
|
||||
.pipe(map(data => data.aeronefs));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { Canopy, CanopyBySize ,JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
|
||||
import { Canopy, CanopyBySize, CanopyByYear, CanopyModelBySize, CanopyModelByYear } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CanopiesService {
|
||||
@@ -13,7 +12,22 @@ export class CanopiesService {
|
||||
) { }
|
||||
|
||||
getAllBySize(): Observable<Array<CanopyBySize>> {
|
||||
return this.apiService.get('/canopies')
|
||||
return this.apiService.get('/canopies/allBySize')
|
||||
.pipe(map(data => data.canopies));
|
||||
}
|
||||
|
||||
getAllByYear(): Observable<Array<CanopyByYear>> {
|
||||
return this.apiService.get('/canopies/allByYear')
|
||||
.pipe(map(data => data.canopies));
|
||||
}
|
||||
|
||||
getAllModelBySize(): Observable<Array<CanopyModelBySize>> {
|
||||
return this.apiService.get('/canopies/allModelBySize')
|
||||
.pipe(map(data => data.canopies));
|
||||
}
|
||||
|
||||
getAllModelByYear(): Observable<Array<CanopyModelByYear>> {
|
||||
return this.apiService.get('/canopies/allModelByYear')
|
||||
.pipe(map(data => data.canopies));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { DropZone, DropZoneByOaci, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
|
||||
import { DropZone, DropZoneByOaci, DropZoneByYear, JumpListConfig, JumpListFilters } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class DropZonesService {
|
||||
@@ -17,4 +17,9 @@ export class DropZonesService {
|
||||
.pipe(map(data => data.dropzones));
|
||||
}
|
||||
|
||||
getAllByDate(): Observable<Array<DropZoneByYear>> {
|
||||
return this.apiService.get('/dropzones/allByDate')
|
||||
.pipe(map(data => data.dropzones));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { Jump, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
|
||||
import { Jump, JumpByDate, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class JumpsService {
|
||||
@@ -50,6 +50,11 @@ export class JumpsService {
|
||||
.pipe(map(data => data.jumps));
|
||||
}
|
||||
|
||||
getAllByDate(): Observable<Array<JumpByDate>> {
|
||||
return this.apiService.get('/jumps/allByDate')
|
||||
.pipe(map(data => data.jumps));
|
||||
}
|
||||
|
||||
create(jump: Jump): Observable<Jump> {
|
||||
return this.apiService.post('/jumps/', { jump: jump })
|
||||
.pipe(map(data => data.jump));
|
||||
|
||||
+2
-2
@@ -8,12 +8,12 @@
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<!-- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata&family=Poppins:wght@300;400;500;600;700&family=Merriweather:wght@400;700&display=swap"> -->
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata&family=Barlow:wght@300;400;500;600;700&family=Merriweather:wght@400;700&display=swap">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@200;300;500&family=Barlow:wght@300;400;500;600;700&family=Merriweather:wght@400;700&display=swap">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link rel="manifest" href="manifest.webmanifest" />
|
||||
<meta name="theme-color" content="#a7d4c4" />
|
||||
</head>
|
||||
<body class="mat-typography">
|
||||
<body class="mat-app-background mat-typography">
|
||||
<huapp-root></huapp-root>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+99
-7
@@ -84,16 +84,13 @@ a.link {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.img-rounded {
|
||||
border-radius: $radius;
|
||||
}
|
||||
.rounded {
|
||||
border-radius: $radius;
|
||||
}
|
||||
.shadow-none {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.font-monospace.fw-lighter,
|
||||
.font-monospace .fw-lighter {
|
||||
font-weight: 200 !important;
|
||||
}
|
||||
huapp-full-layout .mat-mdc-form-field,
|
||||
huapp-full-layout .mdc-text-field--filled .mdc-floating-label {
|
||||
font-size: initial;
|
||||
@@ -109,6 +106,98 @@ huapp-full-layout .mdc-text-field--filled .mdc-floating-label {
|
||||
}
|
||||
}
|
||||
|
||||
/****************
|
||||
* Text Colors *
|
||||
****************/
|
||||
.text-primary {
|
||||
color: $primary !important;
|
||||
}
|
||||
.text-secondary,
|
||||
.text-warn {
|
||||
color: $secondary !important;
|
||||
}
|
||||
.text-accent {
|
||||
color: $accent !important;
|
||||
}
|
||||
.text-success {
|
||||
color: $success !important;
|
||||
}
|
||||
.text-info {
|
||||
color: $info !important;
|
||||
}
|
||||
.text-warning {
|
||||
color: $warning !important;
|
||||
}
|
||||
.text-danger {
|
||||
color: $danger !important;
|
||||
}
|
||||
.text-error {
|
||||
color: $error !important;
|
||||
}
|
||||
.text-white {
|
||||
color: $white !important;
|
||||
}
|
||||
.text-red {
|
||||
color: $red !important;
|
||||
}
|
||||
.text-red-dark {
|
||||
color: $red-dark !important;
|
||||
}
|
||||
.text-orange {
|
||||
color: $orange !important;
|
||||
}
|
||||
.text-yellow {
|
||||
color: $yellow !important;
|
||||
}
|
||||
.text-megna {
|
||||
color: $megna !important;
|
||||
}
|
||||
.text-green {
|
||||
color: $green !important;
|
||||
}
|
||||
.text-teal {
|
||||
color: $teal !important;
|
||||
}
|
||||
.text-turquoise {
|
||||
color: $turquoise !important;
|
||||
}
|
||||
.text-cyan {
|
||||
color: $cyan !important;
|
||||
}
|
||||
.text-blue {
|
||||
color: $blue !important;
|
||||
}
|
||||
.text-navy {
|
||||
color: $navy !important;
|
||||
}
|
||||
.text-pink {
|
||||
color: $pink !important;
|
||||
}
|
||||
.text-magenta {
|
||||
color: $magenta !important;
|
||||
}
|
||||
.text-purple {
|
||||
color: $purple !important;
|
||||
}
|
||||
.text-purple-dark {
|
||||
color: $purple-dark !important;
|
||||
}
|
||||
.text-raspberry {
|
||||
color: $raspberry !important;
|
||||
}
|
||||
.text-grey {
|
||||
color: $grey !important;
|
||||
}
|
||||
.text-muted {
|
||||
color: $muted !important;
|
||||
}
|
||||
.text-extra-muted {
|
||||
color: $extra-muted !important;
|
||||
}
|
||||
.text-empty {
|
||||
color: $empty !important;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* Background Colors *
|
||||
**********************/
|
||||
@@ -197,6 +286,9 @@ huapp-full-layout .mdc-text-field--filled .mdc-floating-label {
|
||||
.bg-extra-muted {
|
||||
background-color: $extra-muted !important;
|
||||
}
|
||||
.bg-empty {
|
||||
background-color: $empty !important;
|
||||
}
|
||||
.bg-crystal,
|
||||
.bg-crystal .mdc-text-field--filled:not(.mdc-text-field--disabled) {
|
||||
background-color: transparent !important;
|
||||
|
||||
@@ -160,7 +160,7 @@ $chart-color-r: #ffffff;
|
||||
stroke:$chart-color-q;
|
||||
}
|
||||
.ct-series-r .ct-bar {
|
||||
stroke:$chart-color-r
|
||||
stroke:$chart-color-r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ File: scss
|
||||
@import "bootstrap/scss/helpers";
|
||||
@import "bootstrap/scss/utilities/api";
|
||||
//@import "bootstrap/scss/tables";
|
||||
@import "bootstrap/scss/type";
|
||||
@import "bootstrap/scss/pagination";
|
||||
@import "bootstrap/scss/alert";
|
||||
|
||||
@@ -119,6 +120,8 @@ $background: map.get($headup_app-theme, background);
|
||||
@include mat.all-component-themes($headup_app-theme);
|
||||
@include components.theme($headup_app-theme, $custom-typography, $headup_app-variants);
|
||||
|
||||
@import "chartist/dist/index";
|
||||
|
||||
@import 'spinner';
|
||||
@import 'header';
|
||||
@import 'sidebar';
|
||||
|
||||
@@ -9,6 +9,8 @@ File: scss
|
||||
|
||||
$bodyfont: 'Barlow', "Helvetica Neue", sans-serif;
|
||||
$headingfont: 'Barlow', "Helvetica Neue", sans-serif;
|
||||
$font-family-monospace: 'Inconsolata', SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
|
||||
$font-size-base: 0.875rem;
|
||||
|
||||
/* Custom Theme Palettes */
|
||||
$md-custom-primary: (
|
||||
@@ -130,6 +132,8 @@ $success: #16d57c;
|
||||
$warning: #ffb035;
|
||||
$info: #0dcaf0;
|
||||
$inverse: #292154;
|
||||
|
||||
$empty: #717171;
|
||||
$muted: #aaaaaa;
|
||||
$extra-muted: #c4c4c4;
|
||||
$dark: #263238;
|
||||
|
||||
Reference in New Issue
Block a user