<!-- 日均值 -->
|
<script>
|
import TimeSelectWithShortCuts from '../../sfc/TimeSelectWithShortCuts.vue';
|
import InputSearch from '../../sfc/InputSearch.vue';
|
import AreaAndmonitorType from '../../sfc/AreaAndmonitorType.vue';
|
|
import DustRadarChart from './components/DustRadarChart.vue';
|
import exceptionApi from '@/api/exceptionApi.js';
|
import { useWindowSize } from '@vueuse/core';
|
|
import LineChart from './components/LineChart.vue'
|
|
|
// const DustRadarChart = defineAsyncComponent(() =>
|
// import('./components/DustRadarChart.vue')
|
// )
|
|
import dayjs from 'dayjs';
|
export default {
|
components: {
|
LineChart,
|
TimeSelectWithShortCuts,
|
InputSearch,
|
AreaAndmonitorType,
|
DustRadarChart
|
},
|
data() {
|
return {
|
isNoData: false,
|
loading: false,
|
chartData: [],
|
chartData1: {}, //保存查询的结果
|
chartData2: {},
|
chartData3: {},
|
chartData4: {},
|
//devId:'', //设备编号
|
begin: '', //开始时间
|
end: '', //结束时间
|
|
form: {
|
// 站点名称
|
name: '',
|
// 设备编号
|
number: '',
|
// 开始时间
|
beginTime: '',
|
// 结束时间
|
endTime: ''
|
},
|
// 折线图配置项
|
option: {},
|
// 数据清单
|
bill: {
|
min: '',
|
max: '',
|
avg: '',
|
online: '',
|
valid: '',
|
exceeding: '',
|
|
// 典型异常复现率
|
exceptionRecurrence: '',
|
// 异常类型据聚集度
|
exceptionTypeAggregation: '',
|
|
}
|
};
|
},
|
setup() {
|
const { height } = useWindowSize();
|
return { height };
|
},
|
mounted() {
|
this.fetch();
|
},
|
methods: {
|
/**
|
* 计算异常类型聚集度 异常复现率
|
* @param: 异常数据数组
|
* @returns:
|
*/
|
calRecur(exceptionArr) {
|
// 典型异常复现率
|
let exceptionTyprRecurRate = 0;
|
// 量级突变
|
let mutationCount = 0;
|
// 超标临近
|
let exceedingNearCount = 0;
|
// 超标次数临界
|
let exceedindCriticalDegree = 0;
|
|
// 保存出现的不同异常类型
|
let exception = []
|
// 异常类型聚集度
|
let exceptionTypeAggregation = 0
|
|
exceptionArr.forEach(item => {
|
// 异常复现率
|
if (item.exceptionType == 4) {
|
mutationCount++;
|
} else if (item.exceptionType == 5) {
|
exceedingNearCount++;
|
} else if (item.exceptionType == 6) {
|
exceedindCriticalDegree++;
|
}
|
|
// 异常类型聚集度
|
if(exception.length == 0){
|
exception.push(item.exceptionType)
|
}
|
// 保存新的异常类型
|
else if(exception.indexOf(item.exceptionType) == -1){
|
exception.push(item.exceptionType)
|
}
|
});
|
|
let sum = 0;
|
// 次数减1,该异常出现2次,算复现1次。出现3次,算复现2次...
|
if (mutationCount > 1) {
|
sum = sum + mutationCount - 1;
|
}
|
if (exceedingNearCount > 1) {
|
sum = sum + exceedindCriticalDegree - 1;
|
}
|
if (exceedindCriticalDegree > 1) {
|
sum = sum + exceedindCriticalDegree - 1;
|
}
|
console.log('sum:',sum);
|
console.log('exception:',exception);
|
console.log('其他',mutationCount,exceedindCriticalDegree,exceedindCriticalDegree);
|
switch (sum) {
|
case 0:
|
exceptionTyprRecurRate = sum / 3;
|
break;
|
case 1:
|
exceptionTyprRecurRate = sum / 3;
|
break;
|
case 2:
|
case sum >= 3:
|
exceptionTyprRecurRate = 1;
|
break;
|
default:
|
return 'error';
|
}
|
|
exceptionTypeAggregation = exception.length / 8
|
|
let obj = {}
|
obj['exceptionRecurrence'] = exceptionTyprRecurRate
|
obj['exceptionTypeAggregation'] = exceptionTypeAggregation
|
|
return obj
|
},
|
/**
|
* 计算日期相差几天
|
* @param:
|
* @createTime:开始时间,结束时间
|
* @returns:
|
*/
|
getDaysDifference(startDate, endDate) {
|
// var start = new Date(startDate);
|
// var end = new Date(endDate);
|
// var timeDiff = Math.abs(end.getTime() - start.getTime());
|
// var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
|
|
return dayjs(endDate).diff(startDate,'day') + 1;
|
},
|
/**
|
* 从分析数据数组中找到最小和大值
|
* @param:
|
* @returns:
|
*/
|
calBillData(arr) {
|
let min = 65536;
|
let max = -1;
|
let avg = 0;
|
let online = 0;
|
let valid = 0;
|
let exceeding = 0;
|
|
let sumAvg = 0;
|
let sumOnline = 0;
|
let sumValid = 0;
|
let sumExceeding = 0;
|
|
// 计算选择的时间的相差的天数
|
let begin = dayjs(this.form.beginTime).format('YYYY-MM-DD');
|
let end = dayjs(this.form.endTime).format('YYYY-MM-DD');
|
let dayDiff = this.getDaysDifference(begin, end);
|
console.log('日期间隔',dayDiff);
|
let obj = {};
|
// 计算最小和大值
|
arr.forEach((item) => {
|
if (item.min < min) {
|
min = item.min;
|
}
|
if (item.max > max) {
|
max = item.max;
|
}
|
// 计算平均值,在线率,有效率,超标率
|
sumAvg = sumAvg + item.dayAvg;
|
sumOnline = sumOnline + Number(item.dayOnline.slice(0, -1));
|
sumValid = sumValid + Number(item.dayValid.slice(0, -1));
|
sumExceeding = sumExceeding + Number(item.dayExceeding.slice(0, -1));
|
});
|
// 计算均值
|
avg = sumAvg / dayDiff;
|
// console.log('sumavg:',sumAvg,dayDiff);
|
online = sumOnline / dayDiff;
|
valid = sumValid / dayDiff;
|
exceeding = sumExceeding / dayDiff;
|
obj['min'] = min.toFixed(3);
|
obj['max'] = max.toFixed(3);
|
|
obj['avg'] = avg.toFixed(2);
|
obj['online'] = online.toFixed(2);
|
obj['valid'] = valid.toFixed(2);
|
obj['exceeding'] = exceeding.toFixed(2);
|
|
return obj;
|
},
|
|
/**
|
* 将中国标准时间转为指定格式
|
* @param:
|
* @returns:
|
*/
|
giveTime(val) {
|
//将中国标准时间转为指定格式(该组件返回的标准时间的格式,所以必须的加这个函数)
|
this.form.beginTime = dayjs(val[0]).format('YYYY-MM-DD HH:mm:ss');
|
this.form.endTime = dayjs(val[1]).format('YYYY-MM-DD HH:mm:ss');
|
},
|
/**
|
* 初始加载函数
|
* @param:
|
* @returns:
|
*/
|
fetch() {
|
// 分析数据
|
this.fetchData();
|
// 异常数据
|
this.exceptiondataCount();
|
},
|
|
// 点击展示按钮
|
fetchData() {
|
if (
|
this.form.beginTime >= this.form.endTime &&
|
(this.form.beginTime != null || this.form.endTime != null) &&
|
(this.form.beginTime != '' || tthis.form.endTime != '')
|
) {
|
alert('请输入有效的时间段');
|
return;
|
}
|
let params = {};
|
if (this.form.name) {
|
params['siteName'] = this.form.name;
|
}
|
if (this.form.beginTime) {
|
params['beginTime'] = this.form.beginTime;
|
}
|
if (this.form.endTime) {
|
params['endTime'] = this.form.endTime;
|
}
|
this.loading = true;
|
exceptionApi
|
.analysisdata(this.form.name, this.form.beginTime, this.form.endTime)
|
.then((response) => {
|
this.chartData = response.data.data;
|
this.loading = false;
|
if (response.data.data.length == 0) {
|
this.isNoData = true;
|
return;
|
}
|
// 移除空数据状态
|
this.isNoData = false;
|
this.setChart();
|
|
let temp = this.calBillData(this.chartData);
|
console.log('temp:', temp);
|
this.bill.min = temp['min'];
|
this.bill.max = temp['max'];
|
|
this.bill.avg = temp['avg'];
|
this.bill.online = temp['online'];
|
this.bill.valid = temp['valid'];
|
this.bill.exceeding = temp['exceeding'];
|
|
this.begin = this.chartData[0].lst
|
this.end = this.chartData[this.chartData.length-1].lst
|
});
|
},
|
|
// 选择其他值类型时
|
setChart() {
|
if (this.chartData.length) {
|
// x轴日期时间
|
let dateList = [];
|
//颗粒物平均浓度
|
let dayAvg = [];
|
let dataOnline = [];
|
let dataValid = [];
|
let dataExceed = [];
|
this.chartData.forEach((item) => {
|
//x轴日期
|
dateList.push(item.lst);
|
// 历史油烟浓度
|
dayAvg.push(item.dayAvg);
|
dataOnline.push(item.dayOnline.slice(0, -1));
|
dataValid.push(item.dayValid.slice(0, -1));
|
dataExceed.push(item.dayExceeding.slice(0, -1));
|
});
|
|
this.chartData1 = {
|
x: dateList,
|
y: dayAvg
|
};
|
this.chartData2 = {
|
x: dateList,
|
y: dataOnline
|
};
|
this.chartData3 = {
|
x: dateList,
|
y: dataValid
|
};
|
this.chartData4 = {
|
x: dateList,
|
y: dataExceed
|
};
|
}
|
},
|
|
// 企业异常详情
|
exceptiondataCount() {
|
exceptionApi
|
.exceptiondata1({
|
siteName: this.form.name,
|
beginTime: this.form.beginTime,
|
endTime: this.form.endTime
|
})
|
.then((res) => {
|
console.log('异常:', res.data.data);
|
let obj = this.calRecur(res.data.data)
|
this.bill.exceptionRecurrence = obj['exceptionRecurrence']
|
this.bill.exceptionTypeAggregation = obj['exceptionTypeAggregation']
|
});
|
}
|
}
|
};
|
</script>
|
<template>
|
<div class="search-container">
|
<el-container>
|
<el-main>
|
|
<el-form :inline="true" :model="form">
|
|
<el-form-item>
|
<AreaAndmonitorType></AreaAndmonitorType>
|
</el-form-item>
|
<el-form-item>
|
<InputSearch
|
:isNeedDefaultSite="1"
|
@submit-value="(n) => (form.name = n)"
|
></InputSearch>
|
</el-form-item>
|
|
<el-form-item>
|
<TimeSelectWithShortCuts
|
@submit-time="giveTime"
|
></TimeSelectWithShortCuts>
|
</el-form-item>
|
|
|
<el-form-item>
|
<el-button type="primary" @click="fetch">展示折线图</el-button>
|
</el-form-item>
|
|
</el-form>
|
|
<div class="time-text">数据统计时段:{{ begin}} ~ {{ end }}</div>
|
|
<el-row :gutter="20">
|
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="16" >
|
|
<el-card
|
shadow="never"
|
>
|
<DustRadarChart :name="['数据有效率','典型异常复现率','异常类型聚集度','数据超标率','数据在线率']" :yData="[bill.valid,bill.exceptionRecurrence,bill.exceptionTypeAggregation,bill.exceeding,bill.online]" ></DustRadarChart>
|
</el-card>
|
</el-col>
|
|
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4">
|
<el-card
|
shadow="never"
|
style="width: 200px;min-width: 200px;"
|
>
|
<template #header><span class="title-16">风险详情</span></template>
|
<el-form >
|
<el-form-item label="最大值:">
|
{{ bill.max }} mg/m³
|
</el-form-item>
|
<el-form-item label="最小值:">
|
{{ bill.min }} mg/m³
|
</el-form-item>
|
<el-form-item label="数据有效率:">
|
{{ bill.online }}%
|
</el-form-item>
|
<el-form-item label="数据在线率:">
|
{{ bill.valid }}%
|
</el-form-item>
|
<el-form-item label="数据超标率:">
|
{{ bill.exceeding }}%
|
</el-form-item>
|
<el-form-item label="异常类型聚集度:">
|
{{ bill.exceptionTypeAggregation*100 }}%
|
</el-form-item>
|
<el-form-item label="典型异常复现率:" label-width="auto">
|
{{ bill.exceptionRecurrence*100 }}%
|
</el-form-item>
|
</el-form>
|
<!-- <div class="date-text">最大值:{{ bill.max }} mg/m³</div> -->
|
<!-- <div>最小值:{{ bill.min }} mg/m³</div>
|
<div>均值:{{ bill.avg }} mg/m³</div>
|
<div>数据有效率:{{ bill.online }}%</div>
|
<div>数据在线率:{{ bill.valid }}%</div>
|
<div>数据超标率:{{ bill.exceeding }}%</div>
|
<div>异常类型聚集度:{{ bill.exceptionTypeAggregation*100 }}%</div>
|
<div>典型异常复现率:{{ bill.exceptionRecurrence*100 }}%</div> -->
|
|
</el-card>
|
</el-col>
|
|
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4">
|
<el-card
|
shadow="never"
|
|
style="width:200px; min-width: 200px;"
|
>
|
<template #header>
|
<span class="title-16">风险等级</span>
|
</template>
|
<template #default>
|
<!-- <el-space direction="vertical" :size="15" > -->
|
<div class="container">
|
<div class="block-color heigh"></div> <div>高风险(≥0.6)</div>
|
</div>
|
<div class="container">
|
<div class="block-color medium" ></div> <div>中风险(0.2~0.6)</div>
|
</div>
|
<div class="container">
|
<div class="block-color low"></div><div>低风险(<0.2)</div>
|
</div>
|
|
|
|
<!-- </el-space> -->
|
</template>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
|
|
<el-row :gutter="24">
|
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="6">
|
<el-card
|
shadow="never"
|
|
>
|
<template #default>
|
<LineChart
|
title="日均值"
|
:chartData="chartData1"
|
yName="mg/m³"
|
seriesName="日均值"
|
>
|
</LineChart>
|
</template>
|
</el-card>
|
</el-col>
|
|
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="6">
|
<el-card
|
shadow="never"
|
|
>
|
<template #default>
|
<LineChart
|
title="日在线率"
|
:chartData="chartData2"
|
yName="%"
|
seriesName="日在线率"
|
>
|
</LineChart>
|
</template>
|
</el-card>
|
</el-col>
|
|
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="6">
|
<el-card shadow="never"
|
>
|
<template #default>
|
<LineChart
|
title="日有效率"
|
:chartData="chartData3"
|
yName="%"
|
seriesName="日有效率"
|
>
|
</LineChart>
|
</template>
|
</el-card>
|
</el-col>
|
|
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="6">
|
<el-card shadow="never" >
|
<template #default>
|
<LineChart
|
title="日超标率"
|
:chartData="chartData4"
|
yName="%"
|
seriesName="日超标率"
|
>
|
</LineChart>
|
</template>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
|
|
</el-main>
|
</el-container>
|
</div>
|
</template>
|
|
<style scoped>
|
.time-text {
|
letter-spacing: 2px;
|
}
|
.el-card {
|
margin-top: 15px;
|
border-radius: 9px;
|
}
|
.chart-container {
|
width: 100%;
|
height: 600px;
|
}
|
.el-header {
|
background-color: #010408;
|
color: #333;
|
line-height: 60px;
|
}
|
.container {
|
display: flex;
|
margin-bottom: 10px;
|
}
|
.block-color {
|
width: 1em;
|
height: 1em;
|
margin-right: 10px;
|
margin-top: 3px;
|
}
|
.heigh {
|
background-color: red;
|
}
|
.medium {
|
background-color: #FADC19;
|
}
|
.low {
|
background-color: #9FDB1D;
|
}
|
|
.el-text {
|
align-self: left;
|
}
|
.el-form-item {
|
margin-bottom: 20px;
|
|
}
|
:deep().el-form-item__content {
|
justify-content: flex-end;
|
|
}
|
.title-16 {
|
font-size: 16px;
|
font-weight: bold;
|
}
|
.el-row {
|
}
|
</style>
|