import { Component, OnInit } from "@angular/core";
|
import { _HttpClient } from "@delon/theme";
|
import { zip } from "rxjs/observable/zip";
|
import * as moment from "moment";
|
import { ResultBean } from "@business/entity/grid";
|
|
@Component({
|
selector: "app-home-page",
|
templateUrl: "./home-page.component.html",
|
styleUrls: ["./home-page.component.less"]
|
})
|
export class HomePageComponent implements OnInit {
|
// 页面 构造函数和初始化
|
constructor(private http: _HttpClient) {
|
this.reloadAqiChart();
|
this.reloadMeteChart();
|
}
|
salesData: any[] = [];
|
aqiData: any[] = [];
|
ngOnInit() {
|
zip(
|
this.http.get<any>(
|
"http://sapi.7drlb.com/api/mj?cityID=1102&apiKey=condition"
|
),
|
this.http.get<any>(
|
"http://sapi.7drlb.com/api/mj?cityID=1102&apiKey=aqi"
|
)
|
).subscribe(([conRes, aqiRes]) => {
|
if (conRes.code == 0 && aqiRes.code == 0) {
|
this.cardData.windDirection = conRes.data.condition.windDir;
|
this.cardData.temperature = conRes.data.condition.temp;
|
this.cardData.aqi = aqiRes.data.aqi.value;
|
this.cardData.pm25 = aqiRes.data.aqi.pm25;
|
setTimeout(() => {
|
this.firstRowLoading = false;
|
}, 500);
|
}
|
});
|
|
this.http.get("/chart").subscribe((res: any) => {
|
res.offlineData.forEach((item: any) => {
|
item.chart = Object.assign([], res.offlineChartData);
|
});
|
this.data = res;
|
this.salesData = res.salesData;
|
this.loading = false;
|
this.changeSaleType();
|
});
|
this.setSelectedApiItem();
|
this.setSelectedApiForecastItem();
|
this.setSelectedMeteItem();
|
this.setSelectedApiSortedItem();
|
}
|
|
// ---------------- 实时气象参数 -----------------------------------
|
public cardData: {
|
aqi?: number;
|
temperature?: number;
|
windDirection?: string;
|
pm25?: number;
|
} = {};
|
public firstRowLoading = true;
|
// ---------------- AQI因子柱形图(过去24小时) --------------------------
|
public aqiDataLoading = true;
|
public aqiItems = [
|
{
|
name: "PM2.5",
|
key: "e1",
|
unit: "ug/m³",
|
selected: true
|
},
|
{
|
name: "PM10",
|
key: "e2",
|
unit: "ug/m³",
|
selected: false
|
},
|
{
|
name: "一氧化碳",
|
key: "e10",
|
unit: "mg/m³",
|
selected: false
|
},
|
{
|
name: "二氧化硫",
|
key: "e11",
|
unit: "ug/m³",
|
selected: false
|
},
|
{
|
name: "臭氧",
|
key: "e15",
|
unit: "ug/m³",
|
selected: false
|
},
|
{
|
name: "二氧化氮",
|
key: "e16",
|
unit: "ug/m³",
|
selected: false
|
}
|
];
|
public get selectedApiItem() {
|
return this.aqiItems.find(item => {
|
return !!item.selected;
|
});
|
}
|
public setSelectedApiItem(item?: any) {
|
if (!!item) {
|
this.aqiItems.forEach(it => {
|
if (item.key === it.key) {
|
it.selected = true;
|
} else {
|
it.selected = false;
|
}
|
});
|
}
|
let dValue = 24;
|
const startTime: Date = moment()
|
.subtract(1, "days")
|
.subtract(dValue, "hours")
|
.toDate();
|
const endTime: Date = moment()
|
.subtract(1, "days")
|
.toDate();
|
const key = this.selectedApiItem.key;
|
const lineChartCriteria = {
|
dataConditions: [
|
{
|
areaRangeId: 320583,
|
areaRange: 2,
|
deviceDimension: "NONE",
|
actualTime: null,
|
timeUnits: "HOUR"
|
}
|
],
|
sensorKeys: [key],
|
timePeriod: {
|
startTime: startTime,
|
endTime: endTime,
|
timeUnits: "HOUR"
|
}
|
};
|
this.aqiDataLoading = true;
|
this.http
|
.post("/report/line-chart", lineChartCriteria)
|
.subscribe(
|
(res: ResultBean<{ [key: string]: Array<Array<number>> }>) => {
|
const data = res.data[key][0];
|
if (!!data && data.length > 0) {
|
const mo = moment(startTime);
|
const aqiData = [];
|
for (
|
let index = 0, num = 0;
|
index < dValue;
|
index++, num = 1
|
) {
|
aqiData.push({
|
x: mo.add(num, "hours").hours() + "时",
|
y: data[index]
|
});
|
}
|
this.aqiData = aqiData;
|
this.aqiDataLoading = false;
|
}
|
}
|
);
|
}
|
// ----------- 空气质量预报(24小时) ----------------------------
|
public aqiChartOption = {};
|
public aqiEchartsIntance;
|
public aqiForecastDataLoading = true;
|
public aqiForecastItems = [
|
{
|
name: "PM2.5",
|
key: "e1",
|
unit: "ug/m³",
|
selected: true
|
},
|
{
|
name: "PM10",
|
key: "e2",
|
unit: "ug/m³",
|
selected: false
|
},
|
{
|
name: "一氧化碳",
|
key: "e10",
|
unit: "mg/m³",
|
selected: false
|
},
|
{
|
name: "二氧化硫",
|
key: "e11",
|
unit: "ug/m³",
|
selected: false
|
},
|
{
|
name: "臭氧",
|
key: "e15",
|
unit: "ug/m³",
|
selected: false
|
},
|
{
|
name: "二氧化氮",
|
key: "e16",
|
unit: "ug/m³",
|
selected: false
|
}
|
];
|
public onApiChartInit(e): void {
|
this.aqiEchartsIntance = e;
|
}
|
public get selectedApiForecastItem() {
|
return this.aqiForecastItems.find(item => {
|
return !!item.selected;
|
});
|
}
|
public setSelectedApiForecastItem(item?: any) {
|
if (!!item) {
|
this.aqiForecastItems.forEach(it => {
|
if (item.key === it.key) {
|
it.selected = true;
|
} else {
|
it.selected = false;
|
}
|
});
|
}
|
let dValue = 24;
|
const startTime: Date = moment()
|
.subtract(2, "days")
|
.subtract(dValue, "hours")
|
.toDate();
|
const endTime: Date = moment()
|
.subtract(2, "days")
|
.toDate();
|
const key = this.selectedApiForecastItem.key;
|
const lineChartCriteria = {
|
dataConditions: [
|
{
|
areaRangeId: 320583,
|
areaRange: 2,
|
deviceDimension: "NONE",
|
actualTime: null,
|
timeUnits: "HOUR"
|
}
|
],
|
sensorKeys: [key],
|
timePeriod: {
|
startTime: startTime,
|
endTime: endTime,
|
timeUnits: "HOUR"
|
}
|
};
|
this.aqiForecastDataLoading = true;
|
this.reloadAqiChart();
|
this.http
|
.post("/report/line-chart", lineChartCriteria)
|
.subscribe(
|
(res: ResultBean<{ [key: string]: Array<Array<number>> }>) => {
|
this.aqiForecastDataLoading = false;
|
const data = res.data[key][0];
|
if (!!data && data.length > 0) {
|
this.aqiEchartsIntance.setOption({
|
series: [{ type: "line", data: data }]
|
});
|
}
|
}
|
);
|
}
|
private reloadAqiChart(): void {
|
// const timeList = this.grid.columns.map(item => item.text);
|
// if (!!this.aqiEchartsIntance) {
|
// this.aqiChartOption = null;
|
// this.aqiEchartsIntance.clear();
|
// }
|
// let series = null;
|
// if ( this.chartSelectedIndex < this.grid.data.length ) {
|
// series = [{type: 'line', data: this.grid.data[this.chartSelectedIndex]}];
|
// }
|
|
// this.initOpton(chartOption ,{ xAxis : [{data : []}]});
|
// this.aqiChartOption = true;
|
const hour = moment().hours() + 1;
|
const xList = [
|
...this.newArray(hour, 24 - hour, null, "时"),
|
...this.newArray(0, hour, null, "时")
|
];
|
this.initOpton(this.aqiChartOption, { xAxis: [{ data: xList }] });
|
}
|
private reloadMeteChart(): void {
|
// if (!!this.aqiEchartsIntance) {
|
// this.aqiChartOption = null;
|
// this.aqiEchartsIntance.clear();
|
// }
|
const hour = moment().hours() + 1;
|
const xList = [
|
...this.newArray(hour, 24 - hour, null, "时"),
|
...this.newArray(0, hour, null, "时")
|
];
|
this.initOpton(this.meteChartOption, { xAxis: [{ data: xList }] });
|
}
|
private newArray = (
|
startOrLen: number,
|
len?: number,
|
prefix?: string,
|
suffix?: string
|
) => {
|
const result = [];
|
const s = !!len ? startOrLen : 0;
|
len = !!len ? len : startOrLen;
|
suffix = !!suffix ? suffix : "";
|
prefix = !!prefix ? prefix : "";
|
for (let i = s; result.length < len; i++) {
|
result.push(prefix + i + suffix);
|
}
|
return result;
|
};
|
// ----------- 气象预报(24小时) -------------
|
public meteChartOption = {};
|
public meteEchartsIntance;
|
public meteChartLoading = false;
|
public onMeteChartInit(e): void {
|
this.meteEchartsIntance = e;
|
}
|
public meteItems = [
|
{
|
name: "风速",
|
key: "windSpeed",
|
unit: "m/s",
|
selected: true
|
},
|
{
|
name: "温度",
|
key: "temp",
|
unit: "℃",
|
selected: false
|
},
|
{
|
name: "降水",
|
key: "qpf",
|
unit: "mm",
|
selected: false
|
},
|
{
|
name: "湿度",
|
key: "humidity",
|
unit: "%RH",
|
selected: false
|
},
|
{
|
name: "紫外线",
|
key: "uvi",
|
unit: "毫瓦/平方米",
|
selected: false
|
},
|
{
|
name: "气压",
|
key: "pressure",
|
unit: "Pa",
|
selected: false
|
}
|
];
|
public get selectedMeteItem() {
|
return this.meteItems.find(item => {
|
return !!item.selected;
|
});
|
}
|
public setSelectedMeteItem(item?: any) {
|
if (!!item) {
|
this.meteItems.forEach(it => {
|
if (item.key === it.key) {
|
it.selected = true;
|
} else {
|
it.selected = false;
|
}
|
});
|
}
|
this.reloadMeteChart();
|
this.meteChartLoading = true;
|
const key = this.selectedMeteItem.key;
|
this.http
|
.get(
|
"http://sapi.7drlb.com/api/mj?cityID=1102&apiKey=forecast24hours"
|
)
|
.subscribe((res: any) => {
|
const hourlyData = <any[]>res.data.hourly;
|
if (!!hourlyData && hourlyData.length > 0) {
|
const selectedData = [];
|
let windDirsData = [];
|
hourlyData.forEach((item, index) => {
|
const itemData = item[key];
|
selectedData.push(itemData);
|
let windDirData = item['windDir'];
|
// windDirData = windDirData.length > 2 ? windDirData.substr(1) : windDirData;
|
if(index == 0 ) {
|
const windDirName = this.winToChName(windDirData);
|
windDirsData.push(
|
{
|
value: windDirName,
|
xAxis: index,
|
yAxis: itemData
|
}
|
);
|
} else {
|
let preWindDirData = hourlyData[index-1]['windDir'];
|
// preWindDirData = preWindDirData.length > 2 ? preWindDirData.substr(1) : preWindDirData;
|
if(preWindDirData !== windDirData) {
|
const windDirName = this.winToChName(windDirData);
|
windDirsData.push(
|
{
|
value: windDirName,
|
xAxis: index,
|
yAxis: itemData
|
}
|
);
|
}
|
}
|
});
|
if (!!selectedData && selectedData.length > 0) {
|
this.meteEchartsIntance.setOption({
|
legend: {
|
data:['风向']
|
},
|
series: [
|
{
|
type: 'line',
|
data: selectedData
|
},
|
{
|
name: '风向',
|
type: 'line',
|
itemStyle: {
|
color: '#c23531'
|
},
|
markPoint: {
|
data: windDirsData
|
}
|
}
|
]
|
});
|
this.meteChartLoading = false;
|
}
|
}
|
});
|
}
|
public winToChName(windDir: string) {
|
let name = '';
|
if(!!windDir) {
|
if(windDir.length >1) {
|
windDir = windDir.split('').reverse().join('');
|
}
|
// let index = 0;
|
for (let ch of windDir) {
|
switch(ch) {
|
case 'E':name += '东';break;
|
case 'S':name += '南';break;
|
case 'W':name += '西';break;
|
case 'N':name += '北';break;
|
}
|
// if(windDir.length >2 && index == 1){
|
// name += '偏';
|
// }
|
// index++;
|
}
|
name += '风';
|
}
|
return name;
|
}
|
// ---------------- echart 初始化函数 ---------------------------
|
private initOpton(chartOption, opt: { [key: string]: object }) {
|
const defaultOption = {
|
title: {
|
left: "center"
|
},
|
tooltip: {
|
trigger: "axis",
|
axisPointer: {
|
type: "cross",
|
label: {
|
backgroundColor: "#6a7985"
|
}
|
}
|
},
|
legend: {
|
data: []
|
},
|
toolbox: {
|
feature: {
|
saveAsImage: {}
|
}
|
},
|
grid: {
|
left: "3%",
|
right: "4%",
|
bottom: "3%",
|
containLabel: true
|
},
|
xAxis: [
|
{
|
type: "category",
|
boundaryGap: false
|
}
|
],
|
yAxis: [
|
{
|
type: "value"
|
}
|
],
|
series: []
|
};
|
Object.assign(defaultOption, opt);
|
Object.assign(chartOption, defaultOption);
|
}
|
//---------- 本月站点排序 apiSortedItem ------------------------
|
public apiSortedTableLoading = false;
|
public apiSortedTableList = [];
|
public apiSortedItems = [
|
{
|
name: "PM2.5",
|
key: "e1",
|
unit: "ug/m³",
|
selected: true
|
},
|
{
|
name: "PM10",
|
key: "e2",
|
unit: "ug/m³",
|
selected: false
|
},
|
{
|
name: "一氧化碳",
|
key: "e10",
|
unit: "mg/m³",
|
selected: false
|
},
|
{
|
name: "二氧化硫",
|
key: "e11",
|
unit: "ug/m³",
|
selected: false
|
},
|
{
|
name: "臭氧",
|
key: "e15",
|
unit: "ug/m³",
|
selected: false
|
},
|
{
|
name: "二氧化氮",
|
key: "e16",
|
unit: "ug/m³",
|
selected: false
|
}
|
];
|
public get selectedApiSortedItem() {
|
return this.apiSortedItems.find(item => {
|
return !!item.selected;
|
});
|
}
|
public setSelectedApiSortedItem(item ?: any) {
|
if (!!item) {
|
this.apiSortedItems.forEach(it => {
|
if (item.key === it.key) {
|
it.selected = true;
|
} else {
|
it.selected = false;
|
}
|
});
|
}
|
this.apiSortedTableLoading = true;
|
const params = {sensorKey: this.selectedApiSortedItem.key, dimension: 'monitorPoint', regionCode: '320583', accountId: '1', timeType: 'day'};
|
this.http.get('screen/region_ranking_data',params).subscribe((res: any) => {
|
this.apiSortedTableLoading = false;
|
// console.log(res);
|
this.apiSortedTableList = res.data;
|
});
|
}
|
public aqiSortedTableSort(sortName, sortValue) {
|
this.apiSortedTableList = [
|
...(<any[]>this.apiSortedTableList).sort((a, b) => {
|
if (a[sortName] > b[sortName]) {
|
return (sortValue === 'ascend') ? 1 : -1;
|
} else if (a[sortName] < b[sortName]) {
|
return (sortValue === 'ascend') ? -1 : 1;
|
} else {
|
return 0;
|
}
|
})
|
];
|
}
|
//---------mock-------------------
|
data: any = {
|
salesData: [],
|
offlineData: []
|
};
|
sort(sortName, sortValue) {
|
this.data.searchData = [
|
...(<any[]>this.data.searchData).sort((a, b) => {
|
if (a[sortName] > b[sortName]) {
|
return sortValue === "ascend" ? 1 : -1;
|
} else if (a[sortName] < b[sortName]) {
|
return sortValue === "ascend" ? -1 : 1;
|
} else {
|
return 0;
|
}
|
})
|
];
|
}
|
loading = true;
|
salesType = "all";
|
salesPieData: any;
|
salesTotal = 0;
|
changeSaleType() {
|
this.salesPieData =
|
this.salesType === "all"
|
? this.data.salesTypeData
|
: this.salesType === "online"
|
? this.data.salesTypeDataOnline
|
: this.salesType === "online2"
|
? this.data.salesTypeDataOnline2
|
: this.data.salesTypeDataOffline;
|
if (this.salesPieData)
|
this.salesTotal = this.salesPieData.reduce(
|
(pre, now) => now.y + pre,
|
0
|
);
|
}
|
}
|