New weather layout
This commit is contained in:
parent
24c4addd48
commit
b23739edf1
@ -24,7 +24,7 @@
|
|||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
</mat-drawer>
|
</mat-drawer>
|
||||||
<mat-drawer-content class="bg-secondary text-white p-4" (click)="open = (mobile && open) ? false : open">
|
<mat-drawer-content class="bg-secondary text-white" (click)="open = (mobile && open) ? false : open">
|
||||||
<main class="h-100" [@routerTransition]="transition(o)">
|
<main class="h-100" [@routerTransition]="transition(o)">
|
||||||
<router-outlet #o="outlet"></router-outlet>
|
<router-outlet #o="outlet"></router-outlet>
|
||||||
</main>
|
</main>
|
||||||
|
@ -25,6 +25,7 @@ import {environment} from '../environments/environment';
|
|||||||
import * as firebase from 'firebase/app';
|
import * as firebase from 'firebase/app';
|
||||||
import { ServiceWorkerModule } from '@angular/service-worker';
|
import { ServiceWorkerModule } from '@angular/service-worker';
|
||||||
import {LineChartModule, NgxChartsModule} from '@swimlane/ngx-charts';
|
import {LineChartModule, NgxChartsModule} from '@swimlane/ngx-charts';
|
||||||
|
import { RoundPipe } from './round.pipe';
|
||||||
|
|
||||||
export const firebaseApp = firebase.initializeApp(environment.firebase);
|
export const firebaseApp = firebase.initializeApp(environment.firebase);
|
||||||
|
|
||||||
@ -36,7 +37,8 @@ export const firebaseApp = firebase.initializeApp(environment.firebase);
|
|||||||
WeatherComponent,
|
WeatherComponent,
|
||||||
SecurityComponent,
|
SecurityComponent,
|
||||||
SettingsComponent,
|
SettingsComponent,
|
||||||
LoginComponent
|
LoginComponent,
|
||||||
|
RoundPipe
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
|
@ -1,32 +1,34 @@
|
|||||||
<h1 class="mb-3">
|
<div class="p-3">
|
||||||
<mat-icon>{{batteryService.icon}}</mat-icon>
|
<h1 class="mb-3">
|
||||||
Powerwall:
|
<mat-icon>{{batteryService.icon}}</mat-icon>
|
||||||
<span *ngIf="batteryService.batteries.length" class="text-muted">{{batteryService.average * 100}}%</span>
|
Powerwall:
|
||||||
<span *ngIf="!batteryService.batteries.length" class="text-muted">UNKNOWN</span>
|
<span *ngIf="batteryService.batteries.length" class="text-muted">{{batteryService.average * 100}}%</span>
|
||||||
</h1>
|
<span *ngIf="!batteryService.batteries.length" class="text-muted">UNKNOWN</span>
|
||||||
<div class="w-100 mb-5" style="min-height: 400px">
|
</h1>
|
||||||
<ngx-charts-area-chart #chart1
|
<div class="w-100 mb-5" style="min-height: 400px">
|
||||||
[results]="batteryService.percentageData"
|
<ngx-charts-area-chart #chart1
|
||||||
[scheme]="scheme"
|
[results]="batteryService.percentageData"
|
||||||
[yAxis]="true"
|
[scheme]="scheme"
|
||||||
[yScaleMin]="0"
|
[yAxis]="true"
|
||||||
[yScaleMax]="100"
|
[yScaleMin]="0"
|
||||||
[yAxisTickFormatting]="percentFormat"
|
[yScaleMax]="100"
|
||||||
legendTitle="Charge"
|
[yAxisTickFormatting]="percentFormat"
|
||||||
[legend]="!app.mobile"
|
legendTitle="Charge"
|
||||||
[roundDomains]="true"
|
[legend]="!app.mobile"
|
||||||
></ngx-charts-area-chart>
|
[roundDomains]="true"
|
||||||
</div>
|
></ngx-charts-area-chart>
|
||||||
<div class="w-100 pt-5" style="min-height: 400px">
|
</div>
|
||||||
<ngx-charts-area-chart #chart2
|
<div class="w-100 pt-5" style="min-height: 400px">
|
||||||
[results]="batteryService.temperatureData"
|
<ngx-charts-area-chart #chart2
|
||||||
[scheme]="scheme"
|
[results]="batteryService.temperatureData"
|
||||||
[yAxis]="true"
|
[scheme]="scheme"
|
||||||
[yScaleMin]="0"
|
[yAxis]="true"
|
||||||
[yScaleMax]="80"
|
[yScaleMin]="0"
|
||||||
[yAxisTickFormatting]="tempFormat"
|
[yScaleMax]="80"
|
||||||
legendTitle="Temperature"
|
[yAxisTickFormatting]="tempFormat"
|
||||||
[legend]="!app.mobile"
|
legendTitle="Temperature"
|
||||||
[roundDomains]="true"
|
[legend]="!app.mobile"
|
||||||
></ngx-charts-area-chart>
|
[roundDomains]="true"
|
||||||
|
></ngx-charts-area-chart>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
11
src/app/round.pipe.ts
Normal file
11
src/app/round.pipe.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'round'
|
||||||
|
})
|
||||||
|
export class RoundPipe implements PipeTransform {
|
||||||
|
transform(value: number, decimalPlaces: number = 0): any {
|
||||||
|
const shift = Math.pow(10, decimalPlaces);
|
||||||
|
return Math.round(value * shift) / shift;
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +1,111 @@
|
|||||||
<div>
|
<div class="w-100 p-3 pt-5" [style.backgroundColor]="day ? '#88aaff' : '#000e31'">
|
||||||
<div class="d-flex flex-column flex-md-row justify-content-center align-items-center flex-grow-1">
|
<!-- Current Weather -->
|
||||||
<i [class]="'wi wi-fw ' + weatherService.icon" style="font-size: 6rem"></i>
|
<div class="d-flex flex-column align-items-center">
|
||||||
<div class="ml-0 ml-md-3">
|
<div>
|
||||||
<h1 class="my-4 my-md-0 font-weight-bold text-center text-md-left">{{weatherService.temp}} °C</h1>
|
<h3>{{weatherService.weather?.currently.summary}}</h3>
|
||||||
<h3 class="m-0">{{weatherService.weather}}</h3>
|
</div>
|
||||||
|
<div class="d-flex flex-column flex-md-row align-items-center justify-content-center">
|
||||||
|
<div class="p-3 text-center">
|
||||||
|
<i [class]="'mt-4 wi wi-fw ' + weatherService.icon" style="font-size: 6rem"></i>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="d-flex flex-column mr-3">
|
||||||
|
<div>
|
||||||
|
<h1 class="mb-0">{{weatherService.weather?.currently.temperature | round: 1}} °C</h1>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Feels Like: {{weatherService.weather?.currently.apparentTemperature | round}} °C
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex flex-column">
|
||||||
|
<div>
|
||||||
|
<mat-icon style="font-size: 18px; width: 18px; height: 18px">arrow_upward</mat-icon>
|
||||||
|
{{weatherService.weather?.daily.data[0].temperatureHigh | round}} °C
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<mat-icon style="font-size: 18px; width: 18px; height: 18px">arrow_downward</mat-icon>
|
||||||
|
{{weatherService.weather?.daily.data[0].temperatureLow | round}} °C
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<i class="wi wi-fw wi-umbrella"></i> {{weatherService.weather?.daily.data[0].precipProbability * 100 | round}}%
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="my-4 d-flex mx-auto" style="max-width: 450px">
|
<!-- Forecast -->
|
||||||
<div class="text-center flex-grow-1">
|
<mat-card class="m-3" style="max-width: 450px">
|
||||||
<i class="wi wi-fw wi-umbrella"></i> {{weatherService.pop}} mm
|
<div class="d-flex justify-content-center">
|
||||||
|
<div *ngFor="let day of weatherService.weather?.daily.data.slice(1, 7)" class="d-flex flex-column align-items-center flex-grow-1" style="max-width: 75px;">
|
||||||
|
{{day.time.toString().slice(0, 4).toUpperCase()}}
|
||||||
|
<i [class]="'my-2 wi wi-fw ' + day.icon" style="font-size: 2rem"></i>
|
||||||
|
<div class="text-center">{{day.temperatureHigh | round}} °C</div>
|
||||||
|
<div class="text-center text-muted">{{day.temperatureLow | round}} °C</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center flex-grow-1">
|
</mat-card>
|
||||||
<i class="wi wi-fw wi-cloud"></i> {{weatherService.cloudCover}} %
|
<!-- Sunlight -->
|
||||||
|
<mat-card class="m-3" style="max-width: 450px">
|
||||||
|
<h5>Sunlight</h5>
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<div class="d-flex align-items-center flex-grow-1">
|
||||||
|
<i class="wi wi-sunrise mr-1"></i> {{weatherService.weather?.daily.data[0].sunriseTime | date: 'shortTime'}}
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center justify-content-center flex-grow-1">
|
||||||
|
<i class="wi wi-fw wi-cloud mr-1"></i> {{weatherService.weather?.currently.cloudCover * 100 | round}}%
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center justify-content-end flex-grow-1">
|
||||||
|
<i class="wi wi-sunset mr-1"></i> {{weatherService.weather?.daily.data[0].sunsetTime | date: 'shortTime'}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center flex-grow-1">
|
<canvas id="myCanvas" class="mt-3" style="width: 100%" height="150"></canvas>
|
||||||
<i class="wi wi-fw wi-strong-wind"></i> {{weatherService.wind[1]}} KM/H
|
</mat-card>
|
||||||
|
<!-- Wind -->
|
||||||
|
<mat-card class="m-3" style="max-width: 450px">
|
||||||
|
<h5>Wind</h5>
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<div class="d-flex align-items-center flex-grow-1">
|
||||||
|
<i class="wi wi-fw wi-windy"></i> {{weatherService.weather?.currently.windSpeed | round}} km/h
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center justify-content-center flex-grow-1">
|
||||||
|
{{weatherService.weather?.currently.windBearing}}°
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center justify-content-end flex-grow-1">
|
||||||
|
<i class="wi wi-fw wi-strong-wind"></i> {{weatherService.weather?.currently.windGust | round}} km/h
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="p-3 text-center">
|
||||||
<mat-divider></mat-divider>
|
<i class="wi wi-wind wi-fw wi-towards-0" [style.transform]="'rotate(' + weatherService.weather?.currently.windBearing + 'deg)'" style="color: #5d8cff; font-size: 14rem; height: 14rem; width: 14rem"></i>
|
||||||
<div class="my-4 d-flex justify-content-center">
|
|
||||||
<div *ngFor="let w of weatherService.forecast" class="d-flex flex-column align-items-center flex-grow-1" style="max-width: 75px;">
|
|
||||||
{{w.day}}
|
|
||||||
<i [class]="'my-2 wi wi-fw ' + w.icon" style="font-size: 2rem"></i>
|
|
||||||
<div class="text-center">{{w.max}} °C</div>
|
|
||||||
<div class="text-center text-muted">{{w.min}} °C</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</mat-card>
|
||||||
<mat-divider></mat-divider>
|
<!-- Atmospheric -->
|
||||||
|
<mat-card class="m-3" style="max-width: 450px">
|
||||||
|
<h5>Atmospheric</h5>
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<div>
|
||||||
|
<i class="wi wi-fw wi-barometer"></i> {{weatherService.weather?.currently.pressure / 10 | round: 1}} kPa
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<i class="wi wi-fw wi-hot"></i> UV Index: {{weatherService.weather?.currently.uvIndex}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<mat-icon>remove_red_eye</mat-icon> {{weatherService.weather?.currently.visibility | round}} km
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<div>
|
||||||
|
<i class="wi wi-fw wi-humidity"></i> {{weatherService.weather?.currently.humidity * 100 | round}}% Humidity
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<i class="wi wi-fw wi-umbrella"></i> {{weatherService.weather?.daily.data[0].precipProbability * 100 | round}}%
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<i class="wi wi-fw wi-flood"></i> {{weatherService.weather?.daily.data[0].precipAccumulation | round: 1}} cm {{weatherService.weather?.daily.data[0].precipType}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,15 +1,89 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
import {WeatherService} from './weather.service';
|
import {WeatherService} from './weather.service';
|
||||||
|
import {timer} from 'rxjs';
|
||||||
|
import {filter} from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-weather',
|
selector: 'app-weather',
|
||||||
templateUrl: './weather.component.html'
|
templateUrl: './weather.component.html'
|
||||||
})
|
})
|
||||||
export class WeatherComponent implements OnInit {
|
export class WeatherComponent implements OnInit {
|
||||||
|
day = false;
|
||||||
|
|
||||||
constructor(public weatherService: WeatherService) { }
|
constructor(public weatherService: WeatherService) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
}
|
timer(0, 1000).pipe(filter(() => this.weatherService.weather)).subscribe(() => {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
const sunrise = this.weatherService.weather.daily.data[0].sunriseTime.getTime();
|
||||||
|
const sunset = this.weatherService.weather.daily.data[0].sunsetTime.getTime();
|
||||||
|
|
||||||
|
this.day = now > sunrise && now < sunset;
|
||||||
|
let diff = sunset - sunrise;
|
||||||
|
let current = new Date().getTime() - sunrise;
|
||||||
|
this.drawSunChart(current / diff);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
drawSunChart(progress: number) {
|
||||||
|
const c = <HTMLCanvasElement>document.getElementById('myCanvas');
|
||||||
|
if (c) {
|
||||||
|
const ctx = c.getContext('2d');
|
||||||
|
|
||||||
|
// All the points in 2D space we care about
|
||||||
|
const width = c.width;
|
||||||
|
const height = c.height;
|
||||||
|
const centerX = width / 2;
|
||||||
|
const centerY = height - 20;
|
||||||
|
const radius = height * 0.8;
|
||||||
|
const pointX = centerX + radius * Math.cos(Math.PI * (1 + progress));
|
||||||
|
const pointY = centerY + radius * Math.sin(Math.PI * (1 + progress));
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
ctx.clearRect(0, 0, width, height);
|
||||||
|
|
||||||
|
// Path background
|
||||||
|
ctx.fillStyle = '#aeaeae';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(centerX, centerY, radius, Math.PI, 0);
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
// Path
|
||||||
|
ctx.lineWidth = 5;
|
||||||
|
ctx.strokeStyle = '#585858';
|
||||||
|
ctx.fillStyle = '#585858';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(centerX, centerY, radius, Math.PI, 0);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
// Show sun
|
||||||
|
if(this.day) {
|
||||||
|
// Stroke background
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.fillStyle = '#b3ad00';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(centerX, centerY, radius, Math.PI, Math.PI * (1 + progress));
|
||||||
|
ctx.lineTo(pointX, centerY);
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
// Stroke
|
||||||
|
ctx.lineWidth = 6;
|
||||||
|
ctx.strokeStyle = '#e5df00';
|
||||||
|
ctx.fillStyle = '#e5df00';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(centerX, centerY, radius, Math.PI, Math.PI * (1 + progress));
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
// Stroke end dot
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.fillStyle = '#e5df00';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(pointX, pointY, 6, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,73 +1,31 @@
|
|||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {HttpClient} from '@angular/common/http';
|
import {HttpClient} from '@angular/common/http';
|
||||||
|
import {WeatherIcons} from './weatherIcons';
|
||||||
import {timer} from 'rxjs';
|
import {timer} from 'rxjs';
|
||||||
import {database} from 'firebase';
|
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class WeatherService {
|
export class WeatherService {
|
||||||
readonly apiKey = 'e8391af54b6fc09dc82b019fc68b8409';
|
|
||||||
readonly city = 'London';
|
|
||||||
readonly countryCode = 'CA';
|
|
||||||
readonly days = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
|
|
||||||
readonly weatherCodes = require('./weatherCodes.json');
|
|
||||||
|
|
||||||
// Weather information
|
|
||||||
cloudCover = 0;
|
|
||||||
forecast = [];
|
|
||||||
humidity = 0;
|
|
||||||
icon: string;
|
icon: string;
|
||||||
pop = 0;
|
lat = 42.9849;
|
||||||
pressure = 0;
|
lng = -81.2453;
|
||||||
sunrise: Date;
|
units = 'ca';
|
||||||
sunset: Date;
|
weather: any;
|
||||||
temp = 0;
|
|
||||||
tempMin = 0;
|
|
||||||
tempMax = 0;
|
|
||||||
weather: string = '';
|
|
||||||
wind: [number, number] = [0, 0];
|
|
||||||
|
|
||||||
constructor(httpClient: HttpClient) {
|
constructor(http: HttpClient) {
|
||||||
|
// Get weather every 5 minutes
|
||||||
timer(0, 5 * 60000).subscribe(async () => {
|
timer(0, 5 * 60000).subscribe(async () => {
|
||||||
// Current weather information
|
this.weather = await http.get(`https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/88373fac9e52db6ad33a296f3b30404d/${this.lat},${this.lng}?units=${this.units}`).toPromise();
|
||||||
httpClient.get(`https://api.openweathermap.org/data/2.5/weather?q=${this.city},${this.countryCode}&APPID=${this.apiKey}&units=metric`).toPromise().then((weather: any) => {
|
|
||||||
this.cloudCover = weather.clouds.all;
|
|
||||||
this.humidity = weather.main.humidity;
|
|
||||||
this.icon = `wi-${this.weatherCodes[weather.weather[0].id].icon}`;
|
|
||||||
this.pressure = weather.main.pressure;
|
|
||||||
this.sunrise = new Date(weather.sys.sunrise);
|
|
||||||
this.sunset = new Date(weather.sys.sunset);
|
|
||||||
this.temp = Math.round(weather.main.temp);
|
|
||||||
this.tempMin = Math.round(weather.main.temp_min);
|
|
||||||
this.tempMax = Math.round(weather.main.temp_max);
|
|
||||||
this.weather = weather.weather[0].description;
|
|
||||||
this.wind = [weather.wind.deg, Math.round(weather.wind.speed)];
|
|
||||||
});
|
|
||||||
|
|
||||||
// 5 day forecast
|
// Format data
|
||||||
httpClient.get(`https://api.openweathermap.org/data/2.5/forecast?q=${this.city},${this.countryCode}&APPID=${this.apiKey}&units=metric`).toPromise().then((weather: any) => {
|
this.weather.daily.data.map(day => Object.assign(day, {
|
||||||
this.pop = Math.round(weather.list.slice(0, 4).reduce((acc, weather) => {
|
icon: WeatherIcons[day.icon],
|
||||||
if(weather['rain']) acc += weather['rain']['3h'] || 0;
|
time: new Date(day.time * 1000),
|
||||||
if(weather['snow']) acc += weather['snow']['3h'] || 0;
|
sunsetTime: new Date(day.sunsetTime * 1000),
|
||||||
return acc;
|
sunriseTime: new Date(day.sunriseTime * 1000),
|
||||||
}, 0) * 10) / 10;
|
}));
|
||||||
|
this.icon = WeatherIcons[this.weather.currently.icon];
|
||||||
let temp = {};
|
|
||||||
weather.list.forEach(weather => {
|
|
||||||
let timestamp = new Date(weather.dt * 1000);
|
|
||||||
let day = timestamp.getDate();
|
|
||||||
console.log(timestamp.getHours());
|
|
||||||
if(!temp[day]) temp[day] = {};
|
|
||||||
if(!temp[day].max || weather.main.temp_max > temp[day].max) temp[day].max = Math.round(weather.main.temp_max);
|
|
||||||
if(!temp[day].min || weather.main.temp_min < temp[day].min) temp[day].min = Math.round(weather.main.temp_min);
|
|
||||||
if(!temp[day].day || timestamp.getHours() == 13) {
|
|
||||||
temp[day].day = timestamp.toString().substring(0, 4);
|
|
||||||
temp[day].icon = `wi-${this.weatherCodes[weather.weather[0].id].icon}`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.forecast = Object.values(temp);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,367 +0,0 @@
|
|||||||
{
|
|
||||||
"200": {
|
|
||||||
"label": "thunderstorm with light rain",
|
|
||||||
"icon": "storm-showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"201": {
|
|
||||||
"label": "thunderstorm with rain",
|
|
||||||
"icon": "storm-showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"202": {
|
|
||||||
"label": "thunderstorm with heavy rain",
|
|
||||||
"icon": "storm-showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"210": {
|
|
||||||
"label": "light thunderstorm",
|
|
||||||
"icon": "storm-showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"211": {
|
|
||||||
"label": "thunderstorm",
|
|
||||||
"icon": "thunderstorm"
|
|
||||||
},
|
|
||||||
|
|
||||||
"212": {
|
|
||||||
"label": "heavy thunderstorm",
|
|
||||||
"icon": "thunderstorm"
|
|
||||||
},
|
|
||||||
|
|
||||||
"221": {
|
|
||||||
"label": "ragged thunderstorm",
|
|
||||||
"icon": "thunderstorm"
|
|
||||||
},
|
|
||||||
|
|
||||||
"230": {
|
|
||||||
"label": "thunderstorm with light drizzle",
|
|
||||||
"icon": "storm-showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"231": {
|
|
||||||
"label": "thunderstorm with drizzle",
|
|
||||||
"icon": "storm-showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"232": {
|
|
||||||
"label": "thunderstorm with heavy drizzle",
|
|
||||||
"icon": "storm-showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"300": {
|
|
||||||
"label": "light intensity drizzle",
|
|
||||||
"icon": "sprinkle"
|
|
||||||
},
|
|
||||||
|
|
||||||
"301": {
|
|
||||||
"label": "drizzle",
|
|
||||||
"icon": "sprinkle"
|
|
||||||
},
|
|
||||||
|
|
||||||
"302": {
|
|
||||||
"label": "heavy intensity drizzle",
|
|
||||||
"icon": "sprinkle"
|
|
||||||
},
|
|
||||||
|
|
||||||
"310": {
|
|
||||||
"label": "light intensity drizzle rain",
|
|
||||||
"icon": "sprinkle"
|
|
||||||
},
|
|
||||||
|
|
||||||
"311": {
|
|
||||||
"label": "drizzle rain",
|
|
||||||
"icon": "sprinkle"
|
|
||||||
},
|
|
||||||
|
|
||||||
"312": {
|
|
||||||
"label": "heavy intensity drizzle rain",
|
|
||||||
"icon": "sprinkle"
|
|
||||||
},
|
|
||||||
|
|
||||||
"313": {
|
|
||||||
"label": "shower rain and drizzle",
|
|
||||||
"icon": "sprinkle"
|
|
||||||
},
|
|
||||||
|
|
||||||
"314": {
|
|
||||||
"label": "heavy shower rain and drizzle",
|
|
||||||
"icon": "sprinkle"
|
|
||||||
},
|
|
||||||
|
|
||||||
"321": {
|
|
||||||
"label": "shower drizzle",
|
|
||||||
"icon": "sprinkle"
|
|
||||||
},
|
|
||||||
|
|
||||||
"500": {
|
|
||||||
"label": "light rain",
|
|
||||||
"icon": "rain"
|
|
||||||
},
|
|
||||||
|
|
||||||
"501": {
|
|
||||||
"label": "moderate rain",
|
|
||||||
"icon": "rain"
|
|
||||||
},
|
|
||||||
|
|
||||||
"502": {
|
|
||||||
"label": "heavy intensity rain",
|
|
||||||
"icon": "rain"
|
|
||||||
},
|
|
||||||
|
|
||||||
"503": {
|
|
||||||
"label": "very heavy rain",
|
|
||||||
"icon": "rain"
|
|
||||||
},
|
|
||||||
|
|
||||||
"504": {
|
|
||||||
"label": "extreme rain",
|
|
||||||
"icon": "rain"
|
|
||||||
},
|
|
||||||
|
|
||||||
"511": {
|
|
||||||
"label": "freezing rain",
|
|
||||||
"icon": "rain-mix"
|
|
||||||
},
|
|
||||||
|
|
||||||
"520": {
|
|
||||||
"label": "light intensity shower rain",
|
|
||||||
"icon": "showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"521": {
|
|
||||||
"label": "shower rain",
|
|
||||||
"icon": "showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"522": {
|
|
||||||
"label": "heavy intensity shower rain",
|
|
||||||
"icon": "showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"531": {
|
|
||||||
"label": "ragged shower rain",
|
|
||||||
"icon": "showers"
|
|
||||||
},
|
|
||||||
|
|
||||||
"600": {
|
|
||||||
"label": "light snow",
|
|
||||||
"icon": "snow"
|
|
||||||
},
|
|
||||||
|
|
||||||
"601": {
|
|
||||||
"label": "snow",
|
|
||||||
"icon": "snow"
|
|
||||||
},
|
|
||||||
|
|
||||||
"602": {
|
|
||||||
"label": "heavy snow",
|
|
||||||
"icon": "snow"
|
|
||||||
},
|
|
||||||
|
|
||||||
"611": {
|
|
||||||
"label": "sleet",
|
|
||||||
"icon": "sleet"
|
|
||||||
},
|
|
||||||
|
|
||||||
"612": {
|
|
||||||
"label": "shower sleet",
|
|
||||||
"icon": "sleet"
|
|
||||||
},
|
|
||||||
|
|
||||||
"615": {
|
|
||||||
"label": "light rain and snow",
|
|
||||||
"icon": "rain-mix"
|
|
||||||
},
|
|
||||||
|
|
||||||
"616": {
|
|
||||||
"label": "rain and snow",
|
|
||||||
"icon": "rain-mix"
|
|
||||||
},
|
|
||||||
|
|
||||||
"620": {
|
|
||||||
"label": "light shower snow",
|
|
||||||
"icon": "rain-mix"
|
|
||||||
},
|
|
||||||
|
|
||||||
"621": {
|
|
||||||
"label": "shower snow",
|
|
||||||
"icon": "rain-mix"
|
|
||||||
},
|
|
||||||
|
|
||||||
"622": {
|
|
||||||
"label": "heavy shower snow",
|
|
||||||
"icon": "rain-mix"
|
|
||||||
},
|
|
||||||
|
|
||||||
"701": {
|
|
||||||
"label": "mist",
|
|
||||||
"icon": "sprinkle"
|
|
||||||
},
|
|
||||||
|
|
||||||
"711": {
|
|
||||||
"label": "smoke",
|
|
||||||
"icon": "smoke"
|
|
||||||
},
|
|
||||||
|
|
||||||
"721": {
|
|
||||||
"label": "haze",
|
|
||||||
"icon": "day-haze"
|
|
||||||
},
|
|
||||||
|
|
||||||
"731": {
|
|
||||||
"label": "sand, dust whirls",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
},
|
|
||||||
|
|
||||||
"741": {
|
|
||||||
"label": "fog",
|
|
||||||
"icon": "fog"
|
|
||||||
},
|
|
||||||
|
|
||||||
"751": {
|
|
||||||
"label": "sand",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
},
|
|
||||||
|
|
||||||
"761": {
|
|
||||||
"label": "dust",
|
|
||||||
"icon": "dust"
|
|
||||||
},
|
|
||||||
|
|
||||||
"762": {
|
|
||||||
"label": "volcanic ash",
|
|
||||||
"icon": "smog"
|
|
||||||
},
|
|
||||||
|
|
||||||
"771": {
|
|
||||||
"label": "squalls",
|
|
||||||
"icon": "day-windy"
|
|
||||||
},
|
|
||||||
|
|
||||||
"781": {
|
|
||||||
"label": "tornado",
|
|
||||||
"icon": "tornado"
|
|
||||||
},
|
|
||||||
|
|
||||||
"800": {
|
|
||||||
"label": "clear sky",
|
|
||||||
"icon": "day-sunny"
|
|
||||||
},
|
|
||||||
|
|
||||||
"801": {
|
|
||||||
"label": "few clouds",
|
|
||||||
"icon": "cloudy"
|
|
||||||
},
|
|
||||||
|
|
||||||
"802": {
|
|
||||||
"label": "scattered clouds",
|
|
||||||
"icon": "cloudy"
|
|
||||||
},
|
|
||||||
|
|
||||||
"803": {
|
|
||||||
"label": "broken clouds",
|
|
||||||
"icon": "cloudy"
|
|
||||||
},
|
|
||||||
|
|
||||||
"804": {
|
|
||||||
"label": "overcast clouds",
|
|
||||||
"icon": "cloudy"
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
"900": {
|
|
||||||
"label": "tornado",
|
|
||||||
"icon": "tornado"
|
|
||||||
},
|
|
||||||
|
|
||||||
"901": {
|
|
||||||
"label": "tropical storm",
|
|
||||||
"icon": "hurricane"
|
|
||||||
},
|
|
||||||
|
|
||||||
"902": {
|
|
||||||
"label": "hurricane",
|
|
||||||
"icon": "hurricane"
|
|
||||||
},
|
|
||||||
|
|
||||||
"903": {
|
|
||||||
"label": "cold",
|
|
||||||
"icon": "snowflake-cold"
|
|
||||||
},
|
|
||||||
|
|
||||||
"904": {
|
|
||||||
"label": "hot",
|
|
||||||
"icon": "hot"
|
|
||||||
},
|
|
||||||
|
|
||||||
"905": {
|
|
||||||
"label": "windy",
|
|
||||||
"icon": "windy"
|
|
||||||
},
|
|
||||||
|
|
||||||
"906": {
|
|
||||||
"label": "hail",
|
|
||||||
"icon": "hail"
|
|
||||||
},
|
|
||||||
|
|
||||||
"951": {
|
|
||||||
"label": "calm",
|
|
||||||
"icon": "day-sunny"
|
|
||||||
},
|
|
||||||
|
|
||||||
"952": {
|
|
||||||
"label": "light breeze",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
},
|
|
||||||
|
|
||||||
"953": {
|
|
||||||
"label": "gentle breeze",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
},
|
|
||||||
|
|
||||||
"954": {
|
|
||||||
"label": "moderate breeze",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
},
|
|
||||||
|
|
||||||
"955": {
|
|
||||||
"label": "fresh breeze",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
},
|
|
||||||
|
|
||||||
"956": {
|
|
||||||
"label": "strong breeze",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
},
|
|
||||||
|
|
||||||
"957": {
|
|
||||||
"label": "high wind, near gale",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
},
|
|
||||||
|
|
||||||
"958": {
|
|
||||||
"label": "gale",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
},
|
|
||||||
|
|
||||||
"959": {
|
|
||||||
"label": "severe gale",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
},
|
|
||||||
|
|
||||||
"960": {
|
|
||||||
"label": "storm",
|
|
||||||
"icon": "thunderstorm"
|
|
||||||
},
|
|
||||||
|
|
||||||
"961": {
|
|
||||||
"label": "violent storm",
|
|
||||||
"icon": "thunderstorm"
|
|
||||||
},
|
|
||||||
|
|
||||||
"962": {
|
|
||||||
"label": "hurricane",
|
|
||||||
"icon": "cloudy-gusts"
|
|
||||||
}
|
|
||||||
}
|
|
16
src/app/weather/weatherIcons.ts
Normal file
16
src/app/weather/weatherIcons.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export enum WeatherIcons {
|
||||||
|
'clear-day' = 'wi-day-sunny',
|
||||||
|
'clear-night' = 'wi-night-clear',
|
||||||
|
'cloudy' = 'wi-cloudy',
|
||||||
|
'default' = '',
|
||||||
|
'fog' = 'wi-fog',
|
||||||
|
'hail' = 'wi-hail',
|
||||||
|
'partly-cloudy-day' = 'wi-day-cloudy',
|
||||||
|
'partly-cloudy-night' = 'wi-night-alt-cloudy',
|
||||||
|
'rain' = 'wi-rain',
|
||||||
|
'sleet' = 'wi-sleet',
|
||||||
|
'snow' = 'wi-snow',
|
||||||
|
'thunderstorm' = 'wi-thunderstorm',
|
||||||
|
'tornado' = 'wi-tornado',
|
||||||
|
'wind' = 'wi-strong-wind',
|
||||||
|
}
|
@ -12,9 +12,9 @@
|
|||||||
<link rel="stylesheet" type="text/css" href="assets/bootstrap.min.css">
|
<link rel="stylesheet" type="text/css" href="assets/bootstrap.min.css">
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body style="background-color: #2F323A;">
|
||||||
<app-root>
|
<app-root>
|
||||||
<div class="center">
|
<div style="position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<h1 class="d-inline text-white">Home Front</h1>
|
<h1 class="d-inline text-white">Home Front</h1>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
@import url('https://fonts.googleapis.com/css?family=Archivo|Material+Icons');
|
@import url('https://fonts.googleapis.com/css?family=Archivo|Material+Icons');
|
||||||
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
|
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
|
||||||
@import url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/css/weather-icons.min.css');
|
@import url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/css/weather-icons.min.css');
|
||||||
|
@import url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/css/weather-icons-wind.min.css');
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
Loading…
Reference in New Issue
Block a user