1. 背景執行 bug fix

2. 店站總覽 即時資訊
This commit is contained in:
Kai 2021-07-08 18:21:51 +08:00
parent 190197c2ec
commit 2661487cc8
11 changed files with 473 additions and 30 deletions

View File

@ -163,5 +163,66 @@ namespace SolarPower.Controllers
apiResult.Msg = errorCode.GetString(apiResult.Code);
return apiResult;
}
public async Task<ApiResult<ChartUptoDate>> GetChartUpToDate(int id)
{
ApiResult<ChartUptoDate> apiResult = new ApiResult<ChartUptoDate>();
ChartUptoDate chartUptoDate = new ChartUptoDate();
try
{
var nowDay = DateTime.Now.ToString("yyyy-MM-dd");
//今日發電量日照度List
var powerIrradianceToday = await overviewRepository.GetListPowerIrradianceTodayByPowerStationId(id, nowDay);
//今日資料轉換
PowerIrradianceChart powerIrradianceTodayChart = new PowerIrradianceChart();
powerIrradianceTodayChart.Labels = powerIrradianceToday.Select(x => x.Label).ToList();
powerIrradianceTodayChart.PowerDatas = powerIrradianceToday.Select(x => x.PowerData).ToList();
powerIrradianceTodayChart.IrradianceDatas = powerIrradianceToday.Select(x => x.IrradianceData).ToList();
chartUptoDate.ChartToday = powerIrradianceTodayChart;
//7日發電量日照度List
var powerIrradiance7day = await overviewRepository.GetListPowerIrradiance7dayByPowerStationId(id, nowDay);
//7日資料轉換
PowerIrradianceChart powerIrradiance7dayChart = new PowerIrradianceChart();
powerIrradiance7dayChart.Labels = powerIrradiance7day.Select(x => x.Label).ToList();
powerIrradiance7dayChart.PowerDatas = powerIrradiance7day.Select(x => x.PowerData).ToList();
powerIrradiance7dayChart.IrradianceDatas = powerIrradiance7day.Select(x => x.IrradianceData).ToList();
chartUptoDate.Chart7day = powerIrradiance7dayChart;
//本月發電量日照度List
var powerIrradianceMonth = await overviewRepository.GetListPowerIrradianceMonthByPowerStationId(id, nowDay);
//今日資料轉換
PowerIrradianceChart powerIrradianceMonthChart = new PowerIrradianceChart();
powerIrradianceMonthChart.Labels = powerIrradianceMonth.Select(x => x.Label).ToList();
powerIrradianceMonthChart.PowerDatas = powerIrradianceMonth.Select(x => x.PowerData).ToList();
powerIrradianceMonthChart.IrradianceDatas = powerIrradianceMonth.Select(x => x.IrradianceData).ToList();
chartUptoDate.ChartMonth = powerIrradianceMonthChart;
//本年發電量日照度List
var powerIrradianceYear = await overviewRepository.GetListPowerIrradianceYearByPowerStationId(id, nowDay);
//今日資料轉換
PowerIrradianceChart powerIrradianceYearChart = new PowerIrradianceChart();
powerIrradianceYearChart.Labels = powerIrradianceYear.Select(x => x.Label).ToList();
powerIrradianceYearChart.PowerDatas = powerIrradianceYear.Select(x => x.PowerData).ToList();
powerIrradianceYearChart.IrradianceDatas = powerIrradianceYear.Select(x => x.IrradianceData).ToList();
chartUptoDate.ChartYear = powerIrradianceYearChart;
apiResult.Code = "0000";
apiResult.Data = chartUptoDate;
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
apiResult.Msg = errorCode.GetString(apiResult.Code);
return apiResult;
}
}
}

View File

@ -54,4 +54,25 @@ namespace SolarPower.Models
public byte IsShowMoney { get; set; } //是否顯示發電金額
public string UpdatedAt { get; set; } //畫面資料更新時間
}
public class ChartUptoDate
{
public PowerIrradianceChart ChartToday { get; set; }
public PowerIrradianceChart Chart7day { get; set; }
public PowerIrradianceChart ChartMonth { get; set; }
public PowerIrradianceChart ChartYear { get; set; }
}
public class PowerIrradiance
{
public string Label { get; set; }
public double PowerData { get; set; }
public double IrradianceData { get; set; }
}
public class PowerIrradianceChart
{
public List<string> Labels { get; set; }
public List<double> PowerDatas { get; set; }
public List<double> IrradianceDatas { get; set; }
}
}

View File

@ -40,14 +40,19 @@ namespace SolarPower.Quartz.Jobs
var DateTimeNow = DateTime.Now;
var count = 0;
#region step2. DB及電站編號找出該電站的控制器
foreach (var powerStation in powerStations)
{
if (count > 0)
{
break;
}
var calcPowerStation = new PowerStation();
calcPowerStation.Id = powerStation.Id;
var dateNowDay = DateTimeNow.AddDays(-1).ToString("yyyy-MM-dd");
dateNowDay = "2021-06-24";
#region step2-1. 30
var table_name = String.Format("`{0}`.`{1}01_station`", powerStation.SiteDB, powerStation.Code);
var history = await powerStationRepository.CalcAvgPowerStationHistory30day(dateNowDay, table_name);
@ -100,7 +105,6 @@ namespace SolarPower.Quartz.Jobs
#region step2-4.
//判斷這個月是否已存在
var dateNowMonth = DateTimeNow.ToString("yyyy-MM");
dateNowMonth = "2021-06";
//電站該月份的歷史資料
var exist_history = await powerStationRepository.GetOnePowerStationHistoryByPowerStationIdAndMonth(powerStation.Id, dateNowMonth);
@ -143,6 +147,8 @@ namespace SolarPower.Quartz.Jobs
}
}
#endregion
count++;
}
#endregion
@ -213,14 +219,14 @@ namespace SolarPower.Quartz.Jobs
await powerStationRepository.AddPyrheliometerHistoryDayList(pyrheliometerHistoryDays, pyrheliometer_history_properties);
//每月
if (insertPowerStationHistoryMonths.Count > 0)
if (insertPyrheliometerHistoryMonths.Count > 0)
{
await powerStationRepository.AddPowerStationHistoryMonthList(insertPowerStationHistoryMonths, history_properties_month);
await powerStationRepository.AddPyrheliometerHistoryMonthList(insertPyrheliometerHistoryMonths, pyrheliometer_history_properties);
}
if (updatePowerStationHistoryMonths.Count > 0)
if (updatePyrheliometerHistoryMonths.Count > 0)
{
await powerStationRepository.UpdatePowerStationHistoryMonthList(updatePowerStationHistoryMonths);
await powerStationRepository.UpdatePyrheliometerHistoryMonthList(updatePyrheliometerHistoryMonths);
}
#endregion

View File

@ -37,14 +37,20 @@ namespace SolarPower.Quartz.Jobs
var DateTimeNow = DateTime.Now;
var count = 0;
#region step2. DB及電站編號找出該電站的控制器
foreach (var powerStation in powerStations)
{
if (count > 0)
{
break;
}
var calcPowerStation = new PowerStation();
calcPowerStation.Id = powerStation.Id;
var dateTime = DateTimeNow.AddHours(-1).ToString("yyyy-MM-dd HH");
dateTime = "2021-06-24 18";
#region step2-1.
var table_name = String.Format("`{0}`.{1}01_station", powerStation.SiteDB, powerStation.Code);
@ -53,7 +59,7 @@ namespace SolarPower.Quartz.Jobs
if (history != null)
{
history.PowerStationId = powerStation.Id;
history.Timestamp = Convert.ToDateTime(history.Timestamp).ToString("yyyy-MM-dd HH:mm:ss");
history.Timestamp = Convert.ToDateTime(history.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
#region
@ -142,13 +148,16 @@ namespace SolarPower.Quartz.Jobs
{
calcPowerStation.Today_irradiance = pyrheliometerHistory.Irradiance;
pyrheliometerHistory.Timestamp = Convert.ToDateTime(pyrheliometerHistory.Timestamp).ToString("yyyy-MM-dd HH:mm:ss");
pyrheliometerHistory.Timestamp = Convert.ToDateTime(pyrheliometerHistory.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
pyrheliometerHistory.PowerStationId = powerStation.Id;
pyrheliometerHistoriesHour.Add(pyrheliometerHistory);
}
}
#endregion
calcPowerStations.Add(calcPowerStation);
count++;
}
#endregion

View File

@ -168,5 +168,102 @@ namespace SolarPower.Repository.Implement
}
return powerstation;
}
public async Task<List<PowerIrradiance>> GetListPowerIrradianceTodayByPowerStationId(int powerStationId, string nowDay)
{
List<PowerIrradiance> result;
using (IDbConnection conn = this._databaseHelper.GetConnection())
{
try
{
var sql_power = @$"SELECT DATE_FORMAT(FROM_UNIXTIME(ps.timestamp/1000), '%Y-%m-%d %H') AS Label, ps.KWH AS PowerData, pyr.Irradiance AS IrradianceData
FROM power_station_history_hour ps
LEFT JOIN pyrheliometer_history_hour pyr ON ps.PowerStationId = pyr.PowerStationId AND DATE_FORMAT(FROM_UNIXTIME(ps.timestamp/1000), '%Y-%m-%d %H') = DATE_FORMAT(FROM_UNIXTIME(pyr.timestamp), '%Y-%m-%d %H')
WHERE ps.PowerStationId = @PowerStationId
AND DATE_FORMAT(FROM_UNIXTIME(ps.timestamp/1000), '%Y-%m-%d') = @NowDay";
result = (await conn.QueryAsync<PowerIrradiance>(sql_power, new { PowerStationId = powerStationId, NowDay = nowDay })).ToList();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
public async Task<List<PowerIrradiance>> GetListPowerIrradiance7dayByPowerStationId(int powerStationId, string nowDay)
{
List<PowerIrradiance> result;
using (IDbConnection conn = this._databaseHelper.GetConnection())
{
try
{
var startDay = Convert.ToDateTime(nowDay).AddDays(-7).ToString("yyyy-MM-dd");
var sql_power = @$"SELECT DATE_FORMAT(ps.timestamp, '%Y-%m-%d') AS Label, ps.TODAYKWH AS PowerData, pyr.Irradiance AS IrradianceData
FROM power_station_history_day ps
LEFT JOIN pyrheliometer_history_day pyr ON ps.PowerStationId = pyr.PowerStationId AND DATE_FORMAT(ps.timestamp, '%Y-%m-%d') = DATE_FORMAT(FROM_UNIXTIME(pyr.timestamp), '%Y-%m-%d')
WHERE ps.PowerStationId = @PowerStationId
AND DATE_FORMAT(ps.timestamp, '%Y-%m-%d') BETWEEN @StartDay AND @NowDay";
result = (await conn.QueryAsync<PowerIrradiance>(sql_power, new { PowerStationId = powerStationId, StartDay = startDay, NowDay = nowDay })).ToList();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
public async Task<List<PowerIrradiance>> GetListPowerIrradianceMonthByPowerStationId(int powerStationId, string nowDay)
{
List<PowerIrradiance> result;
using (IDbConnection conn = this._databaseHelper.GetConnection())
{
try
{
var startDay = Convert.ToDateTime(nowDay).ToString("yyyy-MM-01");
var sql_power = @$"SELECT DATE_FORMAT(ps.timestamp, '%Y-%m-%d') AS Label, ps.TODAYKWH AS PowerData, pyr.Irradiance AS IrradianceData
FROM power_station_history_day ps
LEFT JOIN pyrheliometer_history_day pyr ON ps.PowerStationId = pyr.PowerStationId AND DATE_FORMAT(ps.timestamp, '%Y-%m-%d') = DATE_FORMAT(FROM_UNIXTIME(pyr.timestamp), '%Y-%m-%d')
WHERE ps.PowerStationId = @PowerStationId
AND DATE_FORMAT(ps.timestamp, '%Y-%m-%d') BETWEEN @StartDay AND @NowDay";
result = (await conn.QueryAsync<PowerIrradiance>(sql_power, new { PowerStationId = powerStationId, StartDay = startDay, NowDay = nowDay })).ToList();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
public async Task<List<PowerIrradiance>> GetListPowerIrradianceYearByPowerStationId(int powerStationId, string nowDay)
{
List<PowerIrradiance> result;
using (IDbConnection conn = this._databaseHelper.GetConnection())
{
try
{
var startyear = Convert.ToDateTime(nowDay).ToString("yyyy");
var sql_power = @$"SELECT DATE_FORMAT(ps.timestamp, '%Y-%m') AS Label, ps.MONTHKWH AS PowerData, pyr.Irradiance AS IrradianceData
FROM power_station_history_month ps
LEFT JOIN pyrheliometer_history_month pyr ON ps.PowerStationId = pyr.PowerStationId AND DATE_FORMAT(ps.timestamp, '%Y-%m') = DATE_FORMAT(FROM_UNIXTIME(pyr.timestamp), '%Y-%m')
WHERE ps.PowerStationId = @PowerStationId
AND DATE_FORMAT(ps.timestamp, '%Y') = @Year";
result = (await conn.QueryAsync<PowerIrradiance>(sql_power, new { PowerStationId = powerStationId, Year = startyear})).ToList();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
}
}

View File

@ -2223,7 +2223,7 @@ namespace SolarPower.Repository.Implement
sql_per_device.Add(str);
}
var sql = @"SELCET TIMESTAMP, AVG(SENSOR) AS Irradiance FROM(" + string.Join(" UNION ", sql_per_device) + @") GORUP BY TIMESTAMP";
var sql = @"SELECT a.TIMESTAMP, AVG(a.SENSOR) AS Irradiance FROM(" + string.Join(" UNION ", sql_per_device) + @") a GROUP BY TIMESTAMP";
result = await conn.QueryFirstOrDefaultAsync<PyrheliometerHistory>(sql, new { DateTime = dateTime });
}
@ -2361,8 +2361,8 @@ namespace SolarPower.Repository.Implement
{
var sql = $@"SELECT
PowerStationId,
DATE_FORMAT(p.TIMESTAMP, '%Y-%m'),
AVG(p.Irradiance) AS AvgIrradiance
DATE_FORMAT(p.TIMESTAMP, '%Y-%m') AS TIMESTAMP,
AVG(p.Irradiance) AS Irradiance
FROM pyrheliometer_history_hour p
WHERE DATE_FORMAT(p.TIMESTAMP, '%Y-%m') = @Month
AND p.Irradiance != 0
@ -2387,7 +2387,7 @@ namespace SolarPower.Repository.Implement
{
try
{
var sql = $@"SELECT * FROM pyrheliometer_history_month WHERE DATE_FORMAT(p.TIMESTAMP, '%Y-%m') = @Month AND PowerStationId = @PowerStationId";
var sql = $@"SELECT * FROM pyrheliometer_history_month WHERE DATE_FORMAT(TIMESTAMP, '%Y-%m') = @Month AND PowerStationId = @PowerStationId";
result = await conn.QueryFirstOrDefaultAsync<PyrheliometerHistory>(sql, new { Month = month, PowerStationId = powerStationId });
}
@ -2441,7 +2441,7 @@ namespace SolarPower.Repository.Implement
try
{
string sql = @"UPDATE pyrheliometer_history_month SET
Irradiance=@Irradiance,
Irradiance=@Irradiance
WHERE PowerStationId = @PowerStationId
AND TIMESTAMP LIKE CONCAT(@TIMESTAMP, '%')
";

View File

@ -16,5 +16,9 @@ namespace SolarPower.Repository.Interface
Task<List<CapacityDataTable>> GetCapacityDataTableByPowerStationIds(List<int> powerStationIds);
Task<List<PowerStation>> GetListPowerStationByPowerStationIds(List<int> powerStationIds);
Task<List<PowerStation>> GetSolarByCity(MyUser User, UseStatusCityGetPowerStation post);
Task<List<PowerIrradiance>> GetListPowerIrradianceTodayByPowerStationId(int powerStationId, string nowDay);
Task<List<PowerIrradiance>> GetListPowerIrradiance7dayByPowerStationId(int powerStationId, string nowDay);
Task<List<PowerIrradiance>> GetListPowerIrradianceMonthByPowerStationId(int powerStationId, string nowDay);
Task<List<PowerIrradiance>> GetListPowerIrradianceYearByPowerStationId(int powerStationId, string nowDay);
}
}

View File

@ -102,6 +102,7 @@ namespace SolarPower
services.AddSingleton<CalcPowerStationJob>();
services.AddSingleton(
new JobSchedule(jobType: typeof(CalcPowerStationJob), cronExpression: "0 5 * * * ?")
//new JobSchedule(jobType: typeof(CalcPowerStationJob), cronExpression: "0/5 * * * * ?")
);
#endregion
@ -109,6 +110,7 @@ namespace SolarPower
services.AddSingleton<CalcAvgPowerStationJob>();
services.AddSingleton(
new JobSchedule(jobType: typeof(CalcAvgPowerStationJob), cronExpression: "0 0 2 * * ?")
//new JobSchedule(jobType: typeof(CalcAvgPowerStationJob), cronExpression: "0/10 * * * * ?")
);
#endregion
services.AddHostedService<QuartzHostedService>();

View File

@ -31,7 +31,10 @@
<link rel="stylesheet" media="screen, print" href="~/css/formplugins/dropzone/dropzone.css">
<!--Select2-->
<link rel="stylesheet" media="screen, print" href="~/css//formplugins/select2/select2.bundle.css" />
<link rel="stylesheet" media="screen, print" href="~/css/formplugins/select2/select2.bundle.css" />
<!--Chart.js-->
<link rel="stylesheet" media="screen, print" href="~/css/statistics/chartjs/chartjs.css">
<!--Custome CSS-->
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
@ -1121,6 +1124,8 @@
<script src="~/js/formplugins/dropzone/dropzone.js"></script>
<!-- table2excel -->
<script src="~/js/jquery.table2excel.min.js"></script>
<!--Chart.js-->
<script src="~/js/statistics/chartjs/chartjs.bundle.js"></script>
<!-- Custome JS -->
<script src="~/js/site.js" asp-append-version="true"></script>
<script src="~/js/image.zoom.js" asp-append-version="true"></script>

View File

@ -141,7 +141,7 @@
}, 'json');
//#region 載入上傳資料 - 電站圖片
//#region 載入電站圖片
var url_image = "/PowerStation/GetAllPowerStationImage";
var send_data = {
powerStationId: stationId
@ -166,6 +166,223 @@
}, 'json');
//#endregion
//#region 載入圖表資料
var url = "/StationOverview/GetChartUpToDate";
var send_data = {
id: stationId
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
var chartToday = rel.data.chartToday;
var chart7day = rel.data.chart7day;
var chartMonth = rel.data.chartMonth;
var chartYear = rel.data.chartYear;
//#region 今日
var ctx_chartToday = document.getElementById('chartToday').getContext('2d');
var myChartToday = new Chart(ctx_chartToday, {
type: 'bar',
data: {
labels: chartToday.labels,
datasets: [{
type: 'bar',
label: '輸出功率',
yAxisID: 'A',
backgroundColor: color.primary._300,
borderColor: color.primary._500,
data: chartToday.powerDatas
}, {
type: 'line',
label: '日照度',
yAxisID: 'B',
borderColor: color.danger._300,
pointBackgroundColor: color.danger._500,
pointBorderColor: color.danger._500,
pointBorderWidth: 1,
borderWidth: 2,
pointRadius: 4,
pointHoverRadius: 5,
fill: false,
data: chartToday.irradianceDatas,
}]
},
options: {
scales: {
yAxes: [{
id: 'A',
type: 'linear',
position: 'left',
ticks: {
min: 0
}
}, {
id: 'B',
type: 'linear',
position: 'right',
ticks: {
min: 0
}
}]
}
}
});
//#endregion
//#region 7日
var ctx_chart7day = document.getElementById('chart7day').getContext('2d');
var myChart7day = new Chart(ctx_chart7day, {
type: 'bar',
data: {
labels: chart7day.labels,
datasets: [{
type: 'bar',
label: '輸出功率',
yAxisID: 'A',
backgroundColor: color.primary._300,
borderColor: color.primary._500,
data: chart7day.powerDatas
}, {
type: 'line',
label: '日照度',
yAxisID: 'B',
borderColor: color.danger._300,
pointBackgroundColor: color.danger._500,
pointBorderColor: color.danger._500,
pointBorderWidth: 1,
borderWidth: 2,
pointRadius: 4,
pointHoverRadius: 5,
fill: false,
data: chart7day.irradianceDatas,
}]
},
options: {
scales: {
yAxes: [{
id: 'A',
type: 'linear',
position: 'left',
ticks: {
min: 0
}
}, {
id: 'B',
type: 'linear',
position: 'right',
ticks: {
min: 0
}
}]
}
}
});
//#endregion
//#region 本月
var ctx_chartMonth = document.getElementById('chartMonth').getContext('2d');
var myChartMonth = new Chart(ctx_chartMonth, {
type: 'bar',
data: {
labels: chartMonth.labels,
datasets: [{
type: 'bar',
label: '輸出功率',
yAxisID: 'A',
backgroundColor: color.primary._300,
borderColor: color.primary._500,
data: chartMonth.powerDatas
}, {
type: 'line',
label: '日照度',
yAxisID: 'B',
borderColor: color.danger._300,
pointBackgroundColor: color.danger._500,
pointBorderColor: color.danger._500,
pointBorderWidth: 1,
borderWidth: 2,
pointRadius: 4,
pointHoverRadius: 5,
fill: false,
data: chartMonth.irradianceDatas,
}]
},
options: {
scales: {
yAxes: [{
id: 'A',
type: 'linear',
position: 'left',
ticks: {
min: 0
}
}, {
id: 'B',
type: 'linear',
position: 'right',
ticks: {
min: 0
}
}]
}
}
});
//#endregion
//#region 本年
var ctx_chartYear = document.getElementById('chartYear').getContext('2d');
var myChartYear = new Chart(ctx_chartYear, {
type: 'bar',
data: {
labels: chartYear.labels,
datasets: [{
type: 'bar',
label: '輸出功率',
yAxisID: 'A',
backgroundColor: color.primary._300,
borderColor: color.primary._500,
data: chartYear.powerDatas
}, {
type: 'line',
label: '日照度',
yAxisID: 'B',
borderColor: color.danger._300,
pointBackgroundColor: color.danger._500,
pointBorderColor: color.danger._500,
pointBorderWidth: 1,
borderWidth: 2,
pointRadius: 4,
pointHoverRadius: 5,
fill: false,
data: chartYear.irradianceDatas,
}]
},
options: {
scales: {
yAxes: [{
id: 'A',
type: 'linear',
position: 'left',
ticks: {
min: 0
}
}, {
id: 'B',
type: 'linear',
position: 'right',
ticks: {
min: 0
}
}]
}
}
});
//#endregion
}, 'json');
//#endregion
//#endregion

View File

@ -101,20 +101,8 @@
<div class="col-xl-6">
<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="about:blank" data-src="holder.js/800x400?auto=yes&bg=37e2d0&fg=ffffff&text=First slide" alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="about:blank" data-src="holder.js/800x400?auto=yes&bg=21dfcb&fg=ffffff&text=Second slide" alt="Second slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="about:blank" data-src="holder.js/800x400?auto=yes&bg=1dc9b7&fg=ffffff&text=Third slide" alt="Third slide">
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
@ -127,7 +115,40 @@
</div>
</div>
<div class="col-xl-6">
<img src="img/backgrounds/clouds.png" class="img-fluid">
<div id="carousel-chart" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carousel-chart" data-slide-to="0" class="active"></li>
<li data-target="#carousel-chart" data-slide-to="1"></li>
<li data-target="#carousel-chart" data-slide-to="2"></li>
<li data-target="#carousel-chart" data-slide-to="3"></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item active">
<canvas id="chartToday"></canvas>
</div>
<div class="carousel-item">
<canvas id="chart7day"></canvas>
</div>
<div class="carousel-item">
<canvas id="chartMonth"></canvas>
</div>
<div class="carousel-item">
<canvas id="chartYear"></canvas>
</div>
</div>
<a class="carousel-control-prev" href="#carousel-chart" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carousel-chart" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
<div>
<canvas id="myChart"></canvas>
</div>
</div>
</div>
<div class="row mb-5">