diff --git a/src/main/angular/src/app/core/api.service.ts b/src/main/angular/src/app/core/api.service.ts
index 49ff931..b6d864a 100644
--- a/src/main/angular/src/app/core/api.service.ts
+++ b/src/main/angular/src/app/core/api.service.ts
@@ -4,7 +4,7 @@ import {map, Subscription} from 'rxjs';
import {StompService} from '@stomp/ng2-stompjs';
import {FromJson, Next} from './types';
-const DEV_TO_PROD = true;
+const DEV_TO_PROD = false;
@Injectable({
providedIn: 'root'
diff --git a/src/main/angular/src/app/value/Value.ts b/src/main/angular/src/app/value/Value.ts
index c3f1bc6..7b54892 100644
--- a/src/main/angular/src/app/value/Value.ts
+++ b/src/main/angular/src/app/value/Value.ts
@@ -53,18 +53,44 @@ export class Value {
return new Value(-this.value, this.unit, this.decimals, this.locale);
}
- plus(other: Value | undefined): Value | undefined {
- if (!other) {
- return undefined;
- }
- return new Value(this.value + other.value, this.unit, this.decimals, this.locale);
+ plus(other: Value | number | undefined | null): Value | undefined {
+ const v = this.extractValue(other);
+ return v === undefined ? undefined : new Value(this.value + v, this.unit, this.decimals, this.locale);
}
- minus(other: Value | undefined): Value | undefined {
- if (!other) {
+ minus(other: Value | number | undefined | null): Value | undefined {
+ const v = this.extractValue(other);
+ return v === undefined ? undefined : new Value(this.value - v, this.unit, this.decimals, this.locale);
+ }
+
+ gte(other: Value | number | undefined | null): boolean | undefined {
+ const v = this.extractValue(other);
+ return v === undefined ? undefined : this.value >= v;
+ }
+
+ gt(other: Value | number | undefined | null): boolean | undefined {
+ const v = this.extractValue(other);
+ return v === undefined ? undefined : this.value > v;
+ }
+
+ lte(other: Value | number | undefined | null): boolean | undefined {
+ const v = this.extractValue(other);
+ return v === undefined ? undefined : this.value <= v;
+ }
+
+ lt(other: Value | number | undefined | null): boolean | undefined {
+ const v = this.extractValue(other);
+ return v === undefined ? undefined : this.value < v;
+ }
+
+ extractValue(other: Value | number | undefined | null): number | undefined {
+ if (other === undefined || other === null) {
return undefined;
}
- return new Value(this.value - other.value, this.unit, this.decimals, this.locale);
+ if (other instanceof Value && other.unit !== this.unit) {
+ throw new Error(`Unit mismatch: this=${JSON.stringify(this)}, other=${JSON.stringify(other)}`);
+ }
+ return typeof other === "number" ? other : other.value;
}
notNegative(): Value {
diff --git a/src/main/angular/src/app/weather/weather-diagram/WeatherHour.ts b/src/main/angular/src/app/weather/weather-diagram/WeatherHour.ts
index 874a12f..488f897 100644
--- a/src/main/angular/src/app/weather/weather-diagram/WeatherHour.ts
+++ b/src/main/angular/src/app/weather/weather-diagram/WeatherHour.ts
@@ -8,6 +8,7 @@ export class WeatherHour {
readonly clouds: Value,
readonly irradiation: Value,
readonly precipitation: Value,
+ readonly temperature: Value,
) {
//
}
@@ -18,6 +19,7 @@ export class WeatherHour {
Value.fromJson2(json['clouds'], locale),
Value.fromJson2(json['irradiation'], locale),
Value.fromJson2(json['precipitation'], locale),
+ Value.fromJson2(json['temperature'], locale),
);
}
diff --git a/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.html b/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.html
index 40ccb9a..832ab27 100644
--- a/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.html
+++ b/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.html
@@ -4,9 +4,22 @@
+
+ {{ dateFormat(hour.date | date:'E') }}
+
-
+
+
+
+ ≥30°C
+ ≥20°C
+ ≥10°C
+ >0°C
+ ≤0°C
+
+ Niederschlag 100% = {{ PRECIPITATION_MAX_MM }}mm
+
diff --git a/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.less b/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.less
index a18ee55..e491a85 100644
--- a/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.less
+++ b/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.less
@@ -8,6 +8,7 @@
display: flex;
align-items: flex-end;
width: 100%; // any width will do (flex cares about real with)
+ overflow: visible;
.bar {
position: absolute;
@@ -25,8 +26,73 @@
.precipitation {
background-color: blue;
+ opacity: 0.75;
+ }
+
+ .temperature {
+ border-top: 0.06em solid black;
+ opacity: 0.75;
+ }
+
+ .temperatureGTE30 {
+ border-top-color: red;
+ }
+
+ .temperatureGTE20 {
+ border-top-color: orange;
+ }
+
+ .temperatureGTE10 {
+ border-top-color: yellow;
+ }
+
+ .temperatureGT0 {
+ border-top-color: blue;
+ }
+
+ .temperatureNegative {
+ border-top-color: white;
+ }
+
+ .weekdayHolder {
+ overflow: visible;
+ opacity: 1;
+ height: 100%;
}
}
}
+
+.legend {
+ display: flex;
+ width: 100%;
+ flex-direction: row;
+ justify-content: center;
+
+ .line {
+ padding: 0 0.25em;
+ font-size: 50%;
+ }
+
+ .temperatureGTE30 {
+ color: red;
+ }
+
+ .temperatureGTE20 {
+ color: orange;
+ }
+
+ .temperatureGTE10 {
+ color: yellow;
+ }
+
+ .temperatureGT0 {
+ color: blue;
+ }
+
+ .temperatureNegative {
+ color: white;
+ }
+
+}
diff --git a/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.ts b/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.ts
index fd742d0..e0dc786 100644
--- a/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.ts
+++ b/src/main/angular/src/app/weather/weather-diagram/weather-diagram.component.ts
@@ -1,5 +1,5 @@
import {Component, OnInit} from '@angular/core';
-import {NgForOf} from '@angular/common';
+import {DatePipe, NgClass, NgForOf, NgIf} from '@angular/common';
import {WeatherHour} from './WeatherHour';
import {WeatherService} from './weather.service';
import {WeatherDay} from './WeatherDay';
@@ -11,13 +11,18 @@ const DAY_COUNT = 7;
@Component({
selector: 'app-weather-diagram',
imports: [
- NgForOf
+ NgForOf,
+ NgIf,
+ DatePipe,
+ NgClass
],
templateUrl: './weather-diagram.component.html',
styleUrl: './weather-diagram.component.less'
})
export class WeatherDiagramComponent implements OnInit {
+ protected readonly PRECIPITATION_MAX_MM = 15;
+
protected days: WeatherDay[] = [];
protected hours: WeatherHour[] = [];
@@ -44,7 +49,11 @@ export class WeatherDiagramComponent implements OnInit {
}
precipitation(hour: WeatherHour) {
- return (hour.precipitation.percent(15)?.value || 0) + '%';
+ return (hour.precipitation.percent(this.PRECIPITATION_MAX_MM)?.value || 0) + '%';
+ }
+
+ temperature(hour: WeatherHour) {
+ return (hour.temperature.plus(10)?.percent(50)?.value || 0) + '%';
}
private updateHours() {
@@ -74,4 +83,26 @@ export class WeatherDiagramComponent implements OnInit {
}
}
+ dateFormat(date: string | null) {
+ if (!date) {
+ return "";
+ }
+ return date.substring(0, 2);
+ }
+
+ temperatureClasses(hour: WeatherHour): {} {
+ const temperatureGTE30 = hour.temperature.gte(30);
+ const temperatureGTE20 = hour.temperature.gte(20);
+ const temperatureGTE10 = hour.temperature.gte(10);
+ const temperatureGT0 = hour.temperature.gt(0);
+ const temperatureNegative = hour.temperature.lte(0);
+ return {
+ "temperatureGTE30": temperatureGTE30,
+ "temperatureGTE20": temperatureGTE20 && !temperatureGTE30,
+ "temperatureGTE10": temperatureGTE10 && !temperatureGTE20,
+ "temperatureGT0": temperatureGT0 && !temperatureGTE10,
+ "temperatureNegative": temperatureNegative
+ };
+ }
+
}
diff --git a/src/main/java/de/ph87/data/weather/WeatherDay.java b/src/main/java/de/ph87/data/weather/WeatherDay.java
index 74cf7bf..7b4653f 100644
--- a/src/main/java/de/ph87/data/weather/WeatherDay.java
+++ b/src/main/java/de/ph87/data/weather/WeatherDay.java
@@ -1,13 +1,18 @@
package de.ph87.data.weather;
+import de.ph87.data.value.Unit;
import de.ph87.data.value.Value;
-import de.ph87.data.value.*;
-import lombok.*;
+import lombok.Data;
+import lombok.NonNull;
+import lombok.ToString;
-import java.io.*;
-import java.time.*;
-import java.util.*;
-import java.util.stream.*;
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
@Data
@ToString(includeFieldNames = false)
@@ -67,11 +72,15 @@ public class WeatherDay {
@NonNull
public final Value precipitation;
+ @NonNull
+ public final Value temperature;
+
public Hour(@NonNull final BrightSkyDto.Weather dto) {
date = dto.getTimestamp();
clouds = new Value(dto.getCloud_cover(), Unit.CLOUD_COVER_PERCENT);
irradiation = new Value(dto.getSolar() * 1000, Unit.IRRADIATION_WH_M2);
precipitation = new Value(dto.getPrecipitation(), Unit.PRECIPITATION_MM);
+ temperature = new Value((dto.getTemperature()), Unit.TEMPERATURE_C);
}
}