Compare commits
3 Commits
04be7692c1
...
4feb38c14c
| Author | SHA1 | Date | |
|---|---|---|---|
| 4feb38c14c | |||
| 810dc77b24 | |||
| bec1ee0c28 |
@ -4,6 +4,20 @@ import {Value} from '../series/Value';
|
|||||||
|
|
||||||
export class Location {
|
export class Location {
|
||||||
|
|
||||||
|
powerSelf: Value = Value.NULL;
|
||||||
|
|
||||||
|
powerPurchasePercentConsume: Value = Value.NULL;
|
||||||
|
|
||||||
|
powerProducePercentConsume: Value = Value.NULL;
|
||||||
|
|
||||||
|
powerDeliveryPercentConsume: Value = Value.NULL;
|
||||||
|
|
||||||
|
powerDeliveryPercentProduce: Value = Value.NULL;
|
||||||
|
|
||||||
|
powerSelfPercentConsume: Value = Value.NULL;
|
||||||
|
|
||||||
|
powerSelfPercentProduce: Value = Value.NULL;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly id: number,
|
readonly id: number,
|
||||||
readonly name: string,
|
readonly name: string,
|
||||||
@ -46,6 +60,13 @@ export class Location {
|
|||||||
|
|
||||||
private updateConsume() {
|
private updateConsume() {
|
||||||
this._powerConsume = Value.ZERO.plus(this._powerPurchase?.value, true).plus(this._powerProduce?.value, true).minus(this._powerDeliver?.value, true);
|
this._powerConsume = Value.ZERO.plus(this._powerPurchase?.value, true).plus(this._powerProduce?.value, true).minus(this._powerDeliver?.value, true);
|
||||||
|
this.powerSelf = Value.ZERO.plus(this.powerProduce?.value.minus(this.powerDeliver?.value, true), true);
|
||||||
|
this.powerPurchasePercentConsume = Value.ZERO.plus(this.powerPurchase?.value.percent(this.powerConsume, "%", 0), true);
|
||||||
|
this.powerProducePercentConsume = Value.ZERO.plus(this.powerProduce?.value.percent(this.powerConsume, "%", 0), true);
|
||||||
|
this.powerDeliveryPercentConsume = Value.ZERO.plus(this.powerDeliver?.value.percent(this.powerConsume, "%", 0), true);
|
||||||
|
this.powerDeliveryPercentProduce = Value.ZERO.plus(this.powerDeliver?.value.percent(this.powerProduce?.value, "%", 0), true);
|
||||||
|
this.powerSelfPercentConsume = Value.ZERO.plus(this.powerSelf.percent(this.powerConsume, "%", 0), true);
|
||||||
|
this.powerSelfPercentProduce = Value.ZERO.plus(this.powerSelf.percent(this.powerProduce?.value, "%", 0), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(json: any): Location {
|
static fromJson(json: any): Location {
|
||||||
|
|||||||
@ -2,21 +2,32 @@
|
|||||||
|
|
||||||
<app-location-power [location]="location"></app-location-power>
|
<app-location-power [location]="location"></app-location-power>
|
||||||
|
|
||||||
<app-location-energy [location]="location" [interval]="Interval.DAY" heading="Heute"></app-location-energy>
|
<app-location-energy [location]="location" [interval]="Interval.DAY" [offset]="offsetDay">
|
||||||
|
|
||||||
<app-location-energy [location]="location" [interval]="Interval.DAY" [offset]="offset">
|
|
||||||
<ng-content #SeriesHistoryHeading>
|
<ng-content #SeriesHistoryHeading>
|
||||||
<div style="display: flex; width: 100%">
|
<div style="display: flex; width: 100%">
|
||||||
|
|
||||||
<div (click)="offset += 1">←</div>
|
<div (click)="offsetDay += 1">←</div>
|
||||||
|
|
||||||
<div (click)="offset = Math.max(1, offset -1)">→</div>
|
<div (click)="offsetDay = Math.max(0, offsetDay -1)">→</div>
|
||||||
|
|
||||||
<div style="flex: 1">{{ offsetDayTitle() }}</div>
|
<div style="flex: 1">{{ offsetDayTitle() }}</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-content>
|
</ng-content>
|
||||||
</app-location-energy>
|
</app-location-energy>
|
||||||
|
|
||||||
|
<app-location-energy [location]="location" [interval]="Interval.MONTH" [offset]="offsetMonth">
|
||||||
|
<ng-content #SeriesHistoryHeading>
|
||||||
|
<div style="display: flex; width: 100%">
|
||||||
|
|
||||||
|
<div (click)="offsetMonth += 1">←</div>
|
||||||
|
|
||||||
|
<div (click)="offsetMonth = Math.max(0, offsetMonth -1)">→</div>
|
||||||
|
|
||||||
|
<div style="flex: 1">{{ offsetMonthTitle() }}</div>
|
||||||
|
</div>
|
||||||
|
</ng-content>
|
||||||
|
</app-location-energy>
|
||||||
|
|
||||||
<div class="Section">
|
<div class="Section">
|
||||||
<div class="SectionHeading">
|
<div class="SectionHeading">
|
||||||
<div class="SectionHeadingText">
|
<div class="SectionHeadingText">
|
||||||
|
|||||||
@ -41,7 +41,9 @@ export class LocationDetail implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
private readonly subs: Subscription [] = [];
|
private readonly subs: Subscription [] = [];
|
||||||
|
|
||||||
protected offset: number = 1;
|
protected offsetDay: number = 0;
|
||||||
|
|
||||||
|
protected offsetMonth: number = 0;
|
||||||
|
|
||||||
private readonly datePipe: DatePipe;
|
private readonly datePipe: DatePipe;
|
||||||
|
|
||||||
@ -76,16 +78,21 @@ export class LocationDetail implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected offsetDayTitle(): string {
|
protected offsetDayTitle(): string {
|
||||||
if (this.offset === 1) {
|
if (this.offsetDay === 0) {
|
||||||
|
return 'Heute';
|
||||||
|
} else if (this.offsetDay === 1) {
|
||||||
return 'Gestern';
|
return 'Gestern';
|
||||||
} else {
|
} else {
|
||||||
if (this.offset < 7) {
|
|
||||||
const d = new Date(this.dateService.now);
|
const d = new Date(this.dateService.now);
|
||||||
d.setDate(d.getDate() - this.offset);
|
d.setDate(d.getDate() - this.offsetDay);
|
||||||
return this.datePipe.transform(d, 'EEEE') || '';
|
return this.datePipe.transform(d, 'dd.MM.yyyy EEEE') || '';
|
||||||
}
|
|
||||||
return `Vor ${this.offset} Tagen`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected offsetMonthTitle(): string {
|
||||||
|
const d = new Date(this.dateService.now);
|
||||||
|
d.setMonth(d.getMonth() - this.offsetMonth);
|
||||||
|
return this.datePipe.transform(d, 'yyyy MMMM') || '';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,10 @@
|
|||||||
<div class="SectionBody COLOR_FONT_PURCHASE">
|
<div class="SectionBody COLOR_FONT_PURCHASE">
|
||||||
{{ purchase.toValueString(null) }}
|
{{ purchase.toValueString(null) }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_PURCHASE percent">
|
||||||
|
{{ purchasePercentConsume.toValueString(null) }}
|
||||||
|
<sub class="subscript">Verbrauch</sub>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="Section4">
|
<div class="Section4">
|
||||||
@ -23,6 +27,27 @@
|
|||||||
<div class="SectionBody COLOR_FONT_PRODUCE">
|
<div class="SectionBody COLOR_FONT_PRODUCE">
|
||||||
{{ produce.toValueString(null) }}
|
{{ produce.toValueString(null) }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_PRODUCE percent">
|
||||||
|
{{ producePercentConsume.toValueString(null) }}
|
||||||
|
<sub class="subscript">Verbrauch</sub>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Section4">
|
||||||
|
<div class="SectionHeadingText">
|
||||||
|
Selbst
|
||||||
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_SELF">
|
||||||
|
{{ self.toValueString(null) }}
|
||||||
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_SELF percent">
|
||||||
|
{{ selfPercentConsume.toValueString(null) }}
|
||||||
|
<sub class="subscript">Verbrauch</sub>
|
||||||
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_SELF percent">
|
||||||
|
{{ selfPercentProduce.toValueString(null) }}
|
||||||
|
<sub class="subscript">Produktion</sub>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="Section4">
|
<div class="Section4">
|
||||||
@ -41,6 +66,14 @@
|
|||||||
<div class="SectionBody COLOR_FONT_DELIVER">
|
<div class="SectionBody COLOR_FONT_DELIVER">
|
||||||
{{ deliver.toValueString(null) }}
|
{{ deliver.toValueString(null) }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_DELIVER percent">
|
||||||
|
{{ deliveryPercentConsume.toValueString(null) }}
|
||||||
|
<sub class="subscript">Verbrauch</sub>
|
||||||
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_DELIVER percent">
|
||||||
|
{{ deliveryPercentProduce.toValueString(null) }}
|
||||||
|
<sub class="subscript">Produktion</sub>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -31,6 +31,20 @@ export class LocationEnergy implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
|
|
||||||
protected consume: Value = Value.NULL;
|
protected consume: Value = Value.NULL;
|
||||||
|
|
||||||
|
protected self: Value = Value.NULL;
|
||||||
|
|
||||||
|
protected purchasePercentConsume: Value = Value.NULL;
|
||||||
|
|
||||||
|
protected producePercentConsume: Value = Value.NULL;
|
||||||
|
|
||||||
|
protected deliveryPercentConsume: Value = Value.NULL;
|
||||||
|
|
||||||
|
protected deliveryPercentProduce: Value = Value.NULL;
|
||||||
|
|
||||||
|
protected selfPercentConsume: Value = Value.NULL;
|
||||||
|
|
||||||
|
protected selfPercentProduce: Value = Value.NULL;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
heading!: string;
|
heading!: string;
|
||||||
|
|
||||||
@ -89,6 +103,13 @@ export class LocationEnergy implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
const callNextAndUpdateConsume = (value: Value) => {
|
const callNextAndUpdateConsume = (value: Value) => {
|
||||||
next(value);
|
next(value);
|
||||||
this.consume = this.purchase.plus(this.produce, true).minus(this.deliver, true);
|
this.consume = this.purchase.plus(this.produce, true).minus(this.deliver, true);
|
||||||
|
this.self = this.produce.minus(this.deliver, true);
|
||||||
|
this.purchasePercentConsume = this.purchase.percent(this.consume, "%", 0);
|
||||||
|
this.producePercentConsume = this.produce.percent(this.consume, "%", 0);
|
||||||
|
this.deliveryPercentConsume = this.deliver.percent(this.consume, "%", 0);
|
||||||
|
this.deliveryPercentProduce = this.deliver.percent(this.produce, "%", 0);
|
||||||
|
this.selfPercentConsume = this.self.percent(this.consume, "%", 0);
|
||||||
|
this.selfPercentProduce = this.self.percent(this.produce, "%", 0);
|
||||||
};
|
};
|
||||||
if (fresh !== null && fresh !== undefined) {
|
if (fresh !== null && fresh !== undefined) {
|
||||||
if (fresh.id !== series?.id) {
|
if (fresh.id !== series?.id) {
|
||||||
|
|||||||
@ -2,6 +2,8 @@ export class EnergyPoint {
|
|||||||
|
|
||||||
readonly epochSeconds: number;
|
readonly epochSeconds: number;
|
||||||
|
|
||||||
|
readonly date: Date;
|
||||||
|
|
||||||
private _purchase: number | null = null;
|
private _purchase: number | null = null;
|
||||||
|
|
||||||
private _produce: number | null = null;
|
private _produce: number | null = null;
|
||||||
@ -51,6 +53,7 @@ export class EnergyPoint {
|
|||||||
point: number[],
|
point: number[],
|
||||||
) {
|
) {
|
||||||
this.epochSeconds = point[0];
|
this.epochSeconds = point[0];
|
||||||
|
this.date = new Date(this.epochSeconds * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
set deliver(value: number | null) {
|
set deliver(value: number | null) {
|
||||||
|
|||||||
@ -1,33 +1,42 @@
|
|||||||
<svg [attr.viewBox]="`0 0 ${widthPx} ${heightPx}`" [style.background-color]="'#eee'">
|
<svg [attr.viewBox]="`0 0 ${widthPx} ${heightPx+1}`" [style.background-color]="'#eee'">
|
||||||
@for (point of points; track point.epochSeconds) {
|
@for (point of points; track point.epochSeconds) {
|
||||||
|
<g>
|
||||||
|
<title>
|
||||||
|
Bezug: {{ location.energyPurchase?.toValue(point.purchase, point.date)?.toValueString(null) }}
|
||||||
|
Solar: {{ location.energyProduce?.toValue(point.produce, point.date)?.toValueString(null) }}
|
||||||
|
Selbst: {{ location.energyPurchase?.toValue(point.self, point.date)?.toValueString(null) }}
|
||||||
|
Einsp.: {{ location.energyDeliver?.toValue(point.deliver, point.date)?.toValueString(null) }}
|
||||||
|
Verbrauch: {{ location.energyPurchase?.toValue(point.consume, point.date)?.toValueString(null) }}
|
||||||
|
</title>
|
||||||
<rect
|
<rect
|
||||||
[attr.x]="(point.epochSeconds - xMin) * xFactor"
|
[attr.x]="(point.epochSeconds - xMin) * xFactor"
|
||||||
[attr.y]="heightPx - 1 + yMinPx - point.getPurchaseY(yFactor)"
|
[attr.y]="heightPx + yMinPx - point.getPurchaseY(yFactor)"
|
||||||
[attr.width]="xWidthPx"
|
[attr.width]="xWidthPx"
|
||||||
[attr.height]="point.getPurchaseH(yFactor)"
|
[attr.height]="point.getPurchaseH(yFactor)"
|
||||||
class="COLOR_BACK_PURCHASE"
|
class="COLOR_BACK_PURCHASE"
|
||||||
></rect>
|
></rect>
|
||||||
<rect
|
<rect
|
||||||
[attr.x]="(point.epochSeconds - xMin) * xFactor"
|
[attr.x]="(point.epochSeconds - xMin) * xFactor"
|
||||||
[attr.y]="heightPx - 1 + yMinPx - point.getSelfY(yFactor)"
|
[attr.y]="heightPx + yMinPx - point.getSelfY(yFactor)"
|
||||||
[attr.width]="xWidthPx"
|
[attr.width]="xWidthPx"
|
||||||
[attr.height]="point.getSelfH(yFactor)"
|
[attr.height]="point.getSelfH(yFactor)"
|
||||||
class="COLOR_BACK_SELF"
|
class="COLOR_BACK_SELF"
|
||||||
></rect>
|
></rect>
|
||||||
<rect
|
<rect
|
||||||
[attr.x]="(point.epochSeconds - xMin) * xFactor"
|
[attr.x]="(point.epochSeconds - xMin) * xFactor"
|
||||||
[attr.y]="heightPx + yMinPx"
|
[attr.y]="heightPx+1 + yMinPx"
|
||||||
[attr.width]="xWidthPx"
|
[attr.width]="xWidthPx"
|
||||||
[attr.height]="point.getDeliverH(yFactor)"
|
[attr.height]="point.getDeliverH(yFactor)"
|
||||||
class="COLOR_BACK_DELIVER"
|
class="COLOR_BACK_DELIVER"
|
||||||
></rect>
|
></rect>
|
||||||
|
</g>
|
||||||
|
}
|
||||||
<line
|
<line
|
||||||
x1="0"
|
x1="0"
|
||||||
[attr.y1]="heightPx - 1 + yMinPx"
|
[attr.y1]="heightPx +0.5 + yMinPx"
|
||||||
[attr.x2]="widthPx"
|
[attr.x2]="widthPx"
|
||||||
[attr.y2]="heightPx - 1 + yMinPx"
|
[attr.y2]="heightPx +0.5 + yMinPx"
|
||||||
stroke="#aaaaaa"
|
stroke="#aaaaaa"
|
||||||
stroke-width="1"
|
stroke-width="1"
|
||||||
></line>
|
></line>
|
||||||
}
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.6 KiB |
@ -1 +1,5 @@
|
|||||||
@import "../../../../colors";
|
@import "../../../../colors";
|
||||||
|
|
||||||
|
g:hover {
|
||||||
|
stroke: black;
|
||||||
|
}
|
||||||
|
|||||||
@ -126,6 +126,10 @@ export class EnergyPlot implements OnInit, OnDestroy, AfterViewInit {
|
|||||||
this.ngAfterViewInit();
|
this.ngAfterViewInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get location(): Location {
|
||||||
|
return this._location;
|
||||||
|
}
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
set interval(value: Interval) {
|
set interval(value: Interval) {
|
||||||
this._interval = value;
|
this._interval = value;
|
||||||
|
|||||||
@ -13,6 +13,10 @@
|
|||||||
<div class="SectionBody COLOR_FONT_PURCHASE">
|
<div class="SectionBody COLOR_FONT_PURCHASE">
|
||||||
{{ location.powerPurchase?.value?.toValueString(dateService.now) }}
|
{{ location.powerPurchase?.value?.toValueString(dateService.now) }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_PURCHASE percent">
|
||||||
|
{{ location.powerPurchasePercentConsume.toValueString(dateService.now) }}
|
||||||
|
<sub class="subscript">Verbrauch</sub>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="Section4">
|
<div class="Section4">
|
||||||
@ -22,6 +26,27 @@
|
|||||||
<div class="SectionBody COLOR_FONT_PRODUCE">
|
<div class="SectionBody COLOR_FONT_PRODUCE">
|
||||||
{{ location.powerProduce?.value?.toValueString(dateService.now) }}
|
{{ location.powerProduce?.value?.toValueString(dateService.now) }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_PRODUCE percent">
|
||||||
|
{{ location.powerProducePercentConsume.toValueString(dateService.now) }}
|
||||||
|
<sub class="subscript">Verbrauch</sub>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Section4">
|
||||||
|
<div class="SectionHeadingText">
|
||||||
|
Selbst
|
||||||
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_SELF">
|
||||||
|
{{ location.powerSelf?.toValueString(dateService.now) }}
|
||||||
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_SELF percent">
|
||||||
|
{{ location.powerSelfPercentConsume.toValueString(dateService.now) }}
|
||||||
|
<sub class="subscript">Verbrauch</sub>
|
||||||
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_SELF percent">
|
||||||
|
{{ location.powerSelfPercentProduce.toValueString(dateService.now) }}
|
||||||
|
<sub class="subscript">Produktion</sub>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="Section4">
|
<div class="Section4">
|
||||||
@ -40,6 +65,14 @@
|
|||||||
<div class="SectionBody COLOR_FONT_DELIVER">
|
<div class="SectionBody COLOR_FONT_DELIVER">
|
||||||
{{ location.powerDeliver?.value?.toValueString(dateService.now) }}
|
{{ location.powerDeliver?.value?.toValueString(dateService.now) }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_DELIVER percent">
|
||||||
|
{{ location.powerDeliveryPercentConsume.toValueString(dateService.now) }}
|
||||||
|
<sub class="subscript">Verbrauch</sub>
|
||||||
|
</div>
|
||||||
|
<div class="SectionBody COLOR_FONT_DELIVER percent">
|
||||||
|
{{ location.powerDeliveryPercentProduce.toValueString(dateService.now) }}
|
||||||
|
<sub class="subscript">Produktion</sub>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export class Interval {
|
|||||||
|
|
||||||
static readonly WEEK = new Interval('WEEK', this.HOUR);
|
static readonly WEEK = new Interval('WEEK', this.HOUR);
|
||||||
|
|
||||||
static readonly MONTH = new Interval('MONTH', this.HOUR);
|
static readonly MONTH = new Interval('MONTH', this.DAY);
|
||||||
|
|
||||||
static readonly YEAR = new Interval('YEAR', this.DAY);
|
static readonly YEAR = new Interval('YEAR', this.DAY);
|
||||||
|
|
||||||
|
|||||||
@ -37,4 +37,11 @@ export class Series {
|
|||||||
return this.id === other?.id;
|
return this.id === other?.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toValue(value: number | null | undefined, date: Date | null | undefined): Value {
|
||||||
|
if (value === null || value === undefined || date === null || date === undefined) {
|
||||||
|
return Value.NULL;
|
||||||
|
}
|
||||||
|
return Value.of(this, value, date);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,11 +83,11 @@ export class Value {
|
|||||||
return ageSeconds > this.seconds * 2.1;
|
return ageSeconds > this.seconds * 2.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
onlyPositive(): Value {
|
percent(other: Value | null | undefined, unit: string | null = null, precision: number | null = null): Value {
|
||||||
if (this.value < 0) {
|
if (other === null || other === undefined) {
|
||||||
return Value.ZERO;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
return this;
|
return new BiValue(this, other, (a, b) => a / b * 100, unit, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -98,12 +98,18 @@ export class BiValue extends Value {
|
|||||||
readonly a: Value,
|
readonly a: Value,
|
||||||
readonly b: Value,
|
readonly b: Value,
|
||||||
readonly operation: (a: number, b: number) => number,
|
readonly operation: (a: number, b: number) => number,
|
||||||
|
unit: string | null = null,
|
||||||
|
precision: number | null = null,
|
||||||
) {
|
) {
|
||||||
if (a.unit !== "" && b.unit !== "" && a.unit !== b.unit) {
|
if (a.unit !== "" && b.unit !== "" && a.unit !== b.unit) {
|
||||||
throw new Error(`Operation needs units to be equal or empty: this=${a}, other=${b}`);
|
throw new Error(`Operation needs units to be equal or empty: this=${a}, other=${b}`);
|
||||||
}
|
}
|
||||||
const precision = Math.max(a.precision, b.precision);
|
if (precision === null) {
|
||||||
const unit = a.unit || b.unit;
|
precision = Math.max(a.precision, b.precision);
|
||||||
|
}
|
||||||
|
if (unit === null) {
|
||||||
|
unit = a.unit || b.unit;
|
||||||
|
}
|
||||||
const date = a.date.getTime() < b.date.getTime() ? a.date : b.date;
|
const date = a.date.getTime() < b.date.getTime() ? a.date : b.date;
|
||||||
super(operation(a.value, b.value), precision, 0, unit, date);
|
super(operation(a.value, b.value), precision, 0, unit, date);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
@COLOR_FONT_PURCHASE: red;
|
@COLOR_FONT_PURCHASE: red;
|
||||||
@COLOR_FONT_DELIVER: magenta;
|
@COLOR_FONT_DELIVER: magenta;
|
||||||
@COLOR_FONT_PRODUCE: #0095ff;
|
@COLOR_FONT_PRODUCE: #0095ff;
|
||||||
@COLOR_FONT_SELF: #0095ff;
|
@COLOR_FONT_SELF: #00b34a;
|
||||||
@COLOR_FONT_CONSUME: #ff8800;
|
@COLOR_FONT_CONSUME: #ff8800;
|
||||||
|
|
||||||
@COLOR_BACK_PURCHASE: #ffa7a7;
|
@COLOR_BACK_PURCHASE: #ffa7a7;
|
||||||
@ -28,6 +28,10 @@
|
|||||||
color: @COLOR_FONT_SELF;
|
color: @COLOR_FONT_SELF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.COLOR_FONT_SELF {
|
||||||
|
color: @COLOR_FONT_SELF;
|
||||||
|
}
|
||||||
|
|
||||||
.COLOR_FONT_CONSUME {
|
.COLOR_FONT_CONSUME {
|
||||||
color: @COLOR_FONT_CONSUME;
|
color: @COLOR_FONT_CONSUME;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ body {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
font-size: 4vw;
|
font-size: 3.5vw;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,3 +99,11 @@ div {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.percent {
|
||||||
|
font-size: 70%;
|
||||||
|
|
||||||
|
.subscript {
|
||||||
|
font-size: 60%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user