Mise à jour de composant partagés
This commit is contained in:
+46
@@ -0,0 +1,46 @@
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{ title }}</mat-card-title>
|
||||
<mat-card-subtitle>{{ subtitle }}</mat-card-subtitle>
|
||||
<span class="flex-spacer"></span>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menuAeronefBar" aria-label="Menu Aeronef Bar">
|
||||
<mat-icon fontIcon="more_vert"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuAeronefBar="matMenu">
|
||||
<button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()">
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</mat-card-header>
|
||||
<hr>
|
||||
<mat-card-content>
|
||||
<div *ngIf="displayCharts" class="barchart position-relative w-100 my-1">
|
||||
<canvas baseChart
|
||||
[data]="chartConfig.barChartData"
|
||||
[options]="chartConfig.barChartOptions"
|
||||
[plugins]="chartConfig.barChartPlugins"
|
||||
[legend]="chartConfig.barChartLegend"
|
||||
[type]="'bar'">
|
||||
</canvas>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr class="mb-0">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Historique annuel</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<huapp-history-table [headers]="seriesHeader" [names]="seriesName" [values]="seriesValue" [rows]="seriesRow" [colors]="seriesColor"></huapp-history-table>
|
||||
<!--
|
||||
<div fxLayout="row wrap">
|
||||
<div *ngFor='let name of seriesName; let i=index' fxFlex.gt-lg="33" fxFlex.gt-md="50" fxFlex.gt-xs="20" fxFlex="100">
|
||||
<h6 class="{{seriesColor[i]}} m-0">
|
||||
<i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i>{{name}} - {{seriesValue[i]}}
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</mat-card>
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AeronefsBarComponent } from './aeronefs-bar.component';
|
||||
|
||||
describe('AeronefsBarComponent', () => {
|
||||
let component: AeronefsBarComponent;
|
||||
let fixture: ComponentFixture<AeronefsBarComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AeronefsBarComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AeronefsBarComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { ChartDataset } from 'chart.js';
|
||||
import { NgChartsModule } from 'ng2-charts';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { MenuItems, HistoryTableComponent } from 'src/app/components/shared';
|
||||
import { UtilitiesService, AeronefsService } from 'src/app/core/services';
|
||||
import { AeronefByImat, AeronefByYear, BarConfig } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatButtonModule, MatCardModule, MatExpansionModule, MatIconModule, MatMenuModule,
|
||||
NgChartsModule,
|
||||
HistoryTableComponent
|
||||
],
|
||||
selector: 'huapp-aeronefs-bar',
|
||||
templateUrl: './aeronefs-bar.component.html'
|
||||
})
|
||||
export class AeronefsBarComponent implements OnInit, OnDestroy {
|
||||
private _aeronefByImat: Subscription = new Subscription();
|
||||
private _aeronefByYear: Subscription = new Subscription();
|
||||
private _aeronefsByImat!: Array<AeronefByImat>;
|
||||
private _aeronefsByYear!: Array<AeronefByYear>;
|
||||
public title: string = 'Aéronefs';
|
||||
public subtitle: string = 'Nombre total de sauts par aéronef';
|
||||
public seriesHeader: string[] = [];
|
||||
public seriesName: string[] = [];
|
||||
public seriesValue: any[] = [];
|
||||
public seriesRow: any[] = [];
|
||||
public seriesColor: string[] = this._utilitiesService.getChartColors();
|
||||
public displayCharts = false;
|
||||
public chartConfig: BarConfig = this._utilitiesService.getHorizontalBarChartConfig();
|
||||
|
||||
constructor(
|
||||
private _aeronefsService: AeronefsService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this._loadAeronefByImat();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._aeronefByImat.unsubscribe();
|
||||
this._aeronefByYear.unsubscribe();
|
||||
}
|
||||
|
||||
private _loadAeronefByImat(): void {
|
||||
let values: Array<number> = [];
|
||||
const aeronefs$: Observable<Array<AeronefByImat>> = this._aeronefsService.getAllByImat();
|
||||
this._aeronefByImat = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
|
||||
this._aeronefsByImat = aggregate.map((row: AeronefByImat) => {
|
||||
//this.chartConfig.barChartData.labels!.push(`${row._id.aeronef} ${row._id.imat}`);
|
||||
this.seriesName.push(`${row._id.aeronef} ${row._id.imat}`);
|
||||
this.seriesValue.push(row.count);
|
||||
return row;
|
||||
});
|
||||
let data: ChartDataset<'bar'> = {
|
||||
data: [...this.seriesValue],
|
||||
label: 'Nombre total de sauts',
|
||||
backgroundColor: this._utilitiesService.getSeriesColors(0.9),
|
||||
borderColor: 'rgba(255, 255, 255, 1)', //this._utilitiesService.getSeriesColors(1),
|
||||
borderWidth: 0
|
||||
};
|
||||
this.chartConfig.barChartData.labels = [...this.seriesName];
|
||||
this.chartConfig.barChartData.datasets!.push(data);
|
||||
this.displayCharts = true;
|
||||
this._loadAeronefByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadAeronefByYear(): void {
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
let values: Array<number> = this.seriesHeader.map(() => 0);
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<AeronefByYear>> = this._aeronefsService.getAllByDate();
|
||||
this._aeronefByYear = dropzones$.subscribe((aggregate: Array<AeronefByYear>) => {
|
||||
this._aeronefsByYear = aggregate.map((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;
|
||||
return row;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{ title }}</mat-card-title>
|
||||
<mat-card-subtitle>{{ subtitle }}</mat-card-subtitle>
|
||||
<span class="flex-spacer"></span>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menuAeronef" aria-label="Menu Aeronef">
|
||||
<mat-icon fontIcon="more_vert"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuAeronef="matMenu">
|
||||
<button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()">
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</mat-card-header>
|
||||
<hr>
|
||||
<mat-card-content>
|
||||
<div *ngIf="displayCharts" class="piechart position-relative w-100 my-1">
|
||||
<canvas baseChart class="mx-auto"
|
||||
[labels]="chartConfig.doughnutChartLabels"
|
||||
[datasets]="chartConfig.doughnutChartDatasets"
|
||||
[options]="chartConfig.doughnutChartOptions"
|
||||
[legend]="chartConfig.doughnutChartLegend"
|
||||
[type]="'doughnut'">
|
||||
</canvas>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr class="mb-0">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Historique annuel</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<huapp-history-table [headers]="seriesHeader" [names]="seriesName" [values]="seriesValue" [rows]="seriesRow" [colors]="seriesColor"></huapp-history-table>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
<!--<hr>
|
||||
<mat-card-content>
|
||||
<div fxLayout="row wrap">
|
||||
<div *ngFor='let name of seriesName; let i=index' fxFlex.gt-lg="33" fxFlex.gt-md="50" fxFlex.gt-xs="20" fxFlex="100">
|
||||
<h6 class="{{seriesColor[i]}} m-0">
|
||||
<i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i>{{name}} - {{seriesValue[i]}}
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>-->
|
||||
</mat-card>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AeronefsComponent } from './aeronefs.component';
|
||||
|
||||
describe('AeronefsComponent', () => {
|
||||
let component: AeronefsComponent;
|
||||
let fixture: ComponentFixture<AeronefsComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AeronefsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AeronefsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Router, RouterLink, RouterModule } from '@angular/router';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { NgChartsModule } from 'ng2-charts';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { MenuItems, HistoryTableComponent } from 'src/app/components/shared';
|
||||
import { UtilitiesService, AeronefsService } from 'src/app/core/services';
|
||||
import { AeronefByImat, AeronefByYear, DoughnutConfig } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule, RouterModule,
|
||||
MatBadgeModule, MatButtonModule, MatCardModule, MatExpansionModule, MatIconModule, MatMenuModule,
|
||||
NgChartsModule,
|
||||
HistoryTableComponent
|
||||
],
|
||||
selector: 'huapp-aeronefs',
|
||||
templateUrl: './aeronefs.component.html'
|
||||
})
|
||||
export class AeronefsComponent implements OnInit, OnDestroy {
|
||||
private _aeronefByImat: Subscription = new Subscription();
|
||||
private _aeronefByYear: Subscription = new Subscription();
|
||||
private _aeronefsByImat!: Array<AeronefByImat>;
|
||||
private _aeronefsByYear!: Array<AeronefByYear>;
|
||||
public title: string = 'Aéronefs';
|
||||
public subtitle: string = 'Nombre total de sauts par aéronef';
|
||||
public seriesHeader: string[] = [];
|
||||
public seriesName: string[] = [];
|
||||
public seriesValue: number[] = [];
|
||||
public seriesRow: any[] = [];
|
||||
public seriesColor: string[] = this._utilitiesService.getChartColors();
|
||||
public displayCharts = false;
|
||||
public chartConfig: DoughnutConfig = this._utilitiesService.getDoughnutChartConfig();
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private _aeronefsService: AeronefsService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
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._aeronefsByImat = aggregate.map((row: AeronefByImat) => {
|
||||
this.chartConfig.doughnutChartLabels.push(`${row._id.aeronef} ${row._id.imat}`);
|
||||
this.chartConfig.doughnutChartDatasets[0].data.push(row.count);
|
||||
return row;
|
||||
});
|
||||
this.seriesName = [...this.chartConfig.doughnutChartLabels];
|
||||
this.seriesValue = [...this.chartConfig.doughnutChartDatasets[0].data];
|
||||
this.displayCharts = true;
|
||||
this._loadAeronefByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadAeronefByYear(): void {
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
let values: Array<number> = this.seriesHeader.map(() => 0);
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<AeronefByYear>> = this._aeronefsService.getAllByDate();
|
||||
this._aeronefByYear = dropzones$.subscribe((aggregate: Array<AeronefByYear>) => {
|
||||
this._aeronefsByYear = aggregate.map((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;
|
||||
return row;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{ title }}</mat-card-title>
|
||||
<mat-card-subtitle>{{ subtitle }}</mat-card-subtitle>
|
||||
<span class="flex-spacer"></span>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menuCanopyModel" aria-label="Menu Canopy Model">
|
||||
<mat-icon fontIcon="more_vert"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuCanopyModel="matMenu">
|
||||
<button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()">
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</mat-card-header>
|
||||
<hr>
|
||||
<mat-card-content>
|
||||
<div *ngIf="displayCharts" class="piechart position-relative w-100 my-1">
|
||||
<canvas baseChart class="mx-auto"
|
||||
[labels]="chartConfig.doughnutChartLabels"
|
||||
[datasets]="chartConfig.doughnutChartDatasets"
|
||||
[options]="chartConfig.doughnutChartOptions"
|
||||
[legend]="chartConfig.doughnutChartLegend"
|
||||
[type]="'doughnut'">
|
||||
</canvas>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr class="mb-0">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Historique annuel</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<huapp-history-table [headers]="seriesHeader" [names]="seriesName" [values]="seriesValue" [rows]="seriesRow" [colors]="seriesColor"></huapp-history-table>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</mat-card>
|
||||
Executable
Executable
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CanopyModelsComponent } from './canopy-models.component';
|
||||
|
||||
describe('CanopyModelsComponent', () => {
|
||||
let component: CanopyModelsComponent;
|
||||
let fixture: ComponentFixture<CanopyModelsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ CanopyModelsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CanopyModelsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
import { Component, OnInit, OnDestroy} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { NgChartsModule } from 'ng2-charts';
|
||||
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { MenuItems, HistoryTableComponent } from 'src/app/components/shared';
|
||||
import { UtilitiesService, CanopiesService } from 'src/app/core/services';
|
||||
import { CanopyModelBySize, CanopyModelByYear, DoughnutConfig } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatButtonModule, MatCardModule, MatExpansionModule, MatIconModule, MatMenuModule,
|
||||
NgChartsModule,
|
||||
HistoryTableComponent
|
||||
],
|
||||
selector: 'huapp-canopy-models',
|
||||
templateUrl: './canopy-models.component.html'
|
||||
})
|
||||
export class CanopyModelsComponent implements OnInit, OnDestroy {
|
||||
private _canopyBySize: Subscription = new Subscription();
|
||||
private _canopyByYear: Subscription = new Subscription();
|
||||
private _canopiesBySize!: Array<CanopyModelBySize>;
|
||||
private _canopiesByYear!: Array<CanopyModelByYear>;
|
||||
public title: string = 'Modèles de voile';
|
||||
public subtitle: string = 'Nombre total de sauts par modèle';
|
||||
public seriesHeader: string[] = [];
|
||||
public seriesName: string[] = [];
|
||||
public seriesValue: number[] = [];
|
||||
public seriesRow: any[] = [];
|
||||
public seriesColor: string[] = this._utilitiesService.getChartColors();
|
||||
public displayCharts = false;
|
||||
public chartConfig: DoughnutConfig = this._utilitiesService.getDoughnutChartConfig();
|
||||
|
||||
constructor(
|
||||
private _canopiesService: CanopiesService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this._loadCanopyModelBySize();
|
||||
}
|
||||
|
||||
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._canopiesBySize = aggregate.map((row: CanopyModelBySize) => {
|
||||
this.chartConfig.doughnutChartLabels.push(`${row._id.taille.toString()} - ${row._id.voile}`);
|
||||
this.chartConfig.doughnutChartDatasets[0].data.push(row.count);
|
||||
return row;
|
||||
});
|
||||
this.seriesName = [...this.chartConfig.doughnutChartLabels];
|
||||
this.seriesValue = [...this.chartConfig.doughnutChartDatasets[0].data];
|
||||
this.displayCharts = true;
|
||||
this._loadCanopyModelByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadCanopyModelByYear(): void {
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
let values: Array<number> = this.seriesHeader.map(() => 0);
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<CanopyModelByYear>> = this._canopiesService.getAllModelByYear();
|
||||
this._canopyByYear = dropzones$.subscribe((aggregate: Array<CanopyModelByYear>) => {
|
||||
this._canopiesByYear = aggregate.map((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;
|
||||
return row;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{ title }}</mat-card-title>
|
||||
<mat-card-subtitle>{{ subtitle }}</mat-card-subtitle>
|
||||
<span class="flex-spacer"></span>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menuCanopySize" aria-label="Menu Canopy Size">
|
||||
<mat-icon fontIcon="more_vert"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuCanopySize="matMenu">
|
||||
<button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()">
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</mat-card-header>
|
||||
<hr>
|
||||
<mat-card-content>
|
||||
<div *ngIf="displayCharts" class="piechart position-relative w-100 my-1">
|
||||
<canvas baseChart class="mx-auto"
|
||||
[labels]="chartConfig.doughnutChartLabels"
|
||||
[datasets]="chartConfig.doughnutChartDatasets"
|
||||
[options]="chartConfig.doughnutChartOptions"
|
||||
[legend]="chartConfig.doughnutChartLegend"
|
||||
[type]="'doughnut'">
|
||||
</canvas>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr class="mb-0">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Historique annuel</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<huapp-history-table [headers]="seriesHeader" [names]="seriesName" [values]="seriesValue" [rows]="seriesRow" [colors]="seriesColor"></huapp-history-table>
|
||||
<!--<div fxLayout="row wrap">
|
||||
<div fxLayout="row wrap">
|
||||
<h4 class="{{seriesColor[i]}} m-0" *ngFor='let name of seriesName; let i=index' fxFlex.gt-lg="25" fxFlex.gt-md="50" fxFlex.gt-sm="50" fxFlex.gt-xs="25" fxFlex="100">
|
||||
<i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i>{{name}} ft² : {{seriesValue[i]}}
|
||||
</h4>
|
||||
</div>
|
||||
</div>-->
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</mat-card>
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CanopySizesComponent } from './canopy-sizes.component';
|
||||
|
||||
describe('CanopySizesComponent', () => {
|
||||
let component: CanopySizesComponent;
|
||||
let fixture: ComponentFixture<CanopySizesComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ CanopySizesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CanopySizesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { NgChartsModule } from 'ng2-charts';
|
||||
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { MenuItems, HistoryTableComponent } from 'src/app/components/shared';
|
||||
import { UtilitiesService, CanopiesService } from 'src/app/core/services';
|
||||
import { CanopyBySize, CanopyByYear, DoughnutConfig } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatButtonModule, MatCardModule, MatExpansionModule, MatIconModule, MatMenuModule,
|
||||
NgChartsModule,
|
||||
HistoryTableComponent
|
||||
],
|
||||
selector: 'huapp-canopy-sizes',
|
||||
templateUrl: './canopy-sizes.component.html'
|
||||
})
|
||||
export class CanopySizesComponent implements OnInit, OnDestroy {
|
||||
private _canopyBySize: Subscription = new Subscription();
|
||||
private _canopyByYear: Subscription = new Subscription();
|
||||
private _canopiesBySize!: Array<CanopyBySize>;
|
||||
private _canopiesByYear!: Array<CanopyByYear>;
|
||||
public title: string = 'Tailles de voile';
|
||||
public subtitle: string = 'Nombre total de sauts par taille';
|
||||
public seriesHeader: string[] = [];
|
||||
public seriesName: string[] = [];
|
||||
public seriesValue: number[] = [];
|
||||
public seriesRow: any[] = [];
|
||||
public seriesColor: string[] = this._utilitiesService.getChartColors();
|
||||
public displayCharts = false;
|
||||
public chartConfig: DoughnutConfig = this._utilitiesService.getDoughnutChartConfig();
|
||||
|
||||
constructor(
|
||||
private _canopiesService: CanopiesService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
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._canopiesBySize = aggregate.map((row: CanopyBySize) => {
|
||||
this.chartConfig.doughnutChartLabels.push(row._id.taille.toString());
|
||||
this.chartConfig.doughnutChartDatasets[0].data.push(row.count);
|
||||
return row;
|
||||
});
|
||||
this.seriesName = [...this.chartConfig.doughnutChartLabels];
|
||||
this.seriesValue = [...this.chartConfig.doughnutChartDatasets[0].data];
|
||||
this.displayCharts = true;
|
||||
this._loadCanopyByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadCanopyByYear(): void {
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
let values: Array<number> = this.seriesHeader.map(() => 0);
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<CanopyByYear>> = this._canopiesService.getAllByYear();
|
||||
this._canopyByYear = dropzones$.subscribe((aggregate: Array<CanopyByYear>) => {
|
||||
this._canopiesByYear = aggregate.map((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;
|
||||
return row;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"Bar": {
|
||||
"labels": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"],
|
||||
"series": [
|
||||
[0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 7, 1, 17, 22, 12, 18, 0, 0],
|
||||
[0, 35, 8, 0, 0, 10, 31, 67, 26, 24, 0, 0],
|
||||
[0, 0, 0, 0, 0, 9, 8, 0, 11, 24, 17, 4],
|
||||
[0, 0, 0, 29, 37, 11, 22, 20, 17, 13, 13, 0],
|
||||
[0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
]
|
||||
},
|
||||
"Pie": {
|
||||
"labels": ["261", "45", "178", "16", "13", "11", "4", "2"],
|
||||
"series": [261, 45, 178, 16, 13, 11, 4, 2],
|
||||
"names": ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"]
|
||||
}
|
||||
}
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{ title }}</mat-card-title>
|
||||
<mat-card-subtitle>{{ subtitle }}</mat-card-subtitle>
|
||||
<span class="flex-spacer"></span>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menuDropzoneBar" aria-label="Menu Dropzone Bar">
|
||||
<mat-icon fontIcon="more_vert"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuDropzoneBar="matMenu">
|
||||
<button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()">
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</mat-card-header>
|
||||
<hr>
|
||||
<mat-card-content>
|
||||
<div *ngIf="displayCharts" class="barchart position-relative w-100 my-1">
|
||||
<x-chartist [configuration]="barChartDropZones"></x-chartist>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr class="mb-0">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Historique annuel</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<huapp-history-table [headers]="seriesHeader" [names]="seriesName" [values]="seriesValue" [rows]="seriesRow" [colors]="seriesColor"></huapp-history-table>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</mat-card>
|
||||
Executable
Executable
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DropZonesBarComponent } from './drop-zones-bar.component';
|
||||
|
||||
describe('DropZonesBarComponent', () => {
|
||||
let component: DropZonesBarComponent;
|
||||
let fixture: ComponentFixture<DropZonesBarComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ DropZonesBarComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DropZonesBarComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
Executable
+140
@@ -0,0 +1,140 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { NgChartsModule, baseColors } from 'ng2-charts';
|
||||
import { ChartistModule, Configuration } from 'ng-chartist';
|
||||
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { MenuItems, HistoryTableComponent } from 'src/app/components/shared';
|
||||
import { UtilitiesService, DropZonesService } from 'src/app/core/services';
|
||||
import { DropZoneByOaci, DropZoneByYear } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatButtonModule, MatCardModule, MatExpansionModule, MatIconModule, MatMenuModule,
|
||||
NgChartsModule, ChartistModule,
|
||||
HistoryTableComponent
|
||||
],
|
||||
selector: 'huapp-drop-zones-bar',
|
||||
templateUrl: './drop-zones-bar.component.html'
|
||||
})
|
||||
export class DropZonesBarComponent implements OnInit, OnDestroy {
|
||||
private _dropzoneByOaci: Subscription = new Subscription();
|
||||
private _dropzoneByYear: Subscription = new Subscription();
|
||||
private _dropzonesByOaci!: Array<DropZoneByOaci>;
|
||||
private _dropzonesByYear!: Array<DropZoneByYear>;
|
||||
public title: string = 'Les dropzones';
|
||||
public subtitle: string = 'Nombre total de sauts par dropzone';
|
||||
public seriesHeader: string[] = [];
|
||||
public seriesName: string[] = [];
|
||||
public seriesValue: number[] = [];
|
||||
public seriesRow: any[] = [];
|
||||
public seriesColor: string[] = this._utilitiesService.getChartColors();
|
||||
public displayCharts = false;
|
||||
public barChartDropZones: Configuration = this._utilitiesService.getBarConfig();
|
||||
|
||||
constructor(
|
||||
private _dropzonesService: DropZonesService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems
|
||||
) { }
|
||||
|
||||
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._dropzonesByOaci = aggregate.map((row: DropZoneByOaci) => {
|
||||
this.seriesName.push(`${row._id.oaci} - ${row._id.lieu}`);
|
||||
this.seriesValue.push(row.count);
|
||||
return row;
|
||||
});
|
||||
this._loadDropZoneByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadDropZoneByYear(): void {
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
let values: Array<number> = this.seriesHeader.map(() => 0);
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<DropZoneByYear>> = this._dropzonesService.getAllByDate();
|
||||
this._dropzoneByYear = dropzones$.subscribe((aggregate: Array<DropZoneByYear>) => {
|
||||
this._dropzonesByYear = aggregate.map((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;
|
||||
return row;
|
||||
});
|
||||
this.barChartDropZones = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": this.seriesHeader,
|
||||
"series": this.seriesRow
|
||||
},
|
||||
options: {
|
||||
seriesBarDistance: 15,
|
||||
horizontalBars: false,
|
||||
high: 180,
|
||||
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: 7,
|
||||
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]}` : '';
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
};
|
||||
this.displayCharts = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"Bar": {
|
||||
"labels": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"],
|
||||
"series": [
|
||||
[0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 7, 1, 17, 22, 12, 18, 0, 0],
|
||||
[0, 35, 8, 0, 0, 10, 31, 67, 26, 24, 0, 0],
|
||||
[0, 0, 0, 0, 0, 9, 8, 0, 11, 24, 17, 4],
|
||||
[0, 0, 0, 29, 37, 11, 22, 20, 17, 13, 13, 0],
|
||||
[0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
]
|
||||
},
|
||||
"Pie": {
|
||||
"labels": ["261", "45", "178", "16", "13", "11", "4", "2"],
|
||||
"series": [261, 45, 178, 16, 13, 11, 4, 2],
|
||||
"names": ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"]
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{ title }}</mat-card-title>
|
||||
<mat-card-subtitle>{{ subtitle }}</mat-card-subtitle>
|
||||
<span class="flex-spacer"></span>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menuDropzone" aria-label="Menu Dropzone">
|
||||
<mat-icon fontIcon="more_vert"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuDropzone="matMenu">
|
||||
<button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()">
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</mat-card-header>
|
||||
<hr>
|
||||
<mat-card-content>
|
||||
<div *ngIf="displayCharts" class="piechart position-relative w-100 my-1">
|
||||
<canvas baseChart class="mx-auto"
|
||||
[labels]="chartConfig.doughnutChartLabels"
|
||||
[datasets]="chartConfig.doughnutChartDatasets"
|
||||
[options]="chartConfig.doughnutChartOptions"
|
||||
[legend]="chartConfig.doughnutChartLegend"
|
||||
[type]="'doughnut'">
|
||||
</canvas>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr class="mb-0">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Historique annuel</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<huapp-history-table [headers]="seriesHeader" [names]="seriesName" [values]="seriesValue" [rows]="seriesRow" [colors]="seriesColor"></huapp-history-table>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</mat-card>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DropZonesComponent } from './drop-zones.component';
|
||||
|
||||
describe('DropZonesComponent', () => {
|
||||
let component: DropZonesComponent;
|
||||
let fixture: ComponentFixture<DropZonesComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ DropZonesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DropZonesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { ChartConfiguration } from 'chart.js';
|
||||
import { NgChartsModule } from 'ng2-charts';
|
||||
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { MenuItems, HistoryTableComponent } from 'src/app/components/shared';
|
||||
import { UtilitiesService, DropZonesService } from 'src/app/core/services';
|
||||
import { DropZoneByOaci, DropZoneByYear, DoughnutConfig } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatButtonModule, MatCardModule, MatExpansionModule, MatIconModule, MatMenuModule,
|
||||
NgChartsModule,
|
||||
HistoryTableComponent
|
||||
],
|
||||
selector: 'huapp-drop-zones',
|
||||
templateUrl: './drop-zones.component.html'
|
||||
})
|
||||
export class DropZonesComponent implements OnInit, OnDestroy {
|
||||
private _dropzoneByOaci: Subscription = new Subscription();
|
||||
private _dropzoneByYear: Subscription = new Subscription();
|
||||
private _dropzonesByOaci!: Array<DropZoneByOaci>;
|
||||
private _dropzonesByYear!: Array<DropZoneByYear>;
|
||||
public title: string = 'Les dropzones';
|
||||
public subtitle: string = 'Nombre total de sauts par dropzone';
|
||||
public seriesHeader: string[] = [];
|
||||
public seriesName: string[] = [];
|
||||
public seriesValue: number[] = [];
|
||||
public seriesRow: any[] = [];
|
||||
public seriesColor: string[] = this._utilitiesService.getChartColors();
|
||||
public displayCharts = false;
|
||||
public chartConfig: DoughnutConfig = this._utilitiesService.getDoughnutChartConfig();
|
||||
|
||||
constructor(
|
||||
private _dropzonesService: DropZonesService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems
|
||||
) { }
|
||||
|
||||
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._dropzonesByOaci = aggregate.map((row: DropZoneByOaci) => {
|
||||
this.chartConfig.doughnutChartLabels.push(`${row._id.oaci} - ${row._id.lieu}`);
|
||||
this.chartConfig.doughnutChartDatasets[0].data.push(row.count);
|
||||
return row;
|
||||
});
|
||||
this.seriesName = [...this.chartConfig.doughnutChartLabels];
|
||||
this.seriesValue = [...this.chartConfig.doughnutChartDatasets[0].data];
|
||||
this.displayCharts = true;
|
||||
this._loadDropZoneByYear();
|
||||
});
|
||||
}
|
||||
|
||||
private _loadDropZoneByYear(): void {
|
||||
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
|
||||
let values: Array<number> = this.seriesHeader.map(() => 0);
|
||||
this.seriesName.forEach(() => {
|
||||
this.seriesRow.push([...values]);
|
||||
});
|
||||
const dropzones$: Observable<Array<DropZoneByYear>> = this._dropzonesService.getAllByDate();
|
||||
this._dropzoneByYear = dropzones$.subscribe((aggregate: Array<DropZoneByYear>) => {
|
||||
this._dropzonesByYear = aggregate.map((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;
|
||||
return row;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export * from './aeronefs/aeronefs.component';
|
||||
export * from './aeronefs-bar/aeronefs-bar.component';
|
||||
export * from './canopy-models/canopy-models.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';
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"Bar": {
|
||||
"labels": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"],
|
||||
"series": [
|
||||
[0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 7, 1, 17, 22, 12, 18, 0, 0],
|
||||
[0, 35, 8, 0, 0, 10, 31, 67, 26, 24, 0, 0],
|
||||
[0, 0, 0, 0, 0, 9, 8, 0, 11, 24, 17, 4],
|
||||
[0, 0, 0, 29, 37, 11, 22, 20, 17, 13, 13, 0],
|
||||
[0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
]
|
||||
},
|
||||
"Pie": {
|
||||
"labels": ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"],
|
||||
"series": [261, 45, 178, 16, 13, 11, 4, 2]
|
||||
}
|
||||
}
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{ title }}</mat-card-title>
|
||||
<mat-card-subtitle>{{ subtitle }} de {{min}} à {{max}}</mat-card-subtitle>
|
||||
<span class="flex-spacer"></span>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menuJumpBar" aria-label="Menu Dropzone Bar">
|
||||
<mat-icon fontIcon="more_vert"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuJumpBar="matMenu">
|
||||
<button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()">
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</mat-card-header>
|
||||
<hr>
|
||||
<mat-card-content>
|
||||
<!--
|
||||
<div class="text-center mb-3">
|
||||
<ul class="list-inline my-0">
|
||||
<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>
|
||||
-->
|
||||
<div *ngIf="displayCharts" class="barchart position-relative w-100 my-1">
|
||||
<x-chartist [configuration]="barChartJumps"></x-chartist>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<hr class="mb-0">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Historique annuel</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<table class="table table-striped table-dark table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></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-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="font-monospace text-end">{{ seriesRowTotal[i] }}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<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="font-monospace text-end">{{ grandTotal }}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-end">Moyenne</th>
|
||||
<th *ngFor='let value of seriesRowAvg; 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="font-monospace text-end">{{ grandAvg }}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</mat-card>
|
||||
Executable
Executable
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { JumpsByMonthComponent } from './jumps-by-month.component';
|
||||
|
||||
describe('JumpsByMonthComponent', () => {
|
||||
let component: JumpsByMonthComponent;
|
||||
let fixture: ComponentFixture<JumpsByMonthComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ JumpsByMonthComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(JumpsByMonthComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
Executable
+148
@@ -0,0 +1,148 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { ChartistModule, Configuration } from 'ng-chartist';
|
||||
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { MenuItems } from 'src/app/components/shared';
|
||||
import { UtilitiesService, JumpsService } from 'src/app/core/services';
|
||||
import { JumpByDate } from 'src/app/core/models';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatButtonModule, MatCardModule, MatExpansionModule, MatIconModule, MatMenuModule,
|
||||
ChartistModule
|
||||
],
|
||||
selector: 'huapp-jumps-by-month',
|
||||
templateUrl: './jumps-by-month.component.html'
|
||||
})
|
||||
export class JumpsByMonthComponent implements OnInit, OnDestroy {
|
||||
private _jumpByDate: Subscription = new Subscription();
|
||||
private _jumpsByDate!: Array<JumpByDate>;
|
||||
private _jumpsByDateCount = 0;
|
||||
public title: string = 'Volume mensuel';
|
||||
public subtitle: string = 'Nombre total de sauts par mois';
|
||||
public min = 0;
|
||||
public max = 0;
|
||||
public grandAvg = 0;
|
||||
public grandTotal = 0;
|
||||
public seriesHeader: string[] = [];
|
||||
public seriesName: String[] = [];
|
||||
public seriesRow: any[] = [];
|
||||
public seriesColor: String[] = this._utilitiesService.getChartColors();
|
||||
public seriesRowTotal: number[] = [];
|
||||
public seriesRowAvg: number[] = [];
|
||||
public seriesColTotal: number[] = [];
|
||||
public displayCharts = false;
|
||||
public barChartJumps: Configuration = this._utilitiesService.getBarConfig();
|
||||
|
||||
constructor(
|
||||
private _jumpsService: JumpsService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this._loadJumpByDate();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._jumpByDate.unsubscribe();
|
||||
}
|
||||
|
||||
private _loadJumpByDate() {
|
||||
this.seriesHeader = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"];
|
||||
let values: Array<number> = this.seriesHeader.map(() => 0);
|
||||
this.seriesColTotal = [...values];
|
||||
const jumps$: Observable<Array<JumpByDate>> = this._jumpsService.getAllByDate();
|
||||
this._jumpByDate = jumps$.subscribe((aggregate: Array<JumpByDate>) => {
|
||||
this._jumpsByDateCount = aggregate.length;
|
||||
this._jumpsByDate = aggregate.map((row: JumpByDate) => {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
return row;
|
||||
});
|
||||
this.seriesRow.forEach((row: number[]) => {
|
||||
const total = row.reduce((partialSum, a) => partialSum + a, 0);
|
||||
this.seriesRowTotal.push(total);
|
||||
});
|
||||
this.seriesRowTotal.forEach((row: number) => {
|
||||
let value: number = (row/this.seriesName.length);
|
||||
this.seriesRowAvg.push(value);
|
||||
});
|
||||
this.grandAvg = this.seriesRowAvg.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
|
||||
this.grandTotal = this.seriesColTotal.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
|
||||
this.barChartJumps = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
"labels": this.seriesHeader,
|
||||
"series": this.seriesRow
|
||||
},
|
||||
options: {
|
||||
seriesBarDistance: 15,
|
||||
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]}` : '';
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
};
|
||||
this.displayCharts = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user