Dashboard electricity layout + body scrollable

This commit is contained in:
Patrick Haßel 2024-10-17 15:14:17 +02:00
parent 21956c0d28
commit 99407a8cdf
8 changed files with 109 additions and 41 deletions

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<svg height="800px" width="800px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 503.607 503.607">
<path style="fill:#FFDD09;" d="M452.246,494.213H49.361c-23.502,0-41.967-18.466-41.967-41.967V49.361
c0-23.502,18.466-41.967,41.967-41.967h402.885c23.502,0,41.967,18.466,41.967,41.967v402.885
C494.213,475.747,475.747,494.213,452.246,494.213"/>
<path style="fill:#FD9808;" d="M452.246,7.393h-25.18c23.502,0,41.967,18.466,41.967,41.967v402.885
c0,23.502-18.466,41.967-41.967,41.967h25.18c23.502,0,41.967-18.466,41.967-41.967V49.361
C494.213,25.859,475.747,7.393,452.246,7.393"/>
<path style="fill:#FFFFFF;" d="M49.361,7.393h25.18c-22.662,0-41.967,18.466-41.967,41.967v402.885
c0,23.502,18.466,41.967,41.967,41.967h-25.18c-23.502,0-41.967-18.466-41.967-41.967V49.361
C7.393,25.859,26.698,7.393,49.361,7.393"/>
<path style="fill:#FCC309;" d="M443.852,250.803c0-106.597-86.452-193.049-193.049-193.049S57.754,144.207,57.754,250.803
s86.452,193.049,193.049,193.049S443.852,357.4,443.852,250.803"/>
<path style="fill:#FD9808;" d="M250.803,57.754c-4.197,0-8.393,0-12.59,0.839c100.721,5.875,180.459,89.81,180.459,192.21
s-79.738,186.334-180.459,192.21c4.197,0,8.393,0.839,12.59,0.839c106.597,0,193.049-86.452,193.049-193.049
S357.4,57.754,250.803,57.754"/>
<path style="fill:#FFDD09;" d="M326.344,208.836h-67.148l58.754-92.328h-67.148l-75.541,134.295h55.397l-55.397,134.295
L326.344,208.836z"/>
<path d="M175.262,393.492c-1.679,0-3.357,0-4.197-0.839c-3.357-2.518-5.036-6.715-3.357-10.072l51.2-123.384h-43.646
c-3.357,0-5.875-1.679-7.554-4.197s-1.679-5.875,0-8.393l75.541-134.295c1.679-2.518,4.197-4.197,7.554-4.197h67.148
c3.357,0,5.875,1.679,7.554,4.197s1.679,5.875,0,8.393l-50.361,79.738h51.2c3.357,0,5.875,1.679,7.554,5.036
c1.679,3.357,0.839,6.715-0.839,9.233L181.977,390.974C180.298,392.652,177.78,393.492,175.262,393.492z M189.531,242.41h41.128
c2.518,0,5.036,1.679,6.715,3.357c1.679,2.518,1.679,5.036,0.839,7.554l-35.252,85.613l104.918-121.705h-48.682
c-3.357,0-5.875-1.679-7.554-4.197c-1.679-2.518-1.679-5.875,0-8.393l50.361-79.738H255L189.531,242.41z"/>
<path d="M452.246,502.607H49.361C21.662,502.607-1,479.944-1,452.246V49.361C-1,21.662,21.662-1,49.361-1h402.885
c27.698,0,50.361,22.662,50.361,50.361v402.885C502.607,479.944,479.944,502.607,452.246,502.607z M49.361,15.787
c-18.466,0-33.574,15.108-33.574,33.574v402.885c0,18.466,15.108,33.574,33.574,33.574h402.885
c18.466,0,33.574-15.108,33.574-33.574V49.361c0-18.466-15.108-33.574-33.574-33.574H49.361z"/>
<path d="M250.803,452.246c-110.793,0-201.443-90.649-201.443-201.443S140.01,49.361,250.803,49.361s201.443,90.649,201.443,201.443
S361.597,452.246,250.803,452.246z M250.803,66.148c-101.561,0-184.656,83.095-184.656,184.656s83.095,184.656,184.656,184.656
s184.656-83.095,184.656-184.656S352.364,66.148,250.803,66.148z"/>
<path d="M66.148,49.361c0-9.233-7.554-16.787-16.787-16.787s-16.787,7.554-16.787,16.787s7.554,16.787,16.787,16.787
S66.148,58.593,66.148,49.361"/>
<path d="M66.148,452.246c0-9.233-7.554-16.787-16.787-16.787s-16.787,7.554-16.787,16.787c0,9.233,7.554,16.787,16.787,16.787
S66.148,461.479,66.148,452.246"/>
<path d="M469.033,49.361c0-9.233-7.554-16.787-16.787-16.787c-9.233,0-16.787,7.554-16.787,16.787s7.554,16.787,16.787,16.787
C461.479,66.148,469.033,58.593,469.033,49.361"/>
<path d="M469.033,452.246c0-9.233-7.554-16.787-16.787-16.787c-9.233,0-16.787,7.554-16.787,16.787
c0,9.233,7.554,16.787,16.787,16.787C461.479,469.033,469.033,461.479,469.033,452.246"/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -19,3 +19,5 @@ export interface IValue {
readonly unit: string | null; readonly unit: string | null;
} }
export type DisplayOrSeparator = Display | null;

View File

@ -1,3 +1,3 @@
<div class="width100"> <div class="width100">
<app-values-tile title="Elektrizität" [seriesList]="getElectricitySeries()"></app-values-tile> <app-values-tile title="Elektrizität" icon="electricity.svg" [seriesList]="getElectricitySeries()"></app-values-tile>
</div> </div>

View File

@ -4,7 +4,7 @@ import {Series} from "../../api/series/Series";
import {SeriesService} from "../../api/series/series.service"; import {SeriesService} from "../../api/series/series.service";
import {ValuesTileComponent} from "../../shared/values-tile/values-tile.component"; import {ValuesTileComponent} from "../../shared/values-tile/values-tile.component";
import {Value} from "../../api/series/Value"; import {Value} from "../../api/series/Value";
import {Display} from "../../api/series/IValue"; import {Display, DisplayOrSeparator} from "../../api/series/IValue";
const PURCHASING_MUCH = 200; const PURCHASING_MUCH = 200;
@ -63,7 +63,7 @@ export class DashboardComponent implements OnInit {
return old; return old;
} }
getElectricitySeries(): Display[] { getElectricitySeries(): DisplayOrSeparator[] {
const consumptionPower = Value.positiveOnly(Value.plus(this.photovoltaicPower, this.gridPower)); const consumptionPower = Value.positiveOnly(Value.plus(this.photovoltaicPower, this.gridPower));
const selfConsumed = Value.map(this.photovoltaicProduced, producedTotal => { const selfConsumed = Value.map(this.photovoltaicProduced, producedTotal => {
const producedAfterChange = producedTotal - PRODUCED_UNTIL_METER_CHANGE; const producedAfterChange = producedTotal - PRODUCED_UNTIL_METER_CHANGE;
@ -79,10 +79,11 @@ export class DashboardComponent implements OnInit {
return [ return [
new Display('Bezug', '', this.gridPurchased), new Display('Bezug', '', this.gridPurchased),
new Display('Produktion', '', this.photovoltaicProduced),
new Display('Einspeisung', '', this.gridDelivered), new Display('Einspeisung', '', this.gridDelivered),
new Display('Eigenverbrauch', '', selfConsumed), null,
new Display('Produktion', '#006600', this.photovoltaicProduced),
new Display('Eigenverbrauch', '#006600', selfConsumed),
null,
new Display('Produktion', color, this.photovoltaicPower), new Display('Produktion', color, this.photovoltaicPower),
new Display('Netz', color, this.gridPower), new Display('Netz', color, this.gridPower),
new Display('Verbrauch', color, consumptionPower), new Display('Verbrauch', color, consumptionPower),

View File

@ -1,11 +1,19 @@
<div class="meter" [class.invalid]="!valid"> <div class="meter" [class.invalid]="!valid">
<div class="title">{{ title }}</div> <div class="title">
<img [src]="icon" alt="" *ngIf="icon">
{{ title }}
</div>
<div class="number">{{ number() }}</div> <div class="number">{{ number() }}</div>
<table class="values"> <table class="values">
<tr class="rate" *ngFor="let display of seriesList" [style.color]="display.color"> <ng-container *ngFor="let display of seriesList">
<tr class="rate" *ngIf="display" [style.color]="display.color">
<th>{{ display.title }}</th> <th>{{ display.title }}</th>
<td class="v">{{ display?.iValue?.value | number:'0.0-0' }}</td> <td class="v">{{ display?.iValue?.value | number:'0.0-0' }}</td>
<td class="u">{{ display?.iValue?.unit }}</td> <td class="u">{{ display?.iValue?.unit }}</td>
</tr> </tr>
<tr *ngIf="!display" class="spacer">
<td colspan="3"></td>
</tr>
</ng-container>
</table> </table>
</div> </div>

View File

@ -5,20 +5,25 @@
padding: @space; padding: @space;
border: 1px solid #ddd; border: 1px solid #ddd;
border-radius: @space; border-radius: @space;
} background-color: #fbfbfb;
.title { .title {
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
}
.number { img {
height: 1.5em;
vertical-align: top;
}
}
.number {
font-style: italic; font-style: italic;
text-align: center; text-align: center;
font-size: 80%; font-size: 80%;
} }
.values { .values {
width: 100%; width: 100%;
th { th {
@ -35,4 +40,11 @@
width: 0; width: 0;
} }
.spacer {
height: 1px;
background-color: lightgray;
}
}
} }

View File

@ -2,9 +2,11 @@ import {Component, Input, OnDestroy, OnInit} from '@angular/core';
import {Series} from "../../api/series/Series"; import {Series} from "../../api/series/Series";
import {DecimalPipe, NgForOf, NgIf} from "@angular/common"; import {DecimalPipe, NgForOf, NgIf} from "@angular/common";
import {Subscription, timer} from "rxjs"; import {Subscription, timer} from "rxjs";
import {Display} from "../../api/series/IValue"; import {DisplayOrSeparator} from "../../api/series/IValue";
export const TOO_OLD_MILLIS = 10000; const UPDATE_INTERVAL_MILLIS = 5000;
const TOO_OLD_MILLIS = 10000;
@Component({ @Component({
selector: 'app-values-tile', selector: 'app-values-tile',
@ -29,15 +31,18 @@ export class ValuesTileComponent implements OnInit, OnDestroy {
title: string = ''; title: string = '';
@Input() @Input()
protected seriesList_: Display[] = []; icon?: string;
@Input() @Input()
set seriesList(seriesList: Display[]) { protected seriesList_: DisplayOrSeparator[] = [];
@Input()
set seriesList(seriesList: DisplayOrSeparator[]) {
this.seriesList_ = seriesList; this.seriesList_ = seriesList;
this.displayUpdate(); this.displayUpdate();
} }
get seriesList(): Display[] { get seriesList(): DisplayOrSeparator[] {
return this.seriesList_; return this.seriesList_;
} }
@ -89,7 +94,7 @@ export class ValuesTileComponent implements OnInit, OnDestroy {
} }
ngOnInit(): void { ngOnInit(): void {
this.timer = timer(0, 1000).subscribe(() => this.displayUpdate()); this.timer = timer(0, UPDATE_INTERVAL_MILLIS).subscribe(() => this.displayUpdate());
} }
ngOnDestroy(): void { ngOnDestroy(): void {

View File

@ -4,7 +4,7 @@ body {
font-family: sans-serif; font-family: sans-serif;
font-size: @font; font-size: @font;
margin: 0; margin: 0;
overflow: hidden; overflow-x: hidden;
} }
div { div {