slow build FIX + charts glitch FIX + code clean
This commit is contained in:
parent
a94d80753a
commit
dc7e57f341
@ -9,12 +9,12 @@ import {registerLocaleData} from '@angular/common';
|
|||||||
import localeDe from '@angular/common/locales/de';
|
import localeDe from '@angular/common/locales/de';
|
||||||
import localeDeExtra from '@angular/common/locales/extra/de';
|
import localeDeExtra from '@angular/common/locales/extra/de';
|
||||||
import {stompServiceFactory} from './common';
|
import {stompServiceFactory} from './common';
|
||||||
import {Chart, registerables} from 'chart.js';
|
import {BarController, BarElement, Chart, Legend, LinearScale, TimeScale, Tooltip} from 'chart.js';
|
||||||
import 'chartjs-adapter-date-fns';
|
import 'chartjs-adapter-date-fns';
|
||||||
|
|
||||||
registerLocaleData(localeDe, 'de-DE', localeDeExtra);
|
registerLocaleData(localeDe, 'de-DE', localeDeExtra);
|
||||||
|
|
||||||
Chart.register(...registerables);
|
Chart.register(TimeScale, LinearScale, BarController, BarElement, Tooltip, Legend);
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
export const appConfig: ApplicationConfig = {
|
||||||
providers: [
|
providers: [
|
||||||
|
|||||||
@ -9,16 +9,6 @@
|
|||||||
{{ menuService.title }}
|
{{ menuService.title }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (locationService.id !== null) {
|
|
||||||
<div class="MainMenuItem" (click)="configService.locationId = locationService.id">
|
|
||||||
@if (configService.locationId === locationService.id) {
|
|
||||||
<fa-icon [icon]="faBookmarkSolid" class="bookmarkActive"></fa-icon>
|
|
||||||
} @else {
|
|
||||||
<fa-icon [icon]="faBookmarkRegular" class="bookmarkInactive"></fa-icon>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<div class="MainMenuItem" routerLink="/Location">
|
<div class="MainMenuItem" routerLink="/Location">
|
||||||
<fa-icon [icon]="faHome"></fa-icon>
|
<fa-icon [icon]="faHome"></fa-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import {Component, OnDestroy, OnInit} from '@angular/core';
|
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||||
import {Router, RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router';
|
import {Router, RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router';
|
||||||
import {FaIconComponent} from '@fortawesome/angular-fontawesome';
|
import {FaIconComponent} from '@fortawesome/angular-fontawesome';
|
||||||
import {faBars, faBookmark as faBookmarkSolid, faGears} from '@fortawesome/free-solid-svg-icons';
|
import {faBars, faGears} from '@fortawesome/free-solid-svg-icons';
|
||||||
import {MenuService} from './menu-service';
|
import {MenuService} from './menu-service';
|
||||||
import {Location} from './location/Location';
|
import {Location} from './location/Location';
|
||||||
import {LocationService} from './location/location-service';
|
import {LocationService} from './location/location-service';
|
||||||
import {WebsocketService} from './common';
|
import {WebsocketService} from './common';
|
||||||
import {faBookmark as faBookmarkRegular, faHome} from '@fortawesome/free-regular-svg-icons';
|
import {faHome} from '@fortawesome/free-regular-svg-icons';
|
||||||
import {ConfigService} from './config.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -21,10 +20,6 @@ export class App implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
protected readonly location = location;
|
protected readonly location = location;
|
||||||
|
|
||||||
protected readonly faBookmarkRegular = faBookmarkRegular;
|
|
||||||
|
|
||||||
protected readonly faBookmarkSolid = faBookmarkSolid;
|
|
||||||
|
|
||||||
protected readonly faGears = faGears;
|
protected readonly faGears = faGears;
|
||||||
|
|
||||||
protected readonly faBars = faBars;
|
protected readonly faBars = faBars;
|
||||||
@ -35,7 +30,6 @@ export class App implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly locationService: LocationService,
|
readonly locationService: LocationService,
|
||||||
readonly configService: ConfigService,
|
|
||||||
readonly menuService: MenuService,
|
readonly menuService: MenuService,
|
||||||
readonly router: Router,
|
readonly router: Router,
|
||||||
readonly ws: WebsocketService,
|
readonly ws: WebsocketService,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import {Component, Input, ViewChild} from '@angular/core';
|
import {AfterViewInit, Component, Inject, Input, LOCALE_ID, ViewChild} from '@angular/core';
|
||||||
import {Interval} from '../../../series/Interval';
|
import {Interval} from '../../../series/Interval';
|
||||||
import {PointService} from '../../../point/point-service';
|
import {PointService} from '../../../point/point-service';
|
||||||
import {Location} from '../../Location';
|
import {Location} from '../../Location';
|
||||||
@ -7,7 +7,6 @@ import {ChartConfiguration} from 'chart.js';
|
|||||||
import {de} from 'date-fns/locale';
|
import {de} from 'date-fns/locale';
|
||||||
import {PointSeries} from '../../../point/PointSeries';
|
import {PointSeries} from '../../../point/PointSeries';
|
||||||
import {formatNumber} from '@angular/common';
|
import {formatNumber} from '@angular/common';
|
||||||
import {PointResponse} from '../../../point/PointResponse';
|
|
||||||
|
|
||||||
const COLOR_BACK_PURCHASE = "#ffb9b9";
|
const COLOR_BACK_PURCHASE = "#ffb9b9";
|
||||||
const COLOR_BACK_DELIVER = "#ff59ff";
|
const COLOR_BACK_DELIVER = "#ff59ff";
|
||||||
@ -23,7 +22,10 @@ const COLOR_BACK_CONSUME = "#ffc07a";
|
|||||||
templateUrl: './energy-charts.html',
|
templateUrl: './energy-charts.html',
|
||||||
styleUrl: './energy-charts.less',
|
styleUrl: './energy-charts.less',
|
||||||
})
|
})
|
||||||
class EnergyCharts {
|
export class EnergyCharts implements AfterViewInit {
|
||||||
|
|
||||||
|
@ViewChild(BaseChartDirective)
|
||||||
|
chart?: BaseChartDirective;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
unit: string = "";
|
unit: string = "";
|
||||||
@ -37,62 +39,112 @@ class EnergyCharts {
|
|||||||
@Input()
|
@Input()
|
||||||
minY: number | undefined = undefined;
|
minY: number | undefined = undefined;
|
||||||
|
|
||||||
private _offset!: number | null;
|
@Input()
|
||||||
|
interval!: Interval;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
set offset(value: number | null) {
|
location!: Location;
|
||||||
this._offset = value;
|
|
||||||
this.fetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ViewChild(BaseChartDirective)
|
|
||||||
chart?: BaseChartDirective;
|
|
||||||
|
|
||||||
private _interval!: Interval | null;
|
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
set interval(value: Interval | null) {
|
offset: number = 0;
|
||||||
this._interval = value;
|
|
||||||
this.fetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
private _location!: Location | null;
|
protected data: ChartConfiguration['data'] = {
|
||||||
|
datasets: [],
|
||||||
|
};
|
||||||
|
|
||||||
@Input()
|
protected options: ChartConfiguration['options'] = {
|
||||||
set location(value: Location | null) {
|
responsive: true,
|
||||||
this._location = value;
|
maintainAspectRatio: false,
|
||||||
this.fetch();
|
animation: false,
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
type: 'time',
|
||||||
|
time: {
|
||||||
|
displayFormats: {
|
||||||
|
minute: "HH:mm",
|
||||||
|
hour: "HH:mm",
|
||||||
|
day: "dd.MM"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
adapters: {
|
||||||
|
date: {
|
||||||
|
locale: de
|
||||||
|
},
|
||||||
|
},
|
||||||
|
bounds: 'ticks',
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
max: this.maxY,
|
||||||
|
min: this.minY,
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
interaction: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false,
|
||||||
|
itemSort: (a, b) => b.datasetIndex - a.datasetIndex,
|
||||||
|
callbacks: {
|
||||||
|
title: (items) => {
|
||||||
|
const date = new Date(items[0].parsed.x || 0);
|
||||||
|
const d = date.toLocaleString(this.locale, {
|
||||||
|
dateStyle: 'long',
|
||||||
|
});
|
||||||
|
const t = date.toLocaleString(this.locale, {
|
||||||
|
timeStyle: 'long',
|
||||||
|
});
|
||||||
|
return `${d}\n${t}`;
|
||||||
|
},
|
||||||
|
label: ((ctx: any) => {
|
||||||
|
const groups = /^.*Energie (?<name>.+)\[(?<unit>.+)]$/.exec(ctx.dataset.label || '')?.groups;
|
||||||
|
if (groups) {
|
||||||
|
const value = ctx.parsed.y === null ? '-' : formatNumber(Math.abs(ctx.parsed.y), this.locale, '0.2-2');
|
||||||
|
return `${value} ${groups['unit']} ${groups['name']}`;
|
||||||
|
}
|
||||||
|
return ctx.dataset.label;
|
||||||
|
}) as any,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly pointService: PointService,
|
readonly pointService: PointService,
|
||||||
|
@Inject(LOCALE_ID) readonly locale: string,
|
||||||
) {
|
) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch(): void {
|
ngAfterViewInit(): void {
|
||||||
if (!this._location || !this._interval || this._offset == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const series = [
|
const series = [
|
||||||
this._location.energyPurchase,
|
this.location.energyPurchase,
|
||||||
this._location.energyDeliver,
|
this.location.energyDeliver,
|
||||||
this._location.energyProduce,
|
this.location.energyProduce,
|
||||||
];
|
];
|
||||||
const location = this._location;
|
const location = this.location;
|
||||||
const interval = this._interval;
|
const interval = this.interval;
|
||||||
const offset = this._offset;
|
const offset = this.offset;
|
||||||
this.pointService.relative(series, interval, offset, 1, interval.inner, result => {
|
this.pointService.relative(series, interval, offset, 1, interval.inner, result => {
|
||||||
|
this.data.datasets.length = 0;
|
||||||
|
const xScale = this.chart?.chart?.options?.scales?.['x'];
|
||||||
|
if (xScale) {
|
||||||
|
xScale.min = result ? result.begin.getTime() : undefined;
|
||||||
|
xScale.max = result ? result.end.getTime() - (this.interval?.inner?.millis || 0) : undefined;
|
||||||
|
}
|
||||||
const energyPurchase = result.series.filter(s => s.series.id === location.energyPurchase?.id)[0] || null;
|
const energyPurchase = result.series.filter(s => s.series.id === location.energyPurchase?.id)[0] || null;
|
||||||
const energyDeliver = result.series.filter(s => s.series.id === location.energyDeliver?.id)[0] || null;
|
const energyDeliver = result.series.filter(s => s.series.id === location.energyDeliver?.id)[0] || null;
|
||||||
const energyProduce = result.series.filter(s => s.series.id === location.energyProduce?.id)[0] || null;
|
const energyProduce = result.series.filter(s => s.series.id === location.energyProduce?.id)[0] || null;
|
||||||
const energySelf = energyProduce?.merge(energyDeliver, "Energie Selbst", (a, b) => a - b) || null;
|
const energySelf = energyProduce?.merge(energyDeliver, "Energie Selbst", (a, b) => a - b) || null;
|
||||||
this.data.datasets.length = 0;
|
|
||||||
this.add(energyDeliver, COLOR_BACK_DELIVER, -1, "a");
|
this.add(energyDeliver, COLOR_BACK_DELIVER, -1, "a");
|
||||||
this.add(energySelf, COLOR_BACK_SELF, 1, "a");
|
this.add(energySelf, COLOR_BACK_SELF, 1, "a");
|
||||||
this.add(energyPurchase, COLOR_BACK_PURCHASE, 1, "a");
|
this.add(energyPurchase, COLOR_BACK_PURCHASE, 1, "a");
|
||||||
this.options = this.newOptions(result);
|
this.chart?.chart?.update();
|
||||||
this.chart?.update();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,69 +166,4 @@ class EnergyCharts {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected data: ChartConfiguration['data'] = {
|
|
||||||
datasets: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
protected options: ChartConfiguration['options'] = {};
|
|
||||||
|
|
||||||
private newOptions(result: PointResponse): ChartConfiguration['options'] {
|
|
||||||
return {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
animation: false,
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
type: 'time',
|
|
||||||
min: result.begin.getTime(),
|
|
||||||
max: result.end.getTime() - (this._interval?.inner?.millis || 0),
|
|
||||||
time: {
|
|
||||||
displayFormats: {
|
|
||||||
minute: "HH:mm",
|
|
||||||
hour: "HH:mm",
|
|
||||||
day: "dd.MM"
|
|
||||||
},
|
|
||||||
},
|
|
||||||
adapters: {
|
|
||||||
date: {
|
|
||||||
locale: de
|
|
||||||
},
|
|
||||||
},
|
|
||||||
bounds: 'ticks',
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
max: this.maxY,
|
|
||||||
min: this.minY,
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
interaction: {
|
|
||||||
mode: 'index',
|
|
||||||
intersect: false
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
mode: 'index',
|
|
||||||
intersect: false,
|
|
||||||
itemSort: (a, b) => b.datasetIndex - a.datasetIndex,
|
|
||||||
callbacks: {
|
|
||||||
label: (ctx) => {
|
|
||||||
const groups = /^.*Energie (?<name>.+)\[(?<unit>.+)]$/.exec(ctx.dataset.label || '')?.groups;
|
|
||||||
if (groups) {
|
|
||||||
const value = ctx.parsed.y === null ? '-' : formatNumber(Math.abs(ctx.parsed.y), 'de-DE', '0.2-2');
|
|
||||||
return `${value} ${groups['unit']} ${groups['name']}`;
|
|
||||||
}
|
|
||||||
return ctx.dataset.label;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default EnergyCharts
|
|
||||||
|
|||||||
@ -7,14 +7,13 @@ import {PointService} from '../../point/point-service';
|
|||||||
import {SeriesService} from '../../series/series-service';
|
import {SeriesService} from '../../series/series-service';
|
||||||
import {Subscription} from 'rxjs';
|
import {Subscription} from 'rxjs';
|
||||||
import {Value} from '../../series/Value';
|
import {Value} from '../../series/Value';
|
||||||
import EnergyCharts from './charts/energy-charts';
|
|
||||||
import {ConfigService} from '../../config.service';
|
import {ConfigService} from '../../config.service';
|
||||||
|
import {EnergyCharts} from './charts/energy-charts';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-location-energy',
|
selector: 'app-location-energy',
|
||||||
imports: [
|
imports: [
|
||||||
EnergyCharts,
|
EnergyCharts,
|
||||||
EnergyCharts
|
|
||||||
],
|
],
|
||||||
templateUrl: './location-energy.html',
|
templateUrl: './location-energy.html',
|
||||||
styleUrl: './location-energy.less',
|
styleUrl: './location-energy.less',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user