| | |
| | | import { Component, OnInit } from '@angular/core'; |
| | | import { Component, OnInit, ViewChild } from '@angular/core'; |
| | | import { _HttpClient } from '@delon/theme'; |
| | | import { Sensor, Device, DataCondition, MonitorPoint, Organization, LineChartCriteria } from '@business/entity/data'; |
| | | import { TimeUnits, AreaRange, ResultCode, DeviceDimension } from '@business/enum/types.enum'; |
| | | import { SensorsService } from '@business/services/http/sensors.service'; |
| | | import { PageBean, ResultBean, Grid } from '@business/entity/grid'; |
| | | import { NzTreeComponent } from 'ng-tree-antd'; |
| | | import * as moment from 'moment'; |
| | | import { ExampleService } from '@business/services/util/example.service'; |
| | | import { DeviceService } from '@business/services/http/device.service'; |
| | | import { CascaderOption } from 'ng-zorro-antd/src/cascader/nz-cascader.component'; |
| | | import { AreacodeService } from '@business/services/http/areacode.service'; |
| | | import { MonitorPointService } from '@business/services/http/monitor-point.service'; |
| | | import { NzMessageService } from 'ng-zorro-antd'; |
| | | import * as $ from 'jquery'; |
| | | import { DateService } from '@business/services/util/date.service'; |
| | | import { Subject } from 'rxjs/Subject'; |
| | | |
| | | @Component({ |
| | | selector: 'app-enterprise-data', |
| | | templateUrl: './enterprise-data.component.html', |
| | | styleUrls: ['./enterprise-data.component.less'], |
| | | }) |
| | | export class EnterpriseDataComponent implements OnInit { |
| | | |
| | | constructor( |
| | | private http: _HttpClient |
| | | ) { } |
| | | |
| | | ngOnInit() { |
| | | export class EnterpriseDataComponent implements OnInit { |
| | | // aqi六项排序 |
| | | private aqiSort = { |
| | | e1: 1, |
| | | e2: 2, |
| | | e10: 3, |
| | | e11: 4, |
| | | e15: 5, |
| | | e16: 6 |
| | | }; |
| | | |
| | | public tableWidth = 2800; |
| | | // private tableWidthOption = { |
| | | // 'MONTH': 1400, |
| | | // 'DAY': 2800, |
| | | // 'HOUR': 2100, |
| | | // 'MINUTE': 5000 |
| | | // }; |
| | | public expandForm: boolean; // 搜索区 展开控制 |
| | | // public sensors: any[] = []; |
| | | public sensorOptions: any[] = []; |
| | | /** |
| | | * 数据类型,下拉列表数据 |
| | | * 注意,年度类型,对应查询数据单位为月,以此类推 |
| | | * @memberof QueryComponent |
| | | */ |
| | | public timeUnitOptions = [ |
| | | {label: '年', value: TimeUnits.MONTH}, |
| | | {label: '月', value: TimeUnits.DAY}, |
| | | {label: '日', value: TimeUnits.HOUR}, |
| | | {label: '时', value: TimeUnits.MINUTE}, |
| | | ]; |
| | | public timeUnit: {label: string, value: TimeUnits} = this.timeUnitOptions[2]; |
| | | // 默认时间为昨天,今天无数据 |
| | | public actualTime: Date = moment().subtract(1, 'days').toDate(); |
| | | public actualYearOptions: number []; |
| | | public isCollapse = false; |
| | | public isChartCollapse = false; |
| | | // 显示使用 |
| | | public _areas: { label: string, value: string }[] = new Array(); |
| | | public grid: Grid<{sensor: Sensor, data: string [], weight?: number}> = new Grid(); |
| | | // public grid.data: {sensor: Sensor, data: string [], weight?: number} [] = []; |
| | | // 样式控制,设备名称列冻结偏移 |
| | | public sensorNameScrollLeft = 0; |
| | | public sensorNameScrollTop = 0; |
| | | @ViewChild(NzTreeComponent) private tree: NzTreeComponent; |
| | | private _timeType: {showTime: boolean|{[key: string]: Function|boolean}, mode: 'month' | 'day', dateFormat: string } = {showTime: false, mode: 'day', dateFormat: 'YYYY年MM月DD日'}; |
| | | // 用key-value方式,暂存监测项目 |
| | | private _sensors: {[key: string]: string} = {}; |
| | | private _sensorNames: string; |
| | | get sensorNames(): string { |
| | | return this._sensorNames; |
| | | } |
| | | public toggleCollapse() { |
| | | this.isCollapse = !this.isCollapse; |
| | | } |
| | | public toggleChartCollapse() { |
| | | // 打开的时候 |
| | | if (this.isChartCollapse && !!this.echartsIntance) { |
| | | this.reloadChart(); |
| | | this.switchSensor(this.chartSelectedIndex); |
| | | // this.chartLoading = false; |
| | | } |
| | | this.isChartCollapse = !this.isChartCollapse; |
| | | } |
| | | public deviceOptions: Device[] = []; |
| | | public dataCondition: DataCondition = {areaRangeId: 320583, areaRange: AreaRange.AREA, deviceDimension: DeviceDimension.NONE}; |
| | | |
| | | public dimensionOptions: MonitorPoint[] = []; |
| | | |
| | | get actualYear(): number { |
| | | return this.actualTime.getFullYear(); |
| | | } |
| | | set actualYear(year) { |
| | | this.actualTime.setFullYear(Number(year)); |
| | | } |
| | | dimensionsChange(text?: string) { |
| | | switch (this.dimensionItem.value) { |
| | | case DeviceDimension.MONITORPOINT: |
| | | this.monitorPointsChange(text); break; |
| | | case DeviceDimension.PROFESSION: |
| | | this.professionsChange(text); break; |
| | | } |
| | | } |
| | | professionsChange(text?: string) { |
| | | this.http.get<ResultBean<any[]>>('profession/getall').subscribe( |
| | | result => { |
| | | if (!!result.code) { |
| | | this.dimensionOptions = result.data; |
| | | } |
| | | } |
| | | ); |
| | | } |
| | | monitorPointsChange(text?: string) { |
| | | const pageBean: PageBean = { pageIndex: 0, pageSize: 20 }; |
| | | const example = new ExampleService(); |
| | | let areaName = ''; |
| | | switch (this._areas.length) { |
| | | case 1: |
| | | areaName = 'provinceCode'; break; |
| | | case 2: |
| | | areaName = 'cityCode'; break; |
| | | case 3: |
| | | areaName = 'areaCode'; break; |
| | | } |
| | | if (!!text) { |
| | | example.or().andLike({ name: 'name', value: '%' + text + '%' }) |
| | | .andEqualTo({ name: areaName, value: Number(this._areas.slice(-1).pop().value) }); |
| | | } else { |
| | | example.or() |
| | | .andEqualTo({ name: areaName, value: Number(this._areas.slice(-1).pop().value) }); |
| | | } |
| | | this.monitorPointService.getPageByExample(pageBean, example).subscribe( |
| | | (res: PageBean) => { |
| | | if (!!res && !!res.data) { |
| | | this.dimensionOptions = res.data; |
| | | } |
| | | } |
| | | ); |
| | | } |
| | | devicesChange(text?: string) { |
| | | if (!!this.deviceDimension) { |
| | | const example = new ExampleService(); |
| | | const deviceDimensionProperty = |
| | | this.dimensionItem.value === DeviceDimension.MONITORPOINT ? 'monitorPointId' : 'professionId'; |
| | | if (!!text) { |
| | | example.or().andEqualTo({ name: deviceDimensionProperty, value: this.deviceDimension.id }) |
| | | .andLike({name: 'text', value: text}); |
| | | } else { |
| | | example.or().andEqualTo({ name: deviceDimensionProperty, value: this.deviceDimension.id }); |
| | | } |
| | | this.deviceService.getPageByExample(null, example).subscribe( |
| | | (res: PageBean) => { |
| | | if (!!res && !!res.data) { |
| | | this.deviceOptions = res.data; |
| | | } |
| | | } |
| | | ); |
| | | } else { |
| | | this.deviceOptions = []; |
| | | } |
| | | } |
| | | /** |
| | | * 报表属性 |
| | | */ |
| | | public chartLoading: boolean; |
| | | public chartOption; |
| | | public echartsIntance; |
| | | public chartSelectedIndex = 0; |
| | | public onChartInit(e): void { |
| | | this.echartsIntance = e; |
| | | } |
| | | /** |
| | | * 放在 sensor 选项加载完后调用 |
| | | * @param sensorKeys |
| | | */ |
| | | private mockSelectSensors(sensorKeys: string[]) { |
| | | // 模拟选择 aqi 6个参数 |
| | | // Object.keys(this.aqiSort) |
| | | sensorKeys.forEach( key => { |
| | | const sensor = this.sensorOptions[0].children.find( |
| | | sen => sen.sensorKey === key |
| | | ) |
| | | if (!!sensor) { |
| | | sensor['halfChecked'] = false; |
| | | sensor['checked'] = true; |
| | | const event = {node: {data: sensor}}; |
| | | this.onSensorSelect(event); |
| | | } |
| | | }); |
| | | } |
| | | constructor( |
| | | private http: _HttpClient, |
| | | private sensorsService: SensorsService, |
| | | private deviceService: DeviceService, |
| | | private areacodeService: AreacodeService, |
| | | private monitorPointService: MonitorPointService, |
| | | private msg: NzMessageService, |
| | | private dateService: DateService, |
| | | ) { } |
| | | ngOnInit() { |
| | | this.initPage(); |
| | | // 监测项目 tree click 事件 |
| | | this.treeClickStream.debounceTime(1).subscribe( event => { |
| | | const data = event.node.data; |
| | | // console.log(data); |
| | | if (data.id === -1) { |
| | | const children = data.children; |
| | | // 全选状态 |
| | | if (!data.halfChecked && data.checked) { |
| | | // 全取消操作 |
| | | data['checked'] = false; |
| | | data['halfChecked'] = false; |
| | | children.forEach(element => { |
| | | element['checked'] = false; |
| | | }); |
| | | this._sensors = {}; |
| | | // 未选 或者 半选状态 |
| | | } else { |
| | | // 全选操作 |
| | | children.forEach(element => { |
| | | element['checked'] = true; |
| | | this._sensors [element.id] = element.sensorKey; |
| | | }); |
| | | data['checked'] = true; |
| | | data['halfChecked'] = false; |
| | | } |
| | | } else { |
| | | const parentData = event.node.parent.data; |
| | | data['checked'] = !data['checked']; |
| | | if (data['checked']) { |
| | | this._sensors [data.id] = data.sensorKey; |
| | | } else { |
| | | delete this._sensors [data.id]; |
| | | } |
| | | const length = Object.keys(this._sensors).length; |
| | | parentData['halfChecked'] = length > 0 |
| | | && this.sensorOptions[0].children.length > length; |
| | | parentData['checked'] = !parentData['halfChecked'] && length !== 0; |
| | | } |
| | | this.reloadSensorNames(); |
| | | }); |
| | | } |
| | | |
| | | private initPage() { |
| | | this.sensorsService.getPagingList(null, null).subscribe( |
| | | (res: PageBean) => { |
| | | this.sensorOptions.push({id: -1, name: '全部', isExpanded: true, children: res.data}); |
| | | this.mockSelectSensors(Object.keys(this.aqiSort)); |
| | | } |
| | | ); |
| | | this.actualYearOptions = this.newArray(this.actualYear - 9, 10).map(item => Number(item)).reverse(); |
| | | // 省市区 初始值 |
| | | this.http.get('organization/get-my-org').subscribe( |
| | | (res: ResultBean<Organization>) => { |
| | | if (res.code === ResultCode.SUCCESS) { |
| | | const org = res.data; |
| | | const areas = new Array(3); |
| | | if (!!org.areaNames) { |
| | | const areaNames = org.areaNames; |
| | | Object.keys(areaNames).forEach( |
| | | key => { |
| | | const value = areaNames[key]; |
| | | if ( value != null) { |
| | | switch (key) { |
| | | case 'provinceName' : |
| | | areas[0] = {label : value, value: org.provinceCode }; break; |
| | | case 'cityName' : |
| | | areas[1] = {label : value, value: org.cityCode }; break; |
| | | case 'areaName' : |
| | | areas[2] = {label : value, value: org.areaCode }; break; |
| | | } |
| | | } |
| | | } |
| | | ); |
| | | } else { |
| | | for (let i = 0; i < areas.length; i++) { |
| | | switch (i) { |
| | | case 0: |
| | | areas[0] = {label : '江苏省', value: 320000 }; break; |
| | | case 1: |
| | | areas[1] = {label : '苏州市', value: 320500 }; break; |
| | | case 2: |
| | | areas[2] = {label : '昆山市', value: 320583 }; break; |
| | | } |
| | | } |
| | | } |
| | | this.setAreasData(areas); |
| | | } |
| | | } |
| | | ); |
| | | this.dimensionItem = this.dimensions[0]; |
| | | // this.dimensionsChange(); |
| | | } |
| | | public get sensorsLength(): number { |
| | | return this.sensorOptions.length > 0 ? this.sensorOptions[0].children.length : 0; |
| | | } |
| | | public get sensorsSelect(): number { |
| | | return Object.keys(this._sensors).length; |
| | | } |
| | | public areaLazyLoad(event: { option: CascaderOption, index: number, resolve: (children: CascaderOption[]) => void, reject: () => void }) { |
| | | const index = event['index']; |
| | | const option = event.option; |
| | | switch (index) { |
| | | case -1: |
| | | this.areacodeService.getProvinces().subscribe( |
| | | (res: { label: string, value: string }[]) => { |
| | | event.resolve(res); |
| | | } |
| | | ); break; |
| | | case 0: |
| | | this.areacodeService.getCities(option.value).subscribe( |
| | | (res: { label: string, value: string }[]) => { |
| | | event.resolve(res); |
| | | } |
| | | ); break; |
| | | case 1: |
| | | this.areacodeService.getAreas(option.value).subscribe( |
| | | (res: { label: string, value: string }[]) => { |
| | | event.resolve(res); |
| | | } |
| | | ); break; |
| | | } |
| | | } |
| | | // 第一步,省市区 赋值变 并 改变监控站点选项 |
| | | public setAreasData(areas: {label: string, value: string}[] ) { |
| | | let isChanged = false; |
| | | isChanged = areas.some( (item , index: number) => { |
| | | // this._areas[index] 为null 改变 监控站点选项 |
| | | return this._areas.length < areas.length |
| | | || !this._areas[index] |
| | | || this._areas[index].value !== item.value; |
| | | }); |
| | | if ( isChanged ) { |
| | | this._areas = areas; |
| | | this.deviceDimension = null; |
| | | if (this.dimensionItem.value === DeviceDimension.MONITORPOINT) { |
| | | this.dimensionsChange(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 第二步 设置 监控站点, 值变 改变设备选项,值为null 置空设备选项和设备值 |
| | | public dimensionItem: {label: string, value: DeviceDimension}; |
| | | public dimensions: {label: string, value: DeviceDimension}[] = [ |
| | | {label: '监控站点', value: DeviceDimension.MONITORPOINT}, |
| | | {label: '监控行业', value: DeviceDimension.PROFESSION} |
| | | ]; |
| | | public get otherDimensions(): {label: string, value: DeviceDimension}[] { |
| | | return this.dimensions.filter( |
| | | item => { |
| | | return item.value !== this.dimensionItem.value; |
| | | } |
| | | ); |
| | | } |
| | | public selectDimension(option: {label: string, value: DeviceDimension}) { |
| | | this.dimensionItem = option; |
| | | this.dimensionsChange(); |
| | | this._deviceDimension = null; |
| | | // 清空设备选项 |
| | | this.device = null; |
| | | this.deviceOptions = null; |
| | | } |
| | | public _deviceDimension: {id: number, name: string}; |
| | | get deviceDimension(): {id: number, name: string} { |
| | | return this._deviceDimension; |
| | | } |
| | | set deviceDimension(value) { |
| | | if (!!value) { |
| | | // 值变 改变设备选项 |
| | | if (this._deviceDimension !== value) { |
| | | this._deviceDimension = value; // 此处不能提前也不能放后,设备改变要调用 |
| | | this._device = null; // 设备值清空 |
| | | this.devicesChange(); |
| | | } |
| | | // 值为null 置空设备选项和设备值 |
| | | } else { |
| | | this._deviceDimension = null; |
| | | this.device = null; |
| | | this.deviceOptions = null; |
| | | } |
| | | |
| | | } |
| | | // 第三步 设置 监控站点 |
| | | public _device: Device; |
| | | set device(val: Device) { |
| | | this._device = val; |
| | | |
| | | } |
| | | get device(): Device { |
| | | return this._device; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取 传感器名称 |
| | | * |
| | | * @readonly |
| | | * @type {string} |
| | | * @memberof QueryComponent |
| | | */ |
| | | private treeClickStream: Subject<any> = new Subject<any>(); |
| | | public onTreeClickSelect(event): void { |
| | | this.treeClickStream.next(event); |
| | | } |
| | | public onSensorSelect(event): void { |
| | | const data = event.node.data; |
| | | if (data.id === -1 && data.halfChecked === false) { |
| | | if (!!data.checked) { |
| | | this.sensorOptions[0].children.forEach( |
| | | sensor => { |
| | | this._sensors [sensor.id] = sensor.sensorKey; |
| | | } |
| | | ); |
| | | } else { |
| | | this._sensors = {}; |
| | | } |
| | | } else { |
| | | if (!!data.checked) { |
| | | this._sensors [data.id] = data.sensorKey; |
| | | } else { |
| | | delete this._sensors[data.id]; |
| | | } |
| | | } |
| | | this.reloadSensorNames(); |
| | | } |
| | | private reloadSensorNames(): void { |
| | | // 异步提升展现速度 |
| | | setTimeout(() => { |
| | | this._sensorNames = ''; |
| | | const sensorNameList = Object.keys(this._sensors).map( |
| | | id => { |
| | | const sensor = this.sensorOptions[0].children.find(item => { |
| | | return Number(id) === Number(item.id) ; |
| | | }); |
| | | return sensor.name; |
| | | } |
| | | ); |
| | | this._sensorNames = sensorNameList.join(', '); |
| | | }, 1); |
| | | } |
| | | public setTimeUnit(val: {label: string, value: TimeUnits} ) { |
| | | switch (val.value) { |
| | | // YYYY-MM-DD HH:mm:ss |
| | | case TimeUnits.MONTH: |
| | | this._timeType.dateFormat = 'YYYY年'; |
| | | // this._timeType.dateFormat = 'YYYY-MM'; |
| | | // this._timeType.mode = 'month'; |
| | | // this._timeType.endShowTime = null; |
| | | break; |
| | | case TimeUnits.DAY: |
| | | this._timeType.dateFormat = 'YYYY年MM月'; |
| | | this._timeType.mode = 'month'; |
| | | this._timeType.showTime = false; |
| | | break; |
| | | case TimeUnits.HOUR: |
| | | this._timeType.dateFormat = 'YYYY年MM月DD日'; |
| | | this._timeType.mode = 'day'; |
| | | this._timeType.showTime = false; |
| | | break; |
| | | case TimeUnits.MINUTE: |
| | | this._timeType.dateFormat = 'YYYY年MM月DD日 HH时'; |
| | | this._timeType.mode = 'day'; |
| | | this._timeType.showTime = { |
| | | nzHideDisabledOptions: true, |
| | | nzDisabledHours: () => { |
| | | return []; |
| | | }, |
| | | nzDisabledMinutes: (h) => { |
| | | return this.newArray(60).slice(1).map( |
| | | item => Number(item) |
| | | ); |
| | | }, |
| | | nzDisabledSeconds: () => { |
| | | return this.newArray(60).slice(1).map( |
| | | item => Number(item) |
| | | ); |
| | | } |
| | | }; |
| | | break; |
| | | } |
| | | } |
| | | 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; |
| | | } |
| | | public loadGrid(): void { |
| | | // 数据检查 |
| | | const sensors = Object.values(this._sensors); |
| | | if ( sensors.length === 0 ) { |
| | | this.msg.error(' 监测项目 不能为空'); |
| | | return ; |
| | | } |
| | | this.grid.loading = true; |
| | | this.sensorNameScrollLeft = 0; |
| | | this.grid.data = []; |
| | | const start: Date = this.getPeriodDate(this.actualTime , 'start'); |
| | | const end: Date = this.getPeriodDate(this.actualTime , 'end'); |
| | | this.dataCondition['actualTime'] = null; |
| | | this.dataCondition['timeUnits'] = this.timeUnit.value; |
| | | // 设置区域值 |
| | | const dimValue: number = !!this._deviceDimension ? this._deviceDimension.id : null; |
| | | const devValue: number = !!this._device ? this._device.id : null; |
| | | const areasData = [ devValue, dimValue, Number(this._areas.slice(-1).pop().value)]; |
| | | if (!!this.deviceDimension) { |
| | | this.dataCondition.dimensionValue = this._deviceDimension.id; |
| | | this.dataCondition.deviceDimension = this.dimensionItem.value; |
| | | } |
| | | for (let index = 0 ; index < areasData.length ; index++) { |
| | | const item = areasData[index]; |
| | | if ( item !== null ) { |
| | | this.dataCondition.areaRangeId = item; |
| | | switch (index) { |
| | | case 0: this.dataCondition.areaRange = AreaRange.DEVICE; break; |
| | | case 1: |
| | | // 维度为监控点 |
| | | if (this.dimensionItem.value === DeviceDimension.MONITORPOINT) { |
| | | this.dataCondition.areaRange = AreaRange.MONITORPOINT; |
| | | // 维度为行业 |
| | | } else { |
| | | // 重新标定区域范围 |
| | | this.switchAreas(); |
| | | // 重新设置区域值 |
| | | this.dataCondition.areaRangeId = areasData.slice(-1).pop(); |
| | | } break; |
| | | case 2: |
| | | this.switchAreas(); |
| | | break; |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | const dataConditions = [this.dataCondition]; |
| | | const lineChartCriteria: LineChartCriteria = { |
| | | sensorKeys: sensors, |
| | | timePeriod: {startTime: start , endTime: end, timeUnits: this.timeUnit.value }, |
| | | dataConditions: dataConditions |
| | | }; |
| | | const timePeriod = lineChartCriteria.timePeriod; |
| | | switch (timePeriod.timeUnits) { |
| | | case TimeUnits.MONTH: |
| | | this.grid.columns = this.newArray(1, 12, null, '月').map( |
| | | item => { |
| | | return {text: item}; |
| | | } |
| | | ); break; |
| | | case TimeUnits.DAY: |
| | | const mo = moment(lineChartCriteria.timePeriod.startTime); |
| | | const days = mo.endOf('month').date(); |
| | | this.grid.columns = this.newArray(1, days, null, '日').map( |
| | | item => { |
| | | return {text: item}; |
| | | } |
| | | ); break; |
| | | case TimeUnits.HOUR: |
| | | this.grid.columns = this.newArray(0, 24, null, '时').map( |
| | | item => { |
| | | return {text: item}; |
| | | } |
| | | ); break; |
| | | case TimeUnits.MINUTE: |
| | | this.grid.columns = this.newArray(0, 60, null, '分').map( |
| | | item => { |
| | | return {text: item}; |
| | | } |
| | | ); break; |
| | | } |
| | | // 设置表格宽度,要在此处 |
| | | this.tableWidth = this.grid.columns.length * 80 + 160; |
| | | this.reloadChart(); |
| | | // 重设报表标题 |
| | | this.reloadChartTitle(); |
| | | // 清空数据 |
| | | this.grid.data = []; |
| | | console.log(lineChartCriteria); |
| | | this.http.post('/report/line-chart', lineChartCriteria).subscribe( |
| | | (res: ResultBean<{[key: string]: Array<Array<number>>}>) => { |
| | | if (res.code === 1) { |
| | | const data = res.data; |
| | | if (!!data) { |
| | | const sensorKeys = Object.keys(data); |
| | | // aqi六项置前,其他是有数据项 向前。 |
| | | sensorKeys.forEach( |
| | | key => { |
| | | const sensor = (<Array<Sensor>>this.sensorOptions[0].children). |
| | | find(item => { |
| | | return item.sensorKey === key; |
| | | }); |
| | | let weight = this.aqiSort[key]; |
| | | weight = !!weight ? weight : 101; |
| | | // this.gridSensors.push(sensor); |
| | | const sensorData = data[key][0].map( |
| | | value => { |
| | | if (weight > 100) { |
| | | // pair.value 为null,权重后移 |
| | | weight = !!value ? weight : weight + 1; |
| | | } |
| | | // 四舍五入,保留2位 |
| | | return value != null ? String(Math.round(value * 100) / 100) : '-'; |
| | | } |
| | | ); |
| | | this.grid.data.push({sensor: sensor, data: sensorData, weight: weight}); |
| | | } |
| | | ); |
| | | } |
| | | this.grid.data.sort( (a, b) => a.weight - b.weight ); |
| | | this.grid.loading = false; |
| | | this.switchSensor(0); |
| | | } |
| | | } |
| | | ); |
| | | $('.ant-table-body').scroll( |
| | | () => { |
| | | this.sensorNameScrollLeft = $('.ant-table-body').scrollLeft(); |
| | | this.sensorNameScrollTop = -$('.ant-table-body').scrollTop(); |
| | | } |
| | | ); |
| | | } |
| | | private switchAreas(): void { |
| | | switch (this._areas.length ) { |
| | | case 1: this.dataCondition.areaRange = AreaRange.PROVINCE; break; |
| | | case 2: this.dataCondition.areaRange = AreaRange.CITY; break; |
| | | case 3: this.dataCondition.areaRange = AreaRange.AREA; break; |
| | | } |
| | | } |
| | | private reloadChart(): void { |
| | | const timeList = this.grid.columns.map(item => item.text); |
| | | if (!!this.echartsIntance) { |
| | | this.chartOption = null; |
| | | this.echartsIntance.clear(); |
| | | } |
| | | // let series = null; |
| | | // if ( this.chartSelectedIndex < this.grid.data.length ) { |
| | | // series = [{type: 'line', data: this.grid.data[this.chartSelectedIndex]}]; |
| | | // } |
| | | |
| | | this.initOpton({ xAxis : [{data : timeList}]}); |
| | | this.chartLoading = true; |
| | | } |
| | | private initOpton(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 : [ |
| | | ] |
| | | }; |
| | | $.extend(true, defaultOption, opt); |
| | | this.chartOption = defaultOption; |
| | | } |
| | | public get sensorUnit() { |
| | | return this.grid.data[this.chartSelectedIndex].sensor.unit; |
| | | } |
| | | // 报表标题暂存 防止联动 |
| | | public _chartTitleTemp = ''; |
| | | public _tableTitleTemp = ''; |
| | | public reloadChartTitle(): void { |
| | | const names = ['辖区', '地区', '维度', '时间', '项目']; |
| | | switch ( this.dataCondition.areaRange ) { |
| | | case AreaRange.MONITORPOINT : |
| | | names[0] = '监控站点'; |
| | | names[1] = this._deviceDimension.name; break; |
| | | case AreaRange.DEVICE : |
| | | names[0] = '设备'; |
| | | names[1] = this._device.name; break; |
| | | default : |
| | | names[0] = ''; |
| | | names[1] = this._areas.map( item => item.label).join('/'); |
| | | break; |
| | | } |
| | | // 维度命名 |
| | | if (!!this._deviceDimension) { |
| | | switch (this.dataCondition.deviceDimension) { |
| | | case DeviceDimension.PROFESSION : |
| | | names[2] = '[' + this._deviceDimension.name + ']'; |
| | | break; |
| | | default : |
| | | names[2] = ''; |
| | | break; |
| | | } |
| | | } else { |
| | | names[2] = ''; |
| | | } |
| | | |
| | | names[3] = moment(this.actualTime).format(this._timeType.dateFormat); |
| | | if ( this.grid.data.length > this.chartSelectedIndex) { |
| | | names[4] = this.grid.data[this.chartSelectedIndex].sensor.name; |
| | | } |
| | | const title = names.join(' ') + ' 报表'; |
| | | if (title.trim() !== this._chartTitleTemp.trim()) { |
| | | this._chartTitleTemp = title; |
| | | } |
| | | const tableTile = names.slice(0, -1).join(' ') + ' 各项数据'; |
| | | if (tableTile.trim() !== this._tableTitleTemp.trim()) { |
| | | this._tableTitleTemp = tableTile; |
| | | } |
| | | } |
| | | public switchSensor(index: number): void { |
| | | this.chartSelectedIndex = index; |
| | | this.chartLoading = true; |
| | | this.reloadChartTitle(); |
| | | setTimeout(() => { |
| | | const series = [{type: 'line', data: this.grid.data[index].data}]; |
| | | this.echartsIntance.setOption({ |
| | | title: { |
| | | text: this._chartTitleTemp |
| | | }, |
| | | yAxis : [ |
| | | { |
| | | name : '单位:' + this.sensorUnit |
| | | } |
| | | ], |
| | | series: series |
| | | }); |
| | | this.chartLoading = false; |
| | | }, 600); |
| | | } |
| | | private getPeriodDate(value: Date , type?: 'start'|'end' ): Date { |
| | | let month = 0; |
| | | let day = 1; |
| | | let hour = 0; |
| | | let minute = 0; |
| | | let second = 0; |
| | | let millisecond = 0; |
| | | if ('end' === type) { |
| | | month = 11; |
| | | day = 31; |
| | | hour = 23; |
| | | minute = 59; |
| | | second = 59; |
| | | millisecond = 999; |
| | | } |
| | | const mo = moment(value); |
| | | switch ( this.timeUnit.value ) { |
| | | case TimeUnits.MONTH: |
| | | mo.month(month).date(day).hour(hour).minute(minute).second(second).millisecond(millisecond); break; |
| | | case TimeUnits.DAY: |
| | | mo.date(day).hour(hour).minute(minute).second(second).millisecond(millisecond); break; |
| | | case TimeUnits.HOUR: |
| | | mo.hour(hour).minute(minute).second(second).millisecond(millisecond); break; |
| | | case TimeUnits.MINUTE: |
| | | mo.minute(minute).second(second).millisecond(millisecond); break; |
| | | // case TimeUnits.MINUTE: |
| | | // mo.second(second).millisecond(millisecond); break; |
| | | } |
| | | return mo.toDate(); |
| | | } |
| | | public sensorTableFocusIndex = -1; |
| | | public sensorTableFocus(index) { |
| | | this.sensorTableFocusIndex = index; |
| | | } |
| | | |
| | | public sensorTableBlur(index) { |
| | | this.sensorTableFocusIndex = -1; |
| | | } |
| | | public sensorSelectVisible = false; |
| | | public treeMouseOverOccur = false; |
| | | public onTreeMouseOver(event) { |
| | | this.treeMouseOverOccur = true; |
| | | } |
| | | public onTreeMouseOut(event) { |
| | | this.treeMouseOverOccur = false; |
| | | setTimeout(() => { |
| | | if (!this.treeMouseOverOccur) { |
| | | this.sensorSelectVisible = false; |
| | | } |
| | | }, 900); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |