New file |
| | |
| | | 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; |
| | | } |
| | | console.log(this.aqiData); |
| | | } |
| | | ); |
| | | } |
| | | // ----------- 空气质量预报(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); |
| | | console.log(windDirName); |
| | | 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 |
| | | ); |
| | | } |
| | | } |