Import des sources angular à partir de 'headup_app'
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { AeronefByImat, AeronefByYear } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AeronefsService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAllByImat(): Observable<Array<AeronefByImat>> {
|
||||
return this.apiService.get('/aeronefs/allByImat')
|
||||
.pipe(map(data => data.aeronefs));
|
||||
}
|
||||
|
||||
getAllByImatByYear(): Observable<Array<AeronefByYear>> {
|
||||
return this.apiService.get('/aeronefs/allByImatByYear')
|
||||
.pipe(map(data => data.aeronefs));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
//import { environment } from 'src/environments/environment';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApiService {
|
||||
constructor(
|
||||
private http: HttpClient
|
||||
) { }
|
||||
|
||||
/*private formatErrors(error: any) {
|
||||
return throwError(error.error);
|
||||
}*/
|
||||
|
||||
get(path: string, params: HttpParams = new HttpParams()): Observable<any> {
|
||||
return this.http.get(`${path}`, { params });
|
||||
}
|
||||
|
||||
put(path: string, body: NonNullable<unknown> = {}): Observable<any> {
|
||||
return this.http.put(`${path}`, JSON.stringify(body));
|
||||
}
|
||||
|
||||
post(path: string, body: NonNullable<unknown> = {}): Observable<any> {
|
||||
return this.http.post(`${path}`, JSON.stringify(body));
|
||||
}
|
||||
|
||||
delete(path: string): Observable<any> {
|
||||
return this.http.delete(`${path}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { Application, ApplicationList, ApplicationListConfig, ApplicationListFilters } from 'src/app/core/models';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApplicationsService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
query(config: ApplicationListConfig): Observable<ApplicationList> {
|
||||
// Convert any filters over to Angular's URLSearchParams
|
||||
const params: ApplicationListFilters = {
|
||||
apikey: config.filters.apikey,
|
||||
author: config.filters.author,
|
||||
limit: config.filters.limit,
|
||||
offset: config.filters.offset
|
||||
};
|
||||
return this.apiService
|
||||
.get(
|
||||
'/applications' + ((config.type === 'feed') ? '/feed' : ''),
|
||||
new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params })
|
||||
);
|
||||
}
|
||||
|
||||
get(slug: string): Observable<Application> {
|
||||
return this.apiService.get(`/applications/${slug}`)
|
||||
.pipe(map(data => data.application));
|
||||
}
|
||||
|
||||
destroy(slug: string): Observable<boolean> {
|
||||
return this.apiService.delete(`/applications/${slug}`).pipe(map(data => data.deleted));
|
||||
}
|
||||
|
||||
save(application: Application): Observable<Application> {
|
||||
if (application.slug) {
|
||||
// If we're updating an existing application
|
||||
return this.apiService.put(`/applications/${application.slug}`, { application: application })
|
||||
.pipe(map(data => data.application));
|
||||
} else {
|
||||
// Otherwise, create a new application
|
||||
return this.apiService.post('/applications/', { application: application })
|
||||
.pipe(map(data => data.application));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { CalculatorResult, WeightSizeRange, weightSizes } from 'src/app/core/models';
|
||||
import { UtilitiesService } from 'src/app/core/services';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CalculatorService {
|
||||
public coeffKgLbs: number = this._utilitiesService.getCoeffKgLbs();
|
||||
public coeffFtM: number = this._utilitiesService.getCoeffFtM();
|
||||
|
||||
constructor(
|
||||
private _utilitiesService: UtilitiesService
|
||||
) { }
|
||||
|
||||
private _getTableColumn(jumps: number): number {
|
||||
let column: number = 0;
|
||||
weightSizes[0].ranges.some((range: WeightSizeRange) => {
|
||||
if (jumps >= range.start && jumps <= range.end) {
|
||||
column = (range.num-1)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return column;
|
||||
}
|
||||
|
||||
private _getTableLine(weight: number): number {
|
||||
let line: number;
|
||||
const min = 60;
|
||||
const max = 110;
|
||||
if (weight < min) {
|
||||
line = min;
|
||||
} else if (weight > max) {
|
||||
line = max;
|
||||
} else {
|
||||
line = weight;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
private _isInRange(nb: number, range: WeightSizeRange): boolean {
|
||||
return (nb >= range.start && nb <= range.end);
|
||||
}
|
||||
|
||||
private _reduceLimit(surface: number, percentOff: number): number {
|
||||
return Math.ceil(surface * (100 - percentOff) / 100);
|
||||
}
|
||||
|
||||
public canopySizeCalc(weight: number, jumps: number): CalculatorResult {
|
||||
/* DT48 - 13 mars 2020 */
|
||||
/* const maxRange = 2000; */
|
||||
/* DT48 - 08 février 2024 */
|
||||
const maxRange = 1600;
|
||||
const result: CalculatorResult = {
|
||||
min: 59,
|
||||
min11: 34
|
||||
};
|
||||
if (jumps > maxRange) {
|
||||
return result;
|
||||
}
|
||||
const index: number = (this._getTableLine(weight) - this._getTableLine(0));
|
||||
result.min = weightSizes[index].ranges[this._getTableColumn(jumps)].value!;
|
||||
result.min11 = this._reduceLimit(result.min, 11);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public convertFeet2Meters(size: number): number {
|
||||
return (size * this._utilitiesService.getCoeffFtM());
|
||||
}
|
||||
|
||||
public getCanopySizes(weight: number, reduce = false): number[] {
|
||||
if (weight < 60) {
|
||||
weight = 60;
|
||||
}
|
||||
if (weight > 110) {
|
||||
weight = 110;
|
||||
}
|
||||
const line = (weight - this._getTableLine(0));
|
||||
const data = weightSizes[line];
|
||||
if (reduce) {
|
||||
return data.ranges.map((range: WeightSizeRange): number => {
|
||||
return Math.ceil(range.value! * (100 - 11) / 100);
|
||||
});
|
||||
} else {
|
||||
return data.ranges.map((range: WeightSizeRange): number => {
|
||||
return range.value!;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public getCharge(canopySize: number, nakedWeight: number, equipementWeight: number): number {
|
||||
return (((nakedWeight + equipementWeight) * this.coeffKgLbs) / canopySize);
|
||||
}
|
||||
|
||||
public getRangeNum(jumps: number): number {
|
||||
const data: WeightSizeRange[] = weightSizes[0].ranges;
|
||||
let num: number = 1;
|
||||
/* DT48 - 13 mars 2020 */
|
||||
/* const maxRange = 2000; */
|
||||
/* DT48 - 08 février 2024 */
|
||||
const maxRange = 1600;
|
||||
data.some((range: WeightSizeRange): boolean => {
|
||||
if (jumps >= range.start && jumps <= range.end) {
|
||||
num = range.num;
|
||||
return true;
|
||||
} else if (jumps > maxRange) {
|
||||
num = 9;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return num;
|
||||
}
|
||||
|
||||
public getStateColor(values: CalculatorResult): string {
|
||||
let color: string = 'danger';
|
||||
if (values.current! >= values.min11 && values.current! < values.min) {
|
||||
color = 'warning';
|
||||
}
|
||||
if (values.current! >= values.min) {
|
||||
color = 'success';
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { CanopyBySize, CanopyByYear, CanopyModelBySize, CanopyModelByYear } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CanopiesService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAllBySize(): Observable<Array<CanopyBySize>> {
|
||||
return this.apiService.get('/canopies/allBySize')
|
||||
.pipe(map(data => data.canopies));
|
||||
}
|
||||
|
||||
getAllBySizeByYear(): Observable<Array<CanopyByYear>> {
|
||||
return this.apiService.get('/canopies/allBySizeByYear')
|
||||
.pipe(map(data => data.canopies));
|
||||
}
|
||||
|
||||
getAllBySizeByModel(): Observable<Array<CanopyModelBySize>> {
|
||||
return this.apiService.get('/canopies/allBySizeByModel')
|
||||
.pipe(map(data => data.canopies));
|
||||
}
|
||||
|
||||
getAllBySizeByModelByYear(): Observable<Array<CanopyModelByYear>> {
|
||||
return this.apiService.get('/canopies/allBySizeByModelByYear')
|
||||
.pipe(map(data => data.canopies));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { DropZoneByOaci, DropZoneByYear } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class DropZonesService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAllByOaci(): Observable<Array<DropZoneByOaci>> {
|
||||
return this.apiService.get('/dropzones/allByOaci')
|
||||
.pipe(map(data => data.dropzones));
|
||||
}
|
||||
|
||||
getAllByOaciByYear(): Observable<Array<DropZoneByYear>> {
|
||||
return this.apiService.get('/dropzones/allByOaciByYear')
|
||||
.pipe(map(data => data.dropzones));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export * from './aeronefs.service';
|
||||
export * from './api.service';
|
||||
export * from './applications.service';
|
||||
export * from './calculator.service';
|
||||
export * from './canopies.service';
|
||||
export * from './dropzones.service';
|
||||
export * from './jumps.service';
|
||||
export * from './jump-table.service';
|
||||
export * from './jwt.service';
|
||||
export * from './pages.service';
|
||||
export * from './profiles.service';
|
||||
export * from './qcm.service';
|
||||
export * from './user.service';
|
||||
export * from './utilities.service';
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class JumpTableService {
|
||||
|
||||
tableRefresh: boolean;
|
||||
_tableRefreshBS = new BehaviorSubject<boolean>(false);
|
||||
|
||||
jumpRefresh: boolean;
|
||||
_jumpRefreshBS = new BehaviorSubject<boolean>(false);
|
||||
|
||||
constructor() {
|
||||
this.tableRefresh = false;
|
||||
this.jumpRefresh = false;
|
||||
|
||||
//this._tableRefreshBS.next(this.tableRefresh);
|
||||
//this._jumpRefreshBS.next(this.jumpRefresh);
|
||||
}
|
||||
|
||||
updateTableRefresh(val: boolean) {
|
||||
this.tableRefresh = val;
|
||||
this._tableRefreshBS.next(this.tableRefresh);
|
||||
}
|
||||
|
||||
updateJumpRefresh(val: boolean) {
|
||||
this.jumpRefresh = val;
|
||||
this._jumpRefreshBS.next(this.jumpRefresh);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
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 {
|
||||
Jump, JumpByCategorie, JumpByDate, JumpByDay, JumpByModule, JumpFile,
|
||||
JumpList, JumpListConfig, JumpListFilters, JumpPageData,
|
||||
X2Data, SkydiverIdJumps
|
||||
} from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class JumpsService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
query(config: JumpListConfig): Observable<JumpList> {
|
||||
// Convert any filters over to Angular's URLSearchParams
|
||||
/*
|
||||
const params: JumpListFilters = {
|
||||
date: config.filters.date,
|
||||
lieu: config.filters.lieu,
|
||||
oaci: config.filters.oaci,
|
||||
aeronef: config.filters.aeronef,
|
||||
imat: config.filters.imat,
|
||||
hauteur: config.filters.hauteur,
|
||||
voile: config.filters.voile,
|
||||
taille: config.filters.taille,
|
||||
categorie: config.filters.categorie,
|
||||
module: config.filters.module,
|
||||
participants: config.filters.participants,
|
||||
accessoires: config.filters.accessoires,
|
||||
zone: config.filters.zone,
|
||||
author: config.filters.author,
|
||||
limit: config.filters.limit,
|
||||
offset: config.filters.offset,
|
||||
numeroRangeStart: config.filters.numeroRangeStart!,
|
||||
numeroRangeEnd: config.filters.numeroRangeEnd!,
|
||||
tailleRangeStart: config.filters.tailleRangeStart!,
|
||||
tailleRangeEnd: config.filters.tailleRangeEnd!,
|
||||
participantsRangeStart: config.filters.participantsRangeStart!,
|
||||
participantsRangeEnd: config.filters.participantsRangeEnd!,
|
||||
hauteurRangeStart: config.filters.hauteurRangeStart!,
|
||||
hauteurRangeEnd: config.filters.hauteurRangeEnd!
|
||||
};
|
||||
*/
|
||||
const params: JumpListFilters = {} as JumpListFilters;
|
||||
Object.assign(params, config.filters);
|
||||
return this.apiService
|
||||
.get(
|
||||
'/jumps' + ((config.type === 'feed') ? '/feed' : ''),
|
||||
new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params })
|
||||
);
|
||||
}
|
||||
|
||||
get(slug: string): Observable<JumpPageData> {
|
||||
/* return this.apiService.get(`/jumps/${slug}`)
|
||||
.pipe(map(data => {
|
||||
return { jump: data.jump, prevJump: data.prevJump, nextJump: data.nextJump };
|
||||
})); */
|
||||
return this.apiService.get(`/jumps/${slug}`);
|
||||
}
|
||||
|
||||
getAll(): Observable<Array<Jump>> {
|
||||
return this.apiService.get('/jumps').pipe(map(data => data.jumps));
|
||||
}
|
||||
|
||||
getAllByDate(): Observable<Array<JumpByDate>> {
|
||||
return this.apiService.get('/jumps/allByDate').pipe(map(data => data.jumps));
|
||||
}
|
||||
|
||||
getAllByCategorie(): Observable<Array<JumpByCategorie>> {
|
||||
return this.apiService.get('/jumps/allByCategorie').pipe(map(data => data.jumps));
|
||||
}
|
||||
|
||||
getAllByDay(config: JumpListConfig): Observable<Array<JumpByDay>> {
|
||||
const params: JumpListFilters = {} as JumpListFilters;
|
||||
Object.assign(params, config.filters);
|
||||
return this.apiService.get('/jumps/allByDay', new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params }))
|
||||
.pipe(map(data => data.days));
|
||||
}
|
||||
|
||||
getAllByModule(): Observable<Array<JumpByModule>> {
|
||||
return this.apiService.get('/jumps/allByModule').pipe(map(data => data.jumps));
|
||||
}
|
||||
|
||||
getAllFromSkydiverIdApi(config: JumpListConfig): Observable<SkydiverIdJumps> {
|
||||
const params: JumpListFilters = {} as JumpListFilters;
|
||||
Object.assign(params, config.filters);
|
||||
return this.apiService.get('/jumps/allFromSkydiverIdApi', new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params }))
|
||||
.pipe(map(data => data.jumps));
|
||||
}
|
||||
|
||||
getLastJump(): Observable<Jump> {
|
||||
return this.apiService.get('/jumps/last').pipe(map(data => data.jump));
|
||||
}
|
||||
|
||||
create(jump: Jump): Observable<Jump> {
|
||||
return this.apiService.post('/jumps/', { jump: jump }).pipe(map(data => data.jump));
|
||||
}
|
||||
|
||||
update(jump: Jump): Observable<Jump> {
|
||||
return this.apiService.put(`/jumps/${jump.slug}`, { jump: jump }).pipe(map(data => data.jump));
|
||||
}
|
||||
|
||||
destroy(slug: string): Observable<boolean> {
|
||||
return this.apiService.delete(`/jumps/${slug}`).pipe(map(data => data.deleted));
|
||||
}
|
||||
|
||||
save(jump: Jump): Observable<Jump> {
|
||||
// If we're updating an existing jump
|
||||
if (jump.slug) {
|
||||
return this.apiService.put(`/jumps/${jump.slug}`, { jump: jump }).pipe(map(data => data.jump));
|
||||
|
||||
// Otherwise, create a new jump
|
||||
} else {
|
||||
return this.apiService.post('/jumps/', { jump: jump }).pipe(map(data => data.jump));
|
||||
}
|
||||
}
|
||||
|
||||
saveX2Data(slug: string, file: JumpFile, data: X2Data): Observable<Jump> {
|
||||
return this.apiService.post(`/jumps/data/${slug}`, { file: file, data: data })
|
||||
.pipe(map(data => data.jump));
|
||||
}
|
||||
|
||||
saveFile(slug: string, file: JumpFile): Observable<JumpFile> {
|
||||
return this.apiService.post(`/jumps/file/${slug}`, { file: file })
|
||||
.pipe(map(data => data.file));
|
||||
}
|
||||
|
||||
saveKml(slug: string, file: JumpFile): Observable<JumpFile> {
|
||||
return this.apiService.post(`/jumps/kml/${slug}`, { file: file })
|
||||
.pipe(map(data => data.file));
|
||||
}
|
||||
|
||||
getAeronefs() {
|
||||
/*
|
||||
[
|
||||
{
|
||||
'$match': {
|
||||
'aeronef': 'Pilatus'
|
||||
}
|
||||
}, {
|
||||
'$group': {
|
||||
'_id': {
|
||||
'Aeronef': '$aeronef',
|
||||
'Imat': '$imat'
|
||||
},
|
||||
'count': {
|
||||
'$sum': 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class JwtService {
|
||||
|
||||
getToken(): string {
|
||||
return window.localStorage['jwtToken'];
|
||||
}
|
||||
|
||||
saveToken(token: string) {
|
||||
window.localStorage['jwtToken'] = token;
|
||||
}
|
||||
|
||||
destroyToken() {
|
||||
window.localStorage.removeItem('jwtToken');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { AeronefsPageData, CanopiesPageData, DropZonesPageData, JumpsPageData } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class PagesService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAeronefsPage(): Observable<AeronefsPageData> {
|
||||
return this.apiService.get(`/pages/aeronefs`).pipe(take(1));
|
||||
}
|
||||
|
||||
getCanopiesPage(): Observable<CanopiesPageData> {
|
||||
return this.apiService.get(`/pages/canopies`).pipe(take(1));
|
||||
}
|
||||
|
||||
getDropZonesPage(): Observable<DropZonesPageData> {
|
||||
return this.apiService.get(`/pages/dropzones`).pipe(take(1));
|
||||
}
|
||||
|
||||
getJumpsPage(): Observable<JumpsPageData> {
|
||||
return this.apiService.get(`/pages/jumps`).pipe(take(1));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { ApiService } from 'src/app/core/services';
|
||||
import { Profile } from 'src/app/core/models';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ProfilesService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
get(username: string): Observable<Profile> {
|
||||
return this.apiService.get('/profiles/' + username)
|
||||
.pipe(map((data: { profile: Profile }) => data.profile));
|
||||
}
|
||||
|
||||
follow(username: string): Observable<Profile> {
|
||||
return this.apiService.post('/profiles/' + username + '/follow');
|
||||
}
|
||||
|
||||
unfollow(username: string): Observable<Profile> {
|
||||
return this.apiService.delete('/profiles/' + username + '/follow');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { Qcm, QcmCategory, QcmQuestion } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class QcmService {
|
||||
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
get(type: string): Observable<Qcm> {
|
||||
return this.apiService.get(`/qcm/type/${type}`).pipe(map(data => data.qcm));
|
||||
}
|
||||
|
||||
saveChoices(question: object): Observable<QcmQuestion> {
|
||||
return this.apiService.post('/qcm/choices', { question: question })
|
||||
.pipe(map(data => data.question));
|
||||
}
|
||||
|
||||
saveQuestions(category: object): Observable<QcmCategory> {
|
||||
return this.apiService.post('/qcm/questions', { category: category })
|
||||
.pipe(map(data => data.category));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { Observable, BehaviorSubject, ReplaySubject, Subscription } from 'rxjs';
|
||||
import { distinctUntilChanged, take, tap } from 'rxjs/operators';
|
||||
|
||||
import { User } from 'src/app/core/models';
|
||||
import { JwtService } from 'src/app/core/services';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class UserService implements OnDestroy {
|
||||
private _subcriptions: Array<Subscription> = new Array<Subscription>();
|
||||
private _user: Subscription = new Subscription();
|
||||
private currentUserSubject = new BehaviorSubject<User>({} as User);
|
||||
public currentUser = this.currentUserSubject.asObservable().pipe(distinctUntilChanged());
|
||||
|
||||
private isAuthenticatedSubject = new ReplaySubject<boolean>(1);
|
||||
public isAuthenticated = this.isAuthenticatedSubject.asObservable();
|
||||
|
||||
|
||||
constructor(
|
||||
private readonly http: HttpClient,
|
||||
private readonly jwtService: JwtService
|
||||
) { }
|
||||
|
||||
ngOnDestroy() {
|
||||
this._subcriptions.forEach((subscription: Subscription) => subscription.unsubscribe());
|
||||
}
|
||||
|
||||
// Verify JWT in localstorage with server & load user's info.
|
||||
// This runs once on application startup.
|
||||
populate() {
|
||||
// If JWT detected, attempt to get & store user's info
|
||||
if (this.jwtService.getToken()) {
|
||||
const user$: Observable<{ user: User }> = this.http.get<{ user: User }>('/user').pipe(take(1));
|
||||
this._user = user$.subscribe({
|
||||
next: (data) => this.setAuth(data.user),
|
||||
error: () => this.purgeAuth()
|
||||
});
|
||||
this._subcriptions.push(this._user);
|
||||
} else {
|
||||
// Remove any potential remnants of previous auth states
|
||||
this.purgeAuth();
|
||||
}
|
||||
}
|
||||
|
||||
setAuth(user: User) {
|
||||
// Save JWT sent from server in localstorage
|
||||
this.jwtService.saveToken(user.token);
|
||||
// Set current user data into observable
|
||||
this.currentUserSubject.next(user);
|
||||
// Set isAuthenticated to true
|
||||
this.isAuthenticatedSubject.next(true);
|
||||
}
|
||||
|
||||
purgeAuth() {
|
||||
// Remove JWT from localstorage
|
||||
this.jwtService.destroyToken();
|
||||
// Set current user to an empty object
|
||||
this.currentUserSubject.next({} as User);
|
||||
// Set auth status to false
|
||||
this.isAuthenticatedSubject.next(false);
|
||||
}
|
||||
|
||||
attemptAuth(type: string, credentials?: { email: string; password: string; }): Observable<{ user: User }> {
|
||||
const route = (type === 'login') ? '/login' : '';
|
||||
const user$: Observable<{ user: User }> = this.http.post<{ user: User }>(`/users${route}`, { user: credentials });
|
||||
/*return user$.pipe(map(
|
||||
(data: any) => {
|
||||
this.setAuth(data.user);
|
||||
return data;
|
||||
}
|
||||
));*/
|
||||
return user$.pipe(tap(({ user }) => this.setAuth(user)));
|
||||
}
|
||||
|
||||
getCurrentUser(): User {
|
||||
return this.currentUserSubject.value;
|
||||
}
|
||||
|
||||
canAdministrate(): boolean {
|
||||
return (this.currentUserSubject.value.role == 'Admin') ? true : false;
|
||||
}
|
||||
|
||||
// Update the user on the server (email, pass, etc)
|
||||
update(user: Partial<User>): Observable<{ user: User }> {
|
||||
return this.http.put<{ user: User }>("/user", { user }).pipe(
|
||||
tap(({ user }) => {
|
||||
this.currentUserSubject.next(user);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Chart } from 'chart.js';
|
||||
import { Configuration } from 'ng-chartist';
|
||||
|
||||
import { BarConfig, CircleConfig, DoughnutConfig, LineConfig } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class UtilitiesService {
|
||||
private _coeffKgLbs: number = 2.20462;
|
||||
private _coeffFtM: number = 0.092903;
|
||||
|
||||
constructor() { }
|
||||
|
||||
getCoeffKgLbs(): number {
|
||||
return this._coeffKgLbs;
|
||||
}
|
||||
|
||||
getCoeffFtM(): number {
|
||||
return this._coeffFtM;
|
||||
}
|
||||
|
||||
getBarConfig(): Configuration {
|
||||
const config: Configuration = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
'labels': [],
|
||||
'series': []
|
||||
},
|
||||
options: {},
|
||||
responsiveOptions: []
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
getChartColors(): string[] {
|
||||
const colors: string[] = [
|
||||
'ct-color-a',
|
||||
'ct-color-b',
|
||||
'ct-color-c',
|
||||
'ct-color-d',
|
||||
'ct-color-e',
|
||||
'ct-color-f',
|
||||
'ct-color-g',
|
||||
'ct-color-h',
|
||||
'ct-color-i',
|
||||
'ct-color-j',
|
||||
'ct-color-k',
|
||||
'ct-color-l',
|
||||
'ct-color-m',
|
||||
'ct-color-n',
|
||||
'ct-color-o',
|
||||
'ct-color-p',
|
||||
'ct-color-q',
|
||||
'ct-color-r',
|
||||
'ct-color-s',
|
||||
'ct-color-t',
|
||||
'ct-color-u',
|
||||
'ct-color-v',
|
||||
'ct-color-w',
|
||||
'ct-color-x',
|
||||
'ct-color-y',
|
||||
'ct-color-z'
|
||||
];
|
||||
return colors;
|
||||
}
|
||||
|
||||
getCurrentDateFr(): string {
|
||||
return new Date().toLocaleDateString('fr');
|
||||
}
|
||||
|
||||
getSeriesColors(opacity: number, palette: string = 'all', offset: number = 0): string[] {
|
||||
let colors: string[] = [];
|
||||
switch (palette) {
|
||||
case 'pastels':
|
||||
colors = [
|
||||
`rgba(171, 222, 230, ${opacity})`,
|
||||
`rgba(203, 170, 203, ${opacity})`,
|
||||
`rgba(255, 255, 181, ${opacity})`,
|
||||
`rgba(255, 204, 182, ${opacity})`,
|
||||
`rgba(243, 176, 195, ${opacity})`,
|
||||
`rgba(198, 219, 218, ${opacity})`,
|
||||
`rgba(254, 225, 232, ${opacity})`,
|
||||
`rgba(254, 215, 195, ${opacity})`,
|
||||
`rgba(246, 234, 194, ${opacity})`,
|
||||
`rgba(236, 213, 227, ${opacity})`,
|
||||
`rgba(255, 150, 138, ${opacity})`,
|
||||
`rgba(255, 174, 165, ${opacity})`,
|
||||
`rgba(255, 197, 191, ${opacity})`,
|
||||
`rgba(255, 216, 190, ${opacity})`,
|
||||
`rgba(255, 200, 162, ${opacity})`,
|
||||
`rgba(212, 240, 240, ${opacity})`,
|
||||
`rgba(143, 202, 202, ${opacity})`,
|
||||
`rgba(204, 226, 203, ${opacity})`,
|
||||
`rgba(182, 207, 182, ${opacity})`,
|
||||
`rgba(151, 193, 169, ${opacity})`
|
||||
];
|
||||
break;
|
||||
case 'red':
|
||||
colors = [
|
||||
`rgba(163, 0, 0, ${opacity})`,
|
||||
`rgba(178, 47, 25, ${opacity})`,
|
||||
`rgba(192, 74, 49, ${opacity})`,
|
||||
`rgba(205, 99, 72, ${opacity})`,
|
||||
`rgba(217, 122, 97, ${opacity})`,
|
||||
`rgba(228, 145, 122, ${opacity})`,
|
||||
`rgba(238, 168, 148, ${opacity})`,
|
||||
`rgba(247, 192, 175, ${opacity})`,
|
||||
`rgba(255, 215, 203, ${opacity})`
|
||||
];
|
||||
break;
|
||||
case 'green':
|
||||
colors = [
|
||||
`rgba(0, 109, 45, ${opacity})`,
|
||||
`rgba(42, 124, 64, ${opacity})`,
|
||||
`rgba(67, 140, 83, ${opacity})`,
|
||||
`rgba(90, 155, 102, ${opacity})`,
|
||||
`rgba(112, 171, 122, ${opacity})`,
|
||||
`rgba(134, 187, 142, ${opacity})`,
|
||||
`rgba(156, 203, 163, ${opacity})`,
|
||||
`rgba(179, 219, 184, ${opacity})`,
|
||||
`rgba(201, 235, 205, ${opacity})`
|
||||
];
|
||||
break;
|
||||
case 'blue':
|
||||
colors = [
|
||||
`rgba(0, 76, 109, ${opacity})`,
|
||||
`rgba(37, 94, 126, ${opacity})`,
|
||||
`rgba(61, 112, 143, ${opacity})`,
|
||||
`rgba(83, 131, 161, ${opacity})`,
|
||||
`rgba(105, 150, 179, ${opacity})`,
|
||||
`rgba(127, 170, 198, ${opacity})`,
|
||||
`rgba(148, 190, 217, ${opacity})`,
|
||||
`rgba(171, 210, 236, ${opacity})`,
|
||||
`rgba(193, 231, 255, ${opacity})`
|
||||
];
|
||||
break;
|
||||
case 'all':
|
||||
default:
|
||||
colors = [
|
||||
`rgba(53, 162, 235, ${opacity})`,
|
||||
`rgba(255, 99, 132, ${opacity})`,
|
||||
`rgba(75, 192, 192, ${opacity})`,
|
||||
`rgba(255, 159, 64, ${opacity})`,
|
||||
`rgba(153, 102, 255, ${opacity})`,
|
||||
`rgba(255, 205, 86, ${opacity})`,
|
||||
`rgba(201, 203, 207, ${opacity})`,
|
||||
`rgba(93, 204, 137, ${opacity})`,
|
||||
`rgba(181, 17, 86, ${opacity})`,
|
||||
`rgba(255, 226, 5, ${opacity})`,
|
||||
`rgba(191, 101, 224, ${opacity})`,
|
||||
`rgba(76, 174, 76, ${opacity})`,
|
||||
`rgba(237, 80, 148, ${opacity})`,
|
||||
`rgba(51, 122, 183, ${opacity})`,
|
||||
`rgba(253, 24, 243, ${opacity})`,
|
||||
`rgba(214, 31, 31, ${opacity})`,
|
||||
`rgba(0, 137, 123, ${opacity})`,
|
||||
`rgba(153, 171, 180, ${opacity})`,
|
||||
`rgba(205, 186, 152, ${opacity})`,
|
||||
`rgba(101, 224, 184, ${opacity})`,
|
||||
`rgba(2, 191, 171, ${opacity})`,
|
||||
`rgba(101, 218, 224, ${opacity})`,
|
||||
`rgba(161, 199, 161, ${opacity})`,
|
||||
`rgba(217, 202, 174, ${opacity})`,
|
||||
`rgba(151, 136, 199, ${opacity})`,
|
||||
`rgba(212, 206, 112, ${opacity})`,
|
||||
`rgba(32, 182, 252, ${opacity})`,
|
||||
`rgba(241, 80, 80, ${opacity})`,
|
||||
`rgba(2, 191, 171, ${opacity})`,
|
||||
`rgba(255, 153, 0, ${opacity})`,
|
||||
`rgba(101, 218, 224, ${opacity})`,
|
||||
`rgba(138, 101, 224, ${opacity})`,
|
||||
`rgba(0, 137, 123, ${opacity})`,
|
||||
`rgba(181, 17, 86, ${opacity})`,
|
||||
`rgba(93, 204, 137, ${opacity})`,
|
||||
`rgba(255, 226, 5, ${opacity})`,
|
||||
`rgba(191, 101, 224, ${opacity})`,
|
||||
`rgba(76, 174, 76, ${opacity})`,
|
||||
`rgba(51, 122, 183, ${opacity})`,
|
||||
`rgba(237, 80, 148, ${opacity})`,
|
||||
`rgba(253, 24, 243, ${opacity})`,
|
||||
`rgba(214, 31, 31, ${opacity})`,
|
||||
`rgba(153, 171, 180, ${opacity})`,
|
||||
`rgba(205, 186, 152, ${opacity})`,
|
||||
`rgba(101, 224, 184, ${opacity})`,
|
||||
`rgba(2, 191, 171, ${opacity})`,
|
||||
`rgba(101, 218, 224, ${opacity})`,
|
||||
`rgba(161, 199, 161, ${opacity})`,
|
||||
`rgba(217, 202, 174, ${opacity})`,
|
||||
`rgba(151, 136, 199, ${opacity})`,
|
||||
`rgba(212, 206, 112, ${opacity})`,
|
||||
`rgba(255, 255, 255, ${opacity})`
|
||||
];
|
||||
if (offset > 0 && offset < colors.length) {
|
||||
colors = colors.slice(offset);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
getCircleChartConfig(): CircleConfig {
|
||||
const config: CircleConfig = {
|
||||
circleChartLabels: [],
|
||||
circleChartDatasets: [
|
||||
{
|
||||
data: [],
|
||||
label: 'Nombre total de sauts',
|
||||
backgroundColor: this.getSeriesColors(0.8),
|
||||
borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)'
|
||||
borderWidth: 2
|
||||
}
|
||||
],
|
||||
circleChartOptions: {
|
||||
cutout: '90%',
|
||||
elements: {
|
||||
arc: {
|
||||
//spacing: -10,
|
||||
borderJoinStyle: 'round',
|
||||
borderRadius: 10,
|
||||
borderWidth: 0
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false,
|
||||
position: 'left'
|
||||
}
|
||||
},
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
animation: {
|
||||
onProgress: function (this: Chart) {
|
||||
const width = this.width, height = this.height, ctx = this.ctx;
|
||||
const count: number = parseInt(this.data.datasets[0].data[0]!.toString());
|
||||
const diff: number = parseInt(this.data.datasets[0].data[1]!.toString());
|
||||
const total: number = (count + diff);
|
||||
const percent: number = Math.round((count/total*100));
|
||||
const lineHeight = (height / 8);
|
||||
ctx.restore();
|
||||
let fontSize = (height / 120).toFixed(2);
|
||||
ctx.font = `${fontSize}em sans-serif`;
|
||||
//ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillStyle = '#dddddd';
|
||||
//const text = `${percent} % (${count} ${this.data.datasets[0].label})`, textX = Math.round((width - ctx.measureText(text).width) / 2), textY = height / 2;
|
||||
let text = this.data.datasets[0].label!;
|
||||
let textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
let textY = height / 2;
|
||||
ctx.fillText(text, textX, (textY-lineHeight));
|
||||
text = `${percent}%`;
|
||||
textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
textY = height / 2;
|
||||
ctx.fillText(text, textX, textY);
|
||||
|
||||
ctx.restore();
|
||||
fontSize = (height / 180).toFixed(2);
|
||||
ctx.font = `${fontSize}em sans-serif`;
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillStyle = '#dddddd';
|
||||
text = `${count} / ${total}`;
|
||||
textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
textY = height / 2;
|
||||
ctx.fillText(text, textX, (textY+lineHeight));
|
||||
ctx.save();
|
||||
//console.log(width, height, fontSize);
|
||||
},
|
||||
onComplete: function (this: Chart) {
|
||||
const width = this.width, height = this.height, ctx = this.ctx;
|
||||
const count: number = parseInt(this.data.datasets[0].data[0]!.toString());
|
||||
const diff: number = parseInt(this.data.datasets[0].data[1]!.toString());
|
||||
const total: number = (count + diff);
|
||||
const percent: number = Math.round((count/total*100));
|
||||
const lineHeight = (height / 8);
|
||||
ctx.restore();
|
||||
let fontSize = (height / 120).toFixed(2);
|
||||
ctx.font = `${fontSize}em sans-serif`;
|
||||
//ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillStyle = '#dddddd';
|
||||
//ctx.fillStyle = this.data!.datasets[0].backgroundColor ? this.data.datasets[0].backgroundColor[0]!.toString() : '#dddddd';
|
||||
//const text = `${percent} % (${count} ${this.data.datasets[0].label})`, textX = Math.round((width - ctx.measureText(text).width) / 2), textY = height / 2;
|
||||
let text = this.data.datasets[0].label!;
|
||||
let textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
let textY = height / 2;
|
||||
ctx.fillText(text, textX, (textY-lineHeight));
|
||||
text = `${percent}%`;
|
||||
textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
textY = height / 2;
|
||||
ctx.fillText(text, textX, textY);
|
||||
|
||||
ctx.restore();
|
||||
fontSize = (height / 180).toFixed(2);
|
||||
ctx.font = `${fontSize}em sans-serif`;
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillStyle = '#dddddd';
|
||||
text = `${count} / ${total}`;
|
||||
textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
textY = height / 2;
|
||||
ctx.fillText(text, textX, (textY+lineHeight));
|
||||
ctx.save();
|
||||
//console.log(width, height, fontSize);
|
||||
},
|
||||
},
|
||||
},
|
||||
circleChartPlugins: [
|
||||
/*{
|
||||
beforeInit: (chart: Chart<"doughnut", number[], unknown>) => {
|
||||
const dataset = chart.data.datasets[0];
|
||||
chart.data.labels = [dataset.label];
|
||||
dataset.data = [dataset.data[0], 100 - dataset.data[0]];
|
||||
},
|
||||
id: 'beforeinit'
|
||||
},*/
|
||||
{
|
||||
beforeDatasetDraw: (chart: Chart<"doughnut", number[], unknown>) => {
|
||||
const width = chart.width, height = chart.height, ctx = chart.ctx;
|
||||
ctx.restore();
|
||||
const fontSize = (height / 150).toFixed(2);
|
||||
ctx.font = fontSize + "em sans-serif";
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.textBaseline = "middle";
|
||||
const text = chart.data.datasets[0].data[0] + "%", textX = Math.round((width - ctx.measureText(text).width) / 2), textY = height / 2;
|
||||
ctx.fillText(text, textX, textY);
|
||||
ctx.save();
|
||||
console.log(width, height, fontSize);
|
||||
},
|
||||
id: 'doughnutlabel'
|
||||
}
|
||||
],
|
||||
circleChartLegend: false
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
getDoughnutChartConfig(): DoughnutConfig {
|
||||
const config: DoughnutConfig = {
|
||||
doughnutChartLabels: [],
|
||||
doughnutChartDatasets: [
|
||||
{
|
||||
data: [],
|
||||
label: 'Nombre total de sauts',
|
||||
backgroundColor: this.getSeriesColors(0.8),
|
||||
borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)'
|
||||
borderWidth: 2
|
||||
}
|
||||
],
|
||||
doughnutChartOptions: {
|
||||
elements: {
|
||||
arc: {
|
||||
borderWidth: 2,
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'left'
|
||||
}
|
||||
},
|
||||
responsive: true,
|
||||
maintainAspectRatio: false
|
||||
},
|
||||
doughnutChartLegend: false
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
getBarChartConfig(): BarConfig {
|
||||
const config: BarConfig = {
|
||||
barChartData: {
|
||||
labels: [''],
|
||||
datasets: []
|
||||
},
|
||||
barChartOptions: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top'
|
||||
}
|
||||
},
|
||||
elements: {
|
||||
bar: {
|
||||
borderWidth: 1,
|
||||
}
|
||||
},
|
||||
/*interaction: {
|
||||
intersect: false,
|
||||
axis: 'x'
|
||||
},*/
|
||||
scales: {
|
||||
x: {
|
||||
display: false,
|
||||
beginAtZero: true,
|
||||
ticks: { color: 'rgba(255,255,255,0.3)' },
|
||||
grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2], tickBorderDashOffset: 2 }
|
||||
},
|
||||
y: {
|
||||
display: true,
|
||||
beginAtZero: true,
|
||||
ticks: { color: 'rgba(255,255,255,0.3)' },
|
||||
grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1,2], tickBorderDashOffset: 2 }
|
||||
}
|
||||
},
|
||||
responsive: true,
|
||||
maintainAspectRatio: false
|
||||
},
|
||||
barChartPlugins: [],
|
||||
barChartLegend: true
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
getHorizontalBarChartConfig(): BarConfig {
|
||||
const config: BarConfig = {
|
||||
barChartData: {
|
||||
labels: [''],
|
||||
datasets: []
|
||||
},
|
||||
barChartOptions: {
|
||||
indexAxis: 'y',
|
||||
elements: {
|
||||
bar: {
|
||||
borderWidth: 1,
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'left'
|
||||
},
|
||||
title: {
|
||||
display: false,
|
||||
text: 'Nombre total de sauts'
|
||||
}
|
||||
},
|
||||
responsive: true,
|
||||
aspectRatio: 3,
|
||||
scales: {
|
||||
x: {
|
||||
beginAtZero: true,
|
||||
ticks: { color: 'rgba(255,255,255,0.3)' },
|
||||
grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2] }
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: { color: 'rgba(255,255,255,0.3)' },
|
||||
grid: { display: false, color: 'rgba(255,255,255,0.2)' }
|
||||
}
|
||||
}
|
||||
},
|
||||
barChartPlugins: [],
|
||||
barChartLegend: false
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
getLineChartConfig(): LineConfig {
|
||||
const config: LineConfig = {
|
||||
lineChartData: {
|
||||
labels: [],
|
||||
datasets: []
|
||||
},
|
||||
lineChartOptions: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top'
|
||||
}
|
||||
},
|
||||
/*interaction: {
|
||||
intersect: false,
|
||||
axis: 'x'
|
||||
},*/
|
||||
scales: {
|
||||
x: {
|
||||
display: true,
|
||||
beginAtZero: true,
|
||||
ticks: { color: 'rgba(255,255,255,0.3)' },
|
||||
grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2], tickBorderDashOffset: 2 }
|
||||
},
|
||||
y: {
|
||||
display: true,
|
||||
beginAtZero: true,
|
||||
ticks: { color: 'rgba(255,255,255,0.3)' },
|
||||
grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1,2], tickBorderDashOffset: 2 }
|
||||
}
|
||||
},
|
||||
responsive: true,
|
||||
maintainAspectRatio: false
|
||||
},
|
||||
lineChartLegend: true
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
getMonthsList(): Array<string> {
|
||||
return ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'];
|
||||
}
|
||||
|
||||
getStackedLineAreaChartConfig(): LineConfig {
|
||||
const config: LineConfig = {
|
||||
lineChartData: {
|
||||
labels: [],
|
||||
datasets: []
|
||||
},
|
||||
lineChartOptions: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top'
|
||||
}
|
||||
},
|
||||
interaction: {
|
||||
mode: 'nearest',
|
||||
axis: 'x',
|
||||
intersect: false
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
display: true,
|
||||
beginAtZero: true,
|
||||
ticks: { color: 'rgba(255,255,255,0.3)' },
|
||||
grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2] }
|
||||
},
|
||||
y: {
|
||||
display: true,
|
||||
beginAtZero: true,
|
||||
stacked: true,
|
||||
ticks: { color: 'rgba(255,255,255,0.3)' },
|
||||
grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1,2] }
|
||||
}
|
||||
},
|
||||
responsive: true,
|
||||
maintainAspectRatio: false
|
||||
},
|
||||
lineChartLegend: true
|
||||
};
|
||||
return config;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user