统计分析
This commit is contained in:
parent
02ad8ef072
commit
eac0aadd87
@ -43,8 +43,12 @@
|
||||
<div class="tabsPart">
|
||||
<el-table :data="alarmsTableData" class="tablePart" highlight-current-row>
|
||||
<el-table-column prop="eventTimeFormate" :label="AlarmsFieldsEnums['alarmTime']" align="center"> </el-table-column>
|
||||
<el-table-column prop="deviceCode" :label="AlarmsFieldsEnums['airBlowerNumber']" align="center"> </el-table-column>
|
||||
<el-table-column prop="eventText" :label="AlarmsFieldsEnums['faultDescription']" align="center"> </el-table-column>
|
||||
<el-table-column prop="devicecodeName" :label="AlarmsFieldsEnums['airBlowerNumber']" align="center"> </el-table-column>
|
||||
<el-table-column prop="eventText" :label="AlarmsFieldsEnums['faultDescription']" align="center">
|
||||
<template #default="{ row }">
|
||||
<span v-html="formatText(row.eventText)"></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="eventLevel" :label="AlarmsFieldsEnums['alarmType']" align="center">
|
||||
<template #default="scope">
|
||||
<div class="tip" v-if="scope.row.eventLevel === 0">提示</div>
|
||||
@ -199,6 +203,7 @@ const getalarmsList = () => {
|
||||
return {
|
||||
...item,
|
||||
eventTimeFormate: timestampToTime(item.eventTime),
|
||||
devicecodeName: item.deviceName + item.deviceCode,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@ -209,6 +214,13 @@ const getalarmsList = () => {
|
||||
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
|
||||
})
|
||||
}
|
||||
|
||||
const formatText = (text: any) => {
|
||||
text = text.replace(/ 动作/g, '<span style="color:#a03b1d;"> 动作</span>')
|
||||
text = text.replace(/复归/g, '<span style="color:#39baf4;">复归</span>')
|
||||
return text
|
||||
}
|
||||
|
||||
const timestampToTime = (timestamp: any) => {
|
||||
timestamp = timestamp ? timestamp : null
|
||||
let date = new Date(timestamp)
|
||||
|
@ -1,7 +1,17 @@
|
||||
<template>
|
||||
<div class="statAnalysis">
|
||||
<el-menu :default-active="activeIndex" class="headerList" mode="horizontal" @select="handleSelect">
|
||||
<el-menu-item v-for="(item, index) in headerList" :index="index" :key="index"> {{ item }} </el-menu-item>
|
||||
<el-menu-item index="0" key="0"> {{ headerList[0] }} </el-menu-item>
|
||||
<el-popover placement="top-start" :width="200" popper-class="admin-info-box" trigger="hover" content="同一测点,不同时间段对比">
|
||||
<template #reference>
|
||||
<el-menu-item index="1" key="1"> {{ headerList[1] }} </el-menu-item>
|
||||
</template>
|
||||
</el-popover>
|
||||
<el-popover placement="top-start" :width="200" popper-class="admin-info-box" trigger="hover" content="同一时间段,不同测点对比">
|
||||
<template #reference>
|
||||
<el-menu-item index="2" key="2"> {{ headerList[2] }} </el-menu-item>
|
||||
</template>
|
||||
</el-popover>
|
||||
</el-menu>
|
||||
<PowerCurveAnalysis v-if="activeIndex == 0"></PowerCurveAnalysis>
|
||||
<TrendAnalysis v-if="activeIndex == 1"></TrendAnalysis>
|
||||
@ -19,7 +29,6 @@ const config = useConfig()
|
||||
const activeIndex = ref(0)
|
||||
const { t } = useI18n()
|
||||
const headerList = [t('statAnalysis.PowerCurveAnalysis'), t('statAnalysis.trendAnalysis'), t('statAnalysis.trendComparison')]
|
||||
|
||||
const handleSelect = (index: number) => {
|
||||
activeIndex.value = index
|
||||
}
|
||||
|
@ -54,7 +54,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="chartContainer" style="width: 100%; height: 400px; border: 1px solid rgb(217, 217, 217)"></div>
|
||||
<div ref="chartContainer" style="position: absolute; bottom: 0px; width: 100%; height: 400px; border: 1px solid rgb(217, 217, 217)"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
@ -199,7 +199,7 @@ const shortcuts = [
|
||||
text: '今天',
|
||||
value: () => {
|
||||
const start = getFormattedDate(0) + ' 00:00:00'
|
||||
const end = new Date()
|
||||
const end = getFormattedDate(0) + ' 23:59:59'
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
|
@ -34,7 +34,7 @@
|
||||
<el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button>
|
||||
</div>
|
||||
</el-header>
|
||||
<div class="timeColumns" :class="{ expand: isExpand }">
|
||||
<div class="timeColumns">
|
||||
<div class="headerPart" v-for="(time, index) in times" :key="index">
|
||||
<div class="topLeft">
|
||||
<div class="selectPart">
|
||||
@ -75,10 +75,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="times.length > 2" class="ralIcon" @click="handleClick">
|
||||
<el-icon :size="20" color="#0064AA"><DArrowRight /></el-icon>
|
||||
</div>
|
||||
<div ref="chartContainer" style="width: 100%; height: 400px; border: 1px solid rgb(217, 217, 217)"></div>
|
||||
<div ref="chartContainer" style="position: absolute; bottom: 0px; width: 100%; height: 400px; border: 1px solid rgb(217, 217, 217)"></div>
|
||||
<el-dialog v-model="showMeasure" title="测点名称" :width="800">
|
||||
<template #header>
|
||||
<div class="measureSlotHeader">
|
||||
@ -131,10 +128,6 @@ const timechange = (value: any) => {
|
||||
ElMessage.warning('查询时间点错误,请重新输入')
|
||||
}
|
||||
}
|
||||
const isExpand = ref(false)
|
||||
const handleClick = () => {
|
||||
isExpand.value = !isExpand.value
|
||||
}
|
||||
|
||||
const iotModelId = ref('')
|
||||
const irn = ref('')
|
||||
@ -258,7 +251,7 @@ const shortcuts = [
|
||||
text: '今天',
|
||||
value: () => {
|
||||
const start = getFormattedDate(0) + ' 00:00:00'
|
||||
const end = new Date()
|
||||
const end = getFormattedDate(0) + ' 23:59:59'
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
@ -396,14 +389,27 @@ const historyDataReq = (promises: any) => {
|
||||
const deviceId = statAnalysisSelect.deviceId
|
||||
const attributeCode = statAnalysisSelect.attributeCode
|
||||
results.forEach((res: any, index: number) => {
|
||||
console.log(times[index])
|
||||
const resData = (res && deviceId in res && res[deviceId][attributeCode]) || undefined
|
||||
const xData = resData['times']
|
||||
const yData = resData['values']
|
||||
if (!yData.length) {
|
||||
|
||||
if (!resData['values'].length) {
|
||||
ElMessage.info(`${customName[index]}数据为空`)
|
||||
return
|
||||
}
|
||||
calculate.value[index] = calculateStats(yData)
|
||||
const alltimes = getTimestamps(
|
||||
new Date(times[index][0]).getTime(),
|
||||
new Date(times[index][1]).getTime(),
|
||||
statAnalysisSelect.interval || '5m'
|
||||
)
|
||||
console.log(alltimes)
|
||||
console.log('🚀 ~ results.forEach ~ resData:', resData)
|
||||
const fillData = fillMissingData(alltimes, resData)
|
||||
console.log('🚀 ~ results.forEach ~ fillData:', fillData)
|
||||
|
||||
const xData = fillData['times']
|
||||
const yData = fillData['values']
|
||||
console.log(xData)
|
||||
calculate.value[index] = calculateStats(resData['values'])
|
||||
xDatas.push({
|
||||
series: String(customName[index]),
|
||||
data: xData,
|
||||
@ -484,6 +490,52 @@ function calculateStats(numbers: any) {
|
||||
average: average.toFixed(2),
|
||||
}
|
||||
}
|
||||
|
||||
const getTimestamps = (start: any, end: any, interval: any) => {
|
||||
let timestamps = []
|
||||
let current = start
|
||||
|
||||
while (current < end) {
|
||||
timestamps.push(current)
|
||||
switch (interval) {
|
||||
case '5m':
|
||||
current += 5 * 60 * 1000
|
||||
break
|
||||
case '1d':
|
||||
current += 24 * 60 * 60 * 1000
|
||||
break
|
||||
case '15m':
|
||||
current += 15 * 60 * 1000
|
||||
break
|
||||
case 'NONE':
|
||||
current += 40 * 1000
|
||||
break
|
||||
case '1h':
|
||||
current += 60 * 60 * 1000
|
||||
break
|
||||
default:
|
||||
throw new Error('Unsupported interval')
|
||||
}
|
||||
}
|
||||
|
||||
return timestamps
|
||||
}
|
||||
|
||||
const fillMissingData = (intervals: any, data: any) => {
|
||||
const { times, values } = data
|
||||
const filledTimes: any = []
|
||||
const filledValues: any = []
|
||||
intervals.forEach((time: any) => {
|
||||
const index = times.indexOf(time)
|
||||
filledTimes.push(time)
|
||||
if (index !== -1) {
|
||||
filledValues.push(values[index])
|
||||
} else {
|
||||
filledValues.push('')
|
||||
}
|
||||
})
|
||||
return { times: filledTimes, values: filledValues }
|
||||
}
|
||||
const timestampToTime = (timestamp: any) => {
|
||||
timestamp = timestamp ? timestamp : null
|
||||
let date = new Date(timestamp)
|
||||
@ -498,6 +550,9 @@ const timestampToTime = (timestamp: any) => {
|
||||
<style scoped lang="scss">
|
||||
.statAnalysis {
|
||||
height: 100%;
|
||||
.contain {
|
||||
height: calc(100% - 60px);
|
||||
}
|
||||
.headerPart {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
@ -572,24 +627,11 @@ const timestampToTime = (timestamp: any) => {
|
||||
}
|
||||
}
|
||||
.timeColumns {
|
||||
max-height: 120px;
|
||||
overflow: hidden;
|
||||
height: calc(100% - 480px);
|
||||
overflow-y: auto;
|
||||
.headerPart {
|
||||
padding: 10px 20px;
|
||||
padding: 2px 20px;
|
||||
}
|
||||
&.expand {
|
||||
max-height: max-content;
|
||||
height: auto;
|
||||
overflow: inherit;
|
||||
}
|
||||
}
|
||||
.timeColumns.expand + div.ralIcon {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
.ralIcon {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
#myEChart {
|
||||
width: 100%;
|
||||
|
@ -26,7 +26,7 @@
|
||||
<el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button>
|
||||
</div>
|
||||
</el-header>
|
||||
<div class="timeColumns" :class="{ expand: isExpand }">
|
||||
<div class="timeColumns">
|
||||
<div class="headerPart" v-for="(deviceId, index) in statAnalysisDeviceId" :key="index">
|
||||
<div class="topLeft">
|
||||
<div class="selectPart">
|
||||
@ -81,10 +81,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="statAnalysisDeviceId.length > 2" class="ralIcon" @click="handleClick">
|
||||
<el-icon :size="20" color="#0064AA"><DArrowRight /></el-icon>
|
||||
</div>
|
||||
<div ref="chartContainer" style="width: 100%; height: 400px; border: 1px solid rgb(217, 217, 217)"></div>
|
||||
<div ref="chartContainer" style="position: absolute; bottom: 0px; width: 100%; height: 400px; border: 1px solid rgb(217, 217, 217)"></div>
|
||||
<el-dialog v-model="showMeasure" title="测点名称" :width="800">
|
||||
<template #header>
|
||||
<div class="measureSlotHeader">
|
||||
@ -141,10 +138,6 @@ const switchDevice = (index: number) => {
|
||||
calculate.value.splice(index, 1)
|
||||
}
|
||||
|
||||
const isExpand = ref(false)
|
||||
const handleClick = () => {
|
||||
isExpand.value = !isExpand.value
|
||||
}
|
||||
const iotModelId = ref('')
|
||||
const irn = ref('')
|
||||
const selectAtteibutes = (index: number) => {
|
||||
@ -260,7 +253,7 @@ const shortcuts = [
|
||||
text: '今天',
|
||||
value: () => {
|
||||
const start = getFormattedDate(0) + ' 00:00:00'
|
||||
const end = new Date()
|
||||
const end = getFormattedDate(0) + ' 23:59:59'
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
@ -457,6 +450,9 @@ const timestampToTime = (timestamp: any) => {
|
||||
<style scoped lang="scss">
|
||||
.statAnalysis {
|
||||
height: 100%;
|
||||
.contain {
|
||||
height: calc(100% - 60px);
|
||||
}
|
||||
.headerPart {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
@ -531,24 +527,11 @@ const timestampToTime = (timestamp: any) => {
|
||||
}
|
||||
}
|
||||
.timeColumns {
|
||||
max-height: 120px;
|
||||
overflow: hidden;
|
||||
height: calc(100% - 480px);
|
||||
overflow-y: auto;
|
||||
.headerPart {
|
||||
padding: 10px 20px;
|
||||
padding: 2px 20px;
|
||||
}
|
||||
&.expand {
|
||||
max-height: max-content;
|
||||
height: auto;
|
||||
overflow: inherit;
|
||||
}
|
||||
}
|
||||
.timeColumns.expand + div.ralIcon {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
.ralIcon {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
#myEChart {
|
||||
width: 100%;
|
||||
|
Loading…
Reference in New Issue
Block a user