chart replaces

This commit is contained in:
Daniel Ponte 2025-02-21 21:50:31 -05:00
parent e910ba5226
commit a339b11a94
3 changed files with 54 additions and 12 deletions

View file

@ -1,16 +1,21 @@
import { Component, ElementRef, Input } from '@angular/core'; import { Component, ElementRef, Input } from '@angular/core';
import * as d3 from 'd3'; import * as d3 from 'd3';
import { CallsService } from '../calls/calls.service'; import { CallsService } from '../calls/calls.service';
import { CallStatsRecord } from '../calls'; import { Observable, switchMap } from 'rxjs';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { NgIf } from '@angular/common';
@Component({ @Component({
selector: 'chart', selector: 'chart',
imports: [], imports: [
NgIf,
MatProgressSpinnerModule,
],
templateUrl: './charts.component.html', templateUrl: './charts.component.html',
styleUrl: './charts.component.scss', styleUrl: './charts.component.scss',
}) })
export class ChartsComponent { export class ChartsComponent {
@Input() interval!: string; @Input() interval!: Observable<string>;
loading = true; loading = true;
// I hate javascript so much // I hate javascript so much
months = [ months = [
@ -32,8 +37,8 @@ export class ChartsComponent {
private callsSvc: CallsService, private callsSvc: CallsService,
) {} ) {}
dateFormat(d: Date): string { dateFormat(d: Date, interval: string): string {
switch (this.interval) { switch (interval) {
case 'month': case 'month':
return `${this.months[d.getMonth()]} ${d.getFullYear()}`; return `${this.months[d.getMonth()]} ${d.getFullYear()}`;
case 'day': case 'day':
@ -45,7 +50,11 @@ export class ChartsComponent {
} }
ngOnInit() { ngOnInit() {
this.callsSvc.getCallStats(this.interval).subscribe((stats) => { this.interval.pipe(switchMap((intv) => {
this.loading = true;
return this.callsSvc.getCallStats(intv);
})).
subscribe((stats) => {
let cMax = 0; let cMax = 0;
var cMin = 0; var cMin = 0;
let data = stats.stats.map((rec) => { let data = stats.stats.map((rec) => {
@ -58,12 +67,14 @@ export class ChartsComponent {
if (rec.count > cMax) { if (rec.count > cMax) {
cMax = rec.count; cMax = rec.count;
} }
return { count: rec.count, time: this.dateFormat(new Date(rec.time)) }; return { count: rec.count, time: this.dateFormat(new Date(rec.time), stats.interval) };
}); });
// set the dimensions and margins of the graph // set the dimensions and margins of the graph
var margin = { top: 30, right: 30, bottom: 70, left: 60 }, var margin = { top: 30, right: 30, bottom: 70, left: 60 },
width = 460 - margin.left - margin.right, width = 460 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom; height = 400 - margin.top - margin.bottom;
// clear the old one
d3.select(this.elementRef.nativeElement).select('.chart svg').remove();
const svg = d3 const svg = d3
.select(this.elementRef.nativeElement) .select(this.elementRef.nativeElement)
.select('.chart') .select('.chart')
@ -109,6 +120,7 @@ export class ChartsComponent {
.attr('fill', function (d) { .attr('fill', function (d) {
return d3.interpolateTurbo((d.count - cMin) / (cMax - cMin)); return d3.interpolateTurbo((d.count - cMin) / (cMax - cMin));
}); });
this.loading = false;
}); });
} }
} }

View file

@ -1,4 +1,14 @@
<mat-card class="chart" appearance="outlined"> <mat-card class="chart" appearance="outlined">
<div class="chartTitle">Calls By Week</div> <div class="chartTitle">Calls By</div>
<chart interval="week"></chart> <form [formGroup]="form">
<mat-form-field>
<mat-select formControlName="callsPer">
<mat-option value="hour">Hour</mat-option>
<mat-option value="day">Day</mat-option>
<mat-option value="week">Week</mat-option>
<mat-option value="month">Month</mat-option>
</mat-select>
</mat-form-field>
</form>
<chart [interval]="callsOb"></chart>
</mat-card> </mat-card>

View file

@ -1,11 +1,31 @@
import { Component } from '@angular/core'; import { Component, computed, signal, ViewChild } from '@angular/core';
import { ChartsComponent } from '../charts/charts.component'; import { ChartsComponent } from '../charts/charts.component';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { debounceTime, filter, Observable, startWith, switchAll, switchMap } from 'rxjs';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
@Component({ @Component({
selector: 'app-home', selector: 'app-home',
imports: [ChartsComponent, MatCardModule], imports: [ChartsComponent, MatCardModule, MatFormFieldModule, MatSelectModule, MatInputModule, FormsModule, ReactiveFormsModule ],
templateUrl: './home.component.html', templateUrl: './home.component.html',
styleUrl: './home.component.scss', styleUrl: './home.component.scss',
}) })
export class HomeComponent {} export class HomeComponent {
form = new FormGroup({
callsPer: new FormControl(),
});
callsOb!: Observable<string>;
ngOnInit() {
this.form.controls["callsPer"].setValue("week");
this.callsOb = this.form.controls['callsPer'].valueChanges
.pipe(
startWith("week"),
debounceTime(300),
filter(val => val !== null)
);
}
}