continuation de la partie advertiser

This commit is contained in:
MiharyR 2021-11-24 12:07:31 +01:00
parent 01c0e137e0
commit 1e5b9bd49c
28 changed files with 656 additions and 91 deletions

View file

@ -0,0 +1,91 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- Navbar -->
<app-navbar-advertiser></app-navbar-advertiser>
<!-- Filter -->
<div class="filtersContainer mat-elevation-z8">
<div style="font-weight: bold">Filtre</div>
<mat-divider></mat-divider><br>
<div *ngIf="true; then colPeriode"></div>
<br><mat-divider></mat-divider><br>
<div style="text-align: right; font-size: small;">
<button mat-button (click)="onApplyFilter()" style="font-size: small">Appliquer</button>
</div>
</div>
<!-- chart -->
<div class="chartContainer">
<canvas baseChart
[datasets]="lineChartData"
[labels]="lineChartLabels"
[options]="chartOptions"
[colors]="[]"
[legend]="true"
[chartType]="'line'">
</canvas>
</div>
</div>
</div>
<!-- ------------------------------------------------------------------------------------------------------------------- -->
<ng-template #colPeriode>
<!-- startDate -->
<mat-form-field appearance="fill" style="width: 140px;">
<mat-label>début</mat-label>
<input matInput type="date" [ngModel] ="startDate | date:'yyyy-MM-dd'" (ngModelChange)="onNewStartDate($event);">
</mat-form-field>
&nbsp; - &nbsp;
<!-- endDate -->
<mat-form-field appearance="fill" style="width: 140px;">
<mat-label>fin</mat-label>
<input matInput type="date" [ngModel] ="endDate | date:'yyyy-MM-dd'" (ngModelChange)="onNewEndDate($event);">
</mat-form-field>
&nbsp; - &nbsp;
<!-- step -->
<mat-form-field appearance="fill" style="width: 140px;">
<mat-label>pas d'affichage</mat-label>
<input matInput type="number" [(ngModel)] =step>
</mat-form-field>
&nbsp; - &nbsp;
<!-- step unity -->
<mat-form-field appearance="fill">
<mat-label>unité du pas d'affichage</mat-label>
<mat-select [(ngModel)]="stepUnity">
<mat-option value="jour">jour</mat-option>
<mat-option value="semaine">semaine</mat-option>
<mat-option value="mois">mois</mat-option>
</mat-select>
</mat-form-field>
<!-- ads -->
<mat-select [formControl]="formControl" multiple style="padding-top: 10px;">
<mat-select-trigger>
<span *ngIf="formControl.value?.length > 0">
<span *ngFor="let coupleNameViews of formControl.value"> {{coupleNameViews.name}}, </span>
</span>
</mat-select-trigger>
<mat-option *ngFor="let coupleNameViews of allCoupleNameViews" [value]="coupleNameViews">{{coupleNameViews.name}}</mat-option>
</mat-select>
</ng-template>

View file

@ -0,0 +1,60 @@
.myContainer {
font-size: small;
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
overflow-y: scroll;
}
input {
font-size: small;
width: 140px;
}
.filtersContainer {
background-color: white;
width: 60%;
margin: 50px 50px 50px 50px;
padding: 20px 20px 20px 20px;
}
.chartContainer {
background-color: white;
border: solid 1px black;
padding: 10px 10px 10px 10px;
margin: 50px 50px 50px 50px;
}
// ---------------------------------------------
// periode
.periode {
padding: 10px 10px 0px 10px;
}
.periode .titleContainer {
text-align: right;
border-right: solid 1px #dcdcdc;
font-weight: bold;
}
// -------------------------------------------------------------------------
// aura
::ng-deep .mat-checkbox-ripple .mat-ripple-element {
background-color: grey !important;
}
// contenu coche
::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
background-color: black !important;
}
// indeterminate
::ng-deep .mat-checkbox .mat-checkbox-frame {
border: solid 1px black !important;
background-color: white !important;
}

View file

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PagesPopularityComponent } from './pages-popularity.component';
describe('SubjectsPopularityComponent', () => {
let component: PagesPopularityComponent;
let fixture: ComponentFixture<PagesPopularityComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PagesPopularityComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PagesPopularityComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,234 @@
import { Component, OnInit } from '@angular/core';
import {FormControl} from "@angular/forms";
import {ChartDataSets} from "chart.js";
import {Label} from "ng2-charts";
import { Router} from "@angular/router";
import {FictitiousAdvertsService} from "../../utils/services/fictitiousDatas/fictitiousAdverts/fictitious-adverts.service";
import {FictitiousVideosService} from "../../utils/services/fictitiousDatas/fictitiousVideos/fictitious-videos.service";
import {ThemeService} from "../../utils/services/theme/theme.service";
interface CoupleNameViews {
name: string,
views: Date[],
}
@Component({
selector: 'app-subjects-popularity',
templateUrl: './pages-popularity.component.html',
styleUrls: ['./pages-popularity.component.scss']
})
export class PagesPopularityComponent implements OnInit
{
formControl: FormControl;
allCoupleNameViews: CoupleNameViews[] = [];
startDate: Date = null;
endDate: Date = null;
step: number = 1;
stepUnity: string = "jour" ;
oneDay: number = 24*60*60*1000;
oneWeek: number = 7*24*60*60*1000;
lineChartData: ChartDataSets[] = [];
lineChartLabels: Label[] = [];
chartOptions: any = {
responsive: true,
scales: {
yAxes: [{ display: true, scaleLabel: { display: true, labelString: "vues" } }],
xAxes: [{ scaleLabel: { display: true, labelString: "temps" } }],
}
};
constructor( private router: Router,
public themeService: ThemeService,
private fictitiousAdvertsService: FictitiousAdvertsService,
private fictitiousVideosService: FictitiousVideosService ) {}
ngOnInit(): void
{
if(this.router.url.includes("ads")) this.ngOnInitAds();
else if(this.router.url.includes("subjects")) this.ngOnInitSubjects();
this.formControl = new FormControl(this.allCoupleNameViews);
this.onApplyFilter();
}
// Sera excuté si on est sur la page 'adsPopularity'
// Remplie l'attribut 'allCoupleNameViews'
ngOnInitAds(): void
{
const allAdverts = this.fictitiousAdvertsService.get_TAB_ADVERT();
for(let advert of allAdverts)
{
let couple = {name: advert.title, views: advert.views }
this.allCoupleNameViews.push(couple);
}
}
// Sera excuté si on est sur la page 'subjectsPopularity'
// Remplie l'attribut 'allCoupleNameViews'
ngOnInitSubjects(): void
{
const allVideos = this.fictitiousVideosService.get_TAB_VIDEO();
let myMap: Map<string,Date[]> = new Map();
for(let video of allVideos)
{
const key = video.interest;
if(!myMap.has(key)) myMap.set(key, video.watchedDates);
else {
let tabDate = myMap.get(key);
for(let date0 of video.watchedDates) tabDate = this.insertInOrder(tabDate, date0);
myMap.set(key, tabDate);
}
}
for(const [key, value] of myMap.entries())
{
let couple = {name: key, views: value }
this.allCoupleNameViews.push(couple);
}
}
// Applique le filtre
onApplyFilter(): void
{
// --- initialisation ---
this.lineChartData = [];
this.lineChartLabels = [];
if(this.step <= 0) this.step = 0;
if(this.endDate === null) this.endDate = new Date();
if(this.startDate === null) this.startDate = new Date(this.endDate.getTime() - this.oneWeek); // date d'il y a une semaine
const startTime = this.startDate.getTime();
const endTime = this.endDate.getTime();
// --- remplissage de 'lineChartLabels' ---
let dataWithZeros = [];
let time = startTime;
const intervals = [];
while(time <= endTime)
{
dataWithZeros.push(0);
this.lineChartLabels.push(this.getLabel(new Date(time)));
intervals.push(time);
time = this.addStep(time);
}
intervals.push(time);
// --- remplissage de 'lineChartLabels' ---
for(let coupleNameViews of this.formControl.value)
{
let data = dataWithZeros.slice();
let label = coupleNameViews.name;
let index = 0;
for(let date0 of coupleNameViews.views)
{
const time0 = date0.getTime();
if(time0 > endTime) break;
if((startTime <= time0) && (time0 <= endTime))
{
while((index < intervals.length) && (time0 >= intervals[index])) index += 1;
index = index - 1;
data[index] += 1;
}
}
this.lineChartData.push({"data": data.slice(), "label": label});
}
}
onNewStartDate(event): void {
this.startDate = new Date(event);
}
onNewEndDate(event): void {
this.endDate = new Date(event);
}
// Renvoie le bon label pour le graph
getLabel(date0: Date): string
{
if((this.stepUnity === 'jour') && (this.step === 1))
{
return date0.toLocaleDateString();
}
else {
const time2 = this.addStep(date0.getTime()) - this.oneDay;
let date2 = new Date(time2);
return date0.toLocaleDateString() + " à " + date2.toLocaleDateString();
}
}
// Ajoute le bon pas à la date 'new Date(time)'
addStep(time: number): number
{
let newDate;
if(this.stepUnity === 'jour') {
newDate = new Date(time + this.step*this.oneDay);
}
else if(this.stepUnity === 'semaine') {
newDate = new Date(time + this.step*this.oneWeek);
}
else
{
const oldDate = new Date(time);
let newMonth = oldDate.getMonth() + this.step;
const newYear = oldDate.getFullYear() + (newMonth / 12);
newMonth = newMonth % 12;
const day = this.startDate.getDate();
if((newMonth === 1) && ([29, 30, 31].includes(day))) { // si fevrier et si jour n'existe pas
newDate = new Date(newYear, newMonth, 28);
}
else if((day === 31) && ([3, 5, 9, 10].includes(newMonth))) { // si 31 et mois à 30 jours
newDate = new Date(newYear, newMonth, 30);
}
else {
newDate = new Date(newYear, newMonth, day);
}
}
const _1h = 60*60*1000;
if(newDate.getHours() === 23) return newDate.getTime() + _1h;
else if(newDate.getHours() === 1) return newDate.getTime() - _1h;
else return newDate.getTime();
}
// Insere la date0 dans le tableau tabDate par ordre croissant
insertInOrder(tabDate: Date[], date0: Date): Date[]
{
let i = 0;
let n = tabDate.length;
let time0 = date0.getTime();
while((i <n) && (time0 > tabDate[i].getTime())) i++;
if(i === n) tabDate.push(date0);
else tabDate.splice(i, 0, date0);
return tabDate;
}
}