Eigenständige Chart-Komponente
This commit is contained in:
parent
9d790cf286
commit
780f3cb6a5
@ -1,14 +1,32 @@
|
||||
<main class="main">
|
||||
<div ngbDropdown class="d-inline-block" #houseDrop="ngbDropdown">
|
||||
Haushalt:
|
||||
<button type="button" class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle>
|
||||
{{getHouseName()}}
|
||||
</button>
|
||||
<div ngbDropdownMenu aria-labelledby="dropdownBasic1">
|
||||
<button ngbDropdownItem (click)="$event.stopPropagation(); houseId=1;">Kerpen</button>
|
||||
<button ngbDropdownItem (click)="$event.stopPropagation(); houseId=2;">Rommerskirchen</button>
|
||||
</div>
|
||||
</div>
|
||||
<div ngbDropdown class="d-inline-block">
|
||||
<button type="button" class="btn btn-outline-primary" id="dropdownBasic2" ngbDropdownToggle>
|
||||
Zeitraum
|
||||
</button>
|
||||
<div ngbDropdownMenu aria-labelledby="dropdownBasic2">
|
||||
<button ngbDropdownItem (click)="$event.stopPropagation(); duration=120;">letzte 2 Stunden</button>
|
||||
<button ngbDropdownItem (click)="$event.stopPropagation(); duration=360;">letzte 6 Stunden</button>
|
||||
<button ngbDropdownItem (click)="$event.stopPropagation(); duration=1440;">letzte 24 Stunden</button>
|
||||
</div>
|
||||
</div>
|
||||
<div ngbAccordion>
|
||||
<div ngbAccordionItem>
|
||||
<h2 ngbAccordionHeader>
|
||||
<button ngbAccordionButton>Diagramm der letzten 24h</button>
|
||||
<button ngbAccordionButton>Diagramm</button>
|
||||
</h2>
|
||||
<div ngbAccordionCollapse>
|
||||
<div ngbAccordionBody>
|
||||
<div style="border: 1px solid blueviolet;width: 100%; height: 100%;">
|
||||
<canvas id="canvas"></canvas>
|
||||
</div>
|
||||
<app-chart houseId="{{houseId}}" duration="{{duration}}"></app-chart>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -18,7 +36,7 @@
|
||||
</h2>
|
||||
<div ngbAccordionCollapse>
|
||||
<div ngbAccordionBody>
|
||||
<ng-template><app-test duration="P1D"></app-test></ng-template>
|
||||
<ng-template><app-test duration="P1D" houseId="{{houseId}}"></app-test></ng-template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,77 +1,44 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import { TestComponent } from "./test/test.component";
|
||||
import { ChartComponent } from './chart/chart.component';
|
||||
import { RestService } from './rest.service';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { Chart } from 'chart.js/auto';
|
||||
import 'chartjs-adapter-date-fns';
|
||||
import { de } from 'date-fns/locale';
|
||||
import { Aggregate } from './aggregate';
|
||||
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
standalone: true,
|
||||
imports: [RouterOutlet, TestComponent, NgbModule,],
|
||||
imports: [RouterOutlet, TestComponent, ChartComponent, NgbModule,NgbDropdownModule,],
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.css'
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
export class AppComponent implements OnInit, OnChanges {
|
||||
|
||||
constructor(private rest: RestService) {
|
||||
}
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.rest.getLatestData().subscribe((data: Aggregate[]) => {
|
||||
this.chart = new Chart('canvas', {
|
||||
type: 'line',
|
||||
options: {
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time',
|
||||
time: {
|
||||
tooltipFormat: 'HH:mm',
|
||||
displayFormats: {
|
||||
hour: 'HH:mm',
|
||||
minute: 'HH:mm'
|
||||
}
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Zeitpunkt'
|
||||
},
|
||||
adapters: {
|
||||
date: {
|
||||
locale: de
|
||||
}
|
||||
}
|
||||
},
|
||||
y: {
|
||||
type: 'linear'
|
||||
//stacked: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
data: {
|
||||
labels: data.map(row => row.timestampStart),
|
||||
datasets: [
|
||||
{
|
||||
label: 'Bezug',
|
||||
pointRadius: 0,
|
||||
data: data.map(row => row.obtainedEnergy/60000)
|
||||
}, {
|
||||
label: 'Erzeugt',
|
||||
pointRadius: 0,
|
||||
data: data.map(row => row.producedEnergy/60000)
|
||||
}, {
|
||||
label: 'Eingespeist',
|
||||
pointRadius: 0,
|
||||
data: data.map(row => row.injectedEnergy/60000)
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
})
|
||||
this.houseId = 1;
|
||||
this.duration = 120;
|
||||
}
|
||||
title = 'test1';
|
||||
chart: Chart | null = null;
|
||||
|
||||
getHouseName(): string {
|
||||
if (this.houseId) {
|
||||
if (this.houseId === 1) {
|
||||
return 'Kerpen';
|
||||
} else if (this.houseId === 2) {
|
||||
return 'Rommerskirchen';
|
||||
} else {
|
||||
return 'Unbekannt';
|
||||
}
|
||||
} else {
|
||||
return 'Unbekannt';
|
||||
}
|
||||
}
|
||||
|
||||
houseId: number | undefined = undefined;
|
||||
duration: number | undefined = undefined;
|
||||
}
|
||||
|
||||
0
src/app/chart/chart.component.css
Normal file
0
src/app/chart/chart.component.css
Normal file
3
src/app/chart/chart.component.html
Normal file
3
src/app/chart/chart.component.html
Normal file
@ -0,0 +1,3 @@
|
||||
<div style="border: 1px solid blueviolet;width: 50%; height: 50%;">
|
||||
<canvas id="canvas"></canvas>
|
||||
</div>
|
||||
23
src/app/chart/chart.component.spec.ts
Normal file
23
src/app/chart/chart.component.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ChartComponent } from './chart.component';
|
||||
|
||||
describe('ChartComponent', () => {
|
||||
let component: ChartComponent;
|
||||
let fixture: ComponentFixture<ChartComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ChartComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ChartComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
93
src/app/chart/chart.component.ts
Normal file
93
src/app/chart/chart.component.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import { Component, OnInit, OnChanges, SimpleChanges, numberAttribute, Input } from '@angular/core';
|
||||
import { Chart } from 'chart.js/auto';
|
||||
import 'chartjs-adapter-date-fns';
|
||||
import { de } from 'date-fns/locale';
|
||||
import { RestService } from '../rest.service';
|
||||
import { Aggregate } from '../aggregate';
|
||||
|
||||
@Component({
|
||||
selector: 'app-chart',
|
||||
standalone: true,
|
||||
imports: [],
|
||||
templateUrl: './chart.component.html',
|
||||
styleUrl: './chart.component.css'
|
||||
})
|
||||
export class ChartComponent implements OnInit, OnChanges {
|
||||
|
||||
@Input({ transform: numberAttribute }) houseId!: number;
|
||||
@Input({ transform: numberAttribute }) duration!: number;
|
||||
chart: Chart | null = null;
|
||||
|
||||
constructor(private rest: RestService) {
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
console.log('Nothing yet on chart.ngOnInit()');
|
||||
}
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.rest.getLatestData(this.houseId, this.duration).subscribe((data: Aggregate[]) => {
|
||||
console.log('Change chart');
|
||||
if (this.chart) {
|
||||
this.chart.clear();
|
||||
this.chart.destroy();
|
||||
}
|
||||
this.chart = new Chart('canvas', {
|
||||
type: 'line',
|
||||
options: {
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time',
|
||||
time: {
|
||||
tooltipFormat: 'HH:mm',
|
||||
displayFormats: {
|
||||
hour: 'HH:mm',
|
||||
minute: 'HH:mm'
|
||||
}
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Zeitpunkt'
|
||||
},
|
||||
adapters: {
|
||||
date: {
|
||||
locale: de
|
||||
}
|
||||
}
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
//stacked: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Leistung [Watt]'
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
data: {
|
||||
labels: data.map(row => row.timestampStart),
|
||||
datasets: [
|
||||
{
|
||||
label: 'Bezug (Stromnetz)',
|
||||
borderColor: '#ff0000',
|
||||
pointRadius: 1,
|
||||
data: data.map(row => row.obtainedEnergy/60000)
|
||||
}, {
|
||||
label: 'Erzeugt (Solar)',
|
||||
borderColor: '#ffa500',
|
||||
pointRadius: 1,
|
||||
data: data.map(row => row.producedEnergy/60000)
|
||||
}, {
|
||||
label: 'Eingespeist (Stromnetz)',
|
||||
borderColor: '#006400',
|
||||
pointRadius: 1,
|
||||
data: data.map(row => row.injectedEnergy/60000)
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -16,15 +16,15 @@ export class RestService {
|
||||
return this.http.get<Statistics>('https://vz.home.peper.info/rest-vz/stats?houseId=1&duration=P7D');
|
||||
}
|
||||
|
||||
getLatestData(): Observable<Aggregate[]> {
|
||||
return this.http.get<Aggregate[]>('https://vz.home.peper.info/rest-vz/latest-data?houseId=2&timeWindow=1440');
|
||||
getLatestData(houseId: Number, duration: Number): Observable<Aggregate[]> {
|
||||
return this.http.get<Aggregate[]>('https://vz.home.peper.info/rest-vz/latest-data?houseId=' + houseId + '&timeWindow=' + duration);
|
||||
}
|
||||
|
||||
getStatisticsWithDuration(duration: string | undefined): Observable<Statistics> {
|
||||
getStatisticsWithDuration(duration: string | undefined, houseId: Number): Observable<Statistics> {
|
||||
if (duration) {
|
||||
return this.http.get<Statistics>('https://vz.home.peper.info/rest-vz/stats?houseId=1&duration=' + duration);
|
||||
return this.http.get<Statistics>('https://vz.home.peper.info/rest-vz/stats?houseId=' + houseId + '&duration=' + duration);
|
||||
} else {
|
||||
return this.http.get<Statistics>('https://vz.home.peper.info/rest-vz/stats?houseId=1');
|
||||
return this.http.get<Statistics>('https://vz.home.peper.info/rest-vz/stats?houseId=' + houseId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
||||
import { Statistics } from '../statistics';
|
||||
import { RestService } from '../rest.service';
|
||||
import { formatDate, formatNumber } from '@angular/common';
|
||||
import { NgIf } from '@angular/common';
|
||||
import { numberAttribute } from '@angular/core';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
@Component({
|
||||
@ -12,15 +13,22 @@ import * as _ from 'lodash';
|
||||
templateUrl: './test.component.html',
|
||||
styleUrl: './test.component.css'
|
||||
})
|
||||
export class TestComponent implements OnInit {
|
||||
export class TestComponent implements OnInit, OnChanges {
|
||||
statistics!: Statistics;
|
||||
@Input() duration!: string;
|
||||
@Input({ transform: numberAttribute }) houseId!: Number;
|
||||
|
||||
constructor(private rest: RestService) {
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.rest.getStatisticsWithDuration(this.duration, this.houseId).subscribe((data: Statistics) => {
|
||||
this.statistics = data;
|
||||
})
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.rest.getStatisticsWithDuration(this.duration).subscribe((data: Statistics) => {
|
||||
this.rest.getStatisticsWithDuration(this.duration, this.houseId).subscribe((data: Statistics) => {
|
||||
this.statistics = data;
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user