From 13fff1d2373a9b300eb618a7ab02ccd579519439 Mon Sep 17 00:00:00 2001 From: Chris Kaczor Date: Fri, 11 Oct 2019 18:48:26 -0400 Subject: [PATCH] Add wind chart --- .../charts/weather-charts.component.html | 8 + .../charts/weather-charts.component.scss | 8 + .../charts/weather-charts.component.ts | 184 +++++++++++++++--- .../models/weather/wind-history-grouped.ts | 8 + 4 files changed, 176 insertions(+), 32 deletions(-) create mode 100644 Display/src/app/models/weather/wind-history-grouped.ts diff --git a/Display/src/app/components/weather/charts/weather-charts.component.html b/Display/src/app/components/weather/charts/weather-charts.component.html index 92854d0..6347fcf 100644 --- a/Display/src/app/components/weather/charts/weather-charts.component.html +++ b/Display/src/app/components/weather/charts/weather-charts.component.html @@ -1,6 +1,14 @@
+ + + + {{ item.value }} diff --git a/Display/src/app/components/weather/charts/weather-charts.component.scss b/Display/src/app/components/weather/charts/weather-charts.component.scss index 4491b53..03b97a5 100644 --- a/Display/src/app/components/weather/charts/weather-charts.component.scss +++ b/Display/src/app/components/weather/charts/weather-charts.component.scss @@ -17,3 +17,11 @@ .chart-button-spacer { margin-right: 20px; } + +.selected:after { + content: ""; + display: block; + margin: 0 auto; + width: 100%; + border-bottom: 1px solid #673ab7; +} diff --git a/Display/src/app/components/weather/charts/weather-charts.component.ts b/Display/src/app/components/weather/charts/weather-charts.component.ts index cb8e7cb..32de29d 100644 --- a/Display/src/app/components/weather/charts/weather-charts.component.ts +++ b/Display/src/app/components/weather/charts/weather-charts.component.ts @@ -1,14 +1,17 @@ import { Component, OnInit } from '@angular/core'; import { Chart } from 'angular-highcharts'; -import { SeriesLineOptions } from 'highcharts'; +import { SeriesLineOptions, SeriesWindbarbOptions } from 'highcharts'; import { HttpClient } from '@angular/common/http'; import { WeatherReadingGrouped } from '../../../models/weather/weather-reading-grouped'; +import { WindHistoryGrouped } from '../../../models/weather/wind-history-grouped'; import * as moment from 'moment'; import * as Highcharts from 'highcharts'; import HC_exporting from 'highcharts/modules/exporting'; +import HC_windbarb from 'highcharts/modules/windbarb'; HC_exporting(Highcharts); +HC_windbarb(Highcharts); enum TimeSpan { Last24Hours, @@ -16,6 +19,11 @@ enum TimeSpan { Custom } +enum ChartType { + Weather, + Wind +} + @Component({ selector: 'app-weather-charts', templateUrl: './weather-charts.component.html', @@ -28,6 +36,8 @@ export class WeatherChartsComponent implements OnInit { public timeSpanItems: { [value: number]: string } = {}; public timeSpans: typeof TimeSpan = TimeSpan; public maxDate: moment.Moment = moment().endOf('day'); + public selectedChartType: ChartType = ChartType.Weather; + public ChartType = ChartType; private selectedTimeSpanValue: TimeSpan = TimeSpan.Last24Hours; private selectedDateValue: moment.Moment = moment().startOf('day'); @@ -79,36 +89,17 @@ export class WeatherChartsComponent implements OnInit { return moment(this.selectedDate).format('LL'); } - private loadChart() { - let start: moment.Moment; - let end: moment.Moment; - - this.loading = true; - - if (this.chart) { - this.chart.ref$.subscribe(o => o.showLoading()); + public chartTypeChange(value: ChartType) { + if (this.selectedChartType === value) { + return; } - switch (this.selectedTimeSpan) { - case TimeSpan.Last24Hours: { - start = moment().subtract(24, 'hour'); - end = moment(); + this.selectedChartType = value; - break; - } - - case TimeSpan.Day: { - start = moment(this.selectedDate).startOf('day'); - end = moment(this.selectedDate).endOf('day'); - - break; - } - - default: { - return; - } - } + this.loadChart(); + } + private loadWeatherChart(start: moment.Moment, end: moment.Moment) { const startString = start.toISOString(); const endString = end.toISOString(); @@ -117,11 +108,11 @@ export class WeatherChartsComponent implements OnInit { request.subscribe(data => { const seriesData: Array = []; - seriesData.push({ name: 'Temperature', data: [], yAxis: 0, tooltip: { valueSuffix: '°F' } } as SeriesLineOptions); - seriesData.push({ name: 'Pressure', data: [], yAxis: 1, tooltip: { valueSuffix: '"' } } as SeriesLineOptions); - seriesData.push({ name: 'Humidity', data: [], yAxis: 2, tooltip: { valueSuffix: '%' } } as SeriesLineOptions); - seriesData.push({ name: 'Light', data: [], yAxis: 2, tooltip: { valueSuffix: '%' } } as SeriesLineOptions); - seriesData.push({ name: 'Rain', data: [], yAxis: 3, tooltip: { valueSuffix: '"' } } as SeriesLineOptions); + seriesData.push({ name: 'Temperature', data: [], yAxis: 0, marker: { enabled: false }, tooltip: { valueSuffix: '°F' } } as SeriesLineOptions); + seriesData.push({ name: 'Pressure', data: [], yAxis: 1, marker: { enabled: false }, tooltip: { valueSuffix: '"' } } as SeriesLineOptions); + seriesData.push({ name: 'Humidity', data: [], yAxis: 2, marker: { enabled: false }, tooltip: { valueSuffix: '%' } } as SeriesLineOptions); + seriesData.push({ name: 'Light', data: [], yAxis: 2, marker: { enabled: false }, tooltip: { valueSuffix: '%' } } as SeriesLineOptions); + seriesData.push({ name: 'Rain', data: [], yAxis: 3, marker: { enabled: false }, tooltip: { valueSuffix: '"' } } as SeriesLineOptions); let rainTotal = 0; @@ -232,4 +223,133 @@ export class WeatherChartsComponent implements OnInit { this.loading = false; }); } + + private loadWindChart(start: moment.Moment, end: moment.Moment) { + const startString = start.toISOString(); + const endString = end.toISOString(); + + const request = this.httpClient.get(`/api/weather/readings/wind-history-grouped?start=${startString}&end=${endString}&bucketMinutes=30`); + + request.subscribe(data => { + const seriesData: Array = []; + + seriesData.push({ type: 'line', name: 'Minimum', data: [], yAxis: 0, marker: { enabled: false }, tooltip: { valueSuffix: ' MPH' } } as SeriesLineOptions); + seriesData.push({ type: 'line', name: 'Average', data: [], yAxis: 0, marker: { enabled: false }, tooltip: { valueSuffix: ' MPH' } } as SeriesLineOptions); + seriesData.push({ type: 'line', name: 'Maximum', data: [], yAxis: 0, marker: { enabled: false }, tooltip: { valueSuffix: ' MPH' } } as SeriesLineOptions); + seriesData.push({ type: 'windbarb', name: 'Direction', data: [], marker: { enabled: false }, tooltip: { valueSuffix: ' MPH' } } as SeriesWindbarbOptions); + + data.forEach(dataElement => { + const date = Date.parse(dataElement.bucket); + seriesData[0].data.push([date, dataElement.minimumSpeed]); + seriesData[1].data.push([date, dataElement.averageSpeed]); + seriesData[2].data.push([date, dataElement.maximumSpeed]); + seriesData[3].data.push([date, dataElement.averageSpeed, dataElement.averageDirection]); + }); + + const title = this.selectedTimeSpan === TimeSpan.Last24Hours ? this.timeSpanItems[TimeSpan.Last24Hours] : this.getSelectedDateDisplayString(); + + this.chart = new Chart({ + chart: { + zoomType: 'x' + }, + title: { + text: title + }, + credits: { + enabled: true + }, + xAxis: { + type: 'datetime', + dateTimeLabelFormats: { + millisecond: '%H:%M:%S.%L', + second: '%H:%M:%S', + minute: '%H:%M', + hour: '%l:%M %P', + day: '%b %e', + week: '%e. %b', + month: '%b \'%y', + year: '%Y' + }, + offset: 50 + }, + yAxis: [ + { + labels: { + format: '{value:.2f} MPH', + }, + title: { + text: 'Wind Speed' + } + } + ], + time: { + useUTC: false + }, + tooltip: { + valueDecimals: 2, + shared: true, + dateTimeLabelFormats: { + day: '%A, %b %e, %Y', + hour: '%A, %b %e, %H:%M', + millisecond: '%A, %b %e, %H:%M:%S.%L', + minute: '%A, %b %e, %l:%M %P', + month: '%B %Y', + second: '%A, %b %e, %H:%M:%S', + week: 'Week from %A, %b %e, %Y', + year: '%Y' + } + }, + series: seriesData, + legend: { + enabled: true + }, + exporting: { + enabled: true + } + }); + + this.loading = false; + }); + } + + private loadChart() { + let start: moment.Moment; + let end: moment.Moment; + + this.loading = true; + + if (this.chart) { + this.chart.ref$.subscribe(o => o.showLoading()); + } + + switch (this.selectedTimeSpan) { + case TimeSpan.Last24Hours: { + start = moment().subtract(24, 'hour'); + end = moment(); + + break; + } + + case TimeSpan.Day: { + start = moment(this.selectedDate).startOf('day'); + end = moment(this.selectedDate).endOf('day'); + + break; + } + + default: { + return; + } + } + + switch (this.selectedChartType) { + case ChartType.Weather: + this.loadWeatherChart(start, end); + break; + + case ChartType.Wind: + this.loadWindChart(start, end); + break; + } + } } diff --git a/Display/src/app/models/weather/wind-history-grouped.ts b/Display/src/app/models/weather/wind-history-grouped.ts new file mode 100644 index 0000000..6eda87a --- /dev/null +++ b/Display/src/app/models/weather/wind-history-grouped.ts @@ -0,0 +1,8 @@ +export class WindHistoryGrouped { + bucket: string; + minimumSpeed: number; + averageSpeed: number; + maximumSpeed: number; + averageDirection: number; +} +