|
|
|
@ -26,7 +26,7 @@
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</el-col>
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
|
|
|
|
<el-col :span="19" :xs="24">
|
|
|
|
<el-col :span="19" :xs="24">
|
|
|
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
|
|
|
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
|
|
|
|
label-width="100px"
|
|
|
|
label-width="100px"
|
|
|
|
@ -43,13 +43,13 @@
|
|
|
|
style="width: 340px"
|
|
|
|
style="width: 340px"
|
|
|
|
></date-picker>
|
|
|
|
></date-picker>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
|
|
<el-form-item>
|
|
|
|
<el-form-item>
|
|
|
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
|
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
|
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
|
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form>
|
|
|
|
</el-form>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 图表联动提示 -->
|
|
|
|
<!-- 图表联动提示 -->
|
|
|
|
<el-alert
|
|
|
|
<el-alert
|
|
|
|
v-if="powerOutageSummary.count > 0"
|
|
|
|
v-if="powerOutageSummary.count > 0"
|
|
|
|
@ -59,7 +59,7 @@
|
|
|
|
show-icon
|
|
|
|
show-icon
|
|
|
|
style="margin-bottom: 10px"
|
|
|
|
style="margin-bottom: 10px"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 停电统计信息 -->
|
|
|
|
<!-- 停电统计信息 -->
|
|
|
|
<el-card v-if="powerOutageSummary.count > 0" class="power-outage-summary" shadow="hover">
|
|
|
|
<el-card v-if="powerOutageSummary.count > 0" class="power-outage-summary" shadow="hover">
|
|
|
|
<div slot="header">
|
|
|
|
<div slot="header">
|
|
|
|
@ -74,7 +74,7 @@
|
|
|
|
<p><strong>总停电时长:</strong> {{ powerOutageSummary.totalDuration }} 小时</p>
|
|
|
|
<p><strong>总停电时长:</strong> {{ powerOutageSummary.totalDuration }} 小时</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</el-card>
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 图表区域 -->
|
|
|
|
<!-- 图表区域 -->
|
|
|
|
<div class="charts-container">
|
|
|
|
<div class="charts-container">
|
|
|
|
<Chart ref="Chart1" class="chart1"/>
|
|
|
|
<Chart ref="Chart1" class="chart1"/>
|
|
|
|
@ -85,9 +85,9 @@
|
|
|
|
</el-row>
|
|
|
|
</el-row>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
<script>
|
|
|
|
|
|
|
|
|
|
|
|
import { getMonitorInfoTree } from '@/api/ems/base/baseMonitorInfo'
|
|
|
|
import { getMonitorInfoTree } from '@/api/ems/base/baseMonitorInfo'
|
|
|
|
import Treeselect from '@riophae/vue-treeselect'
|
|
|
|
import Treeselect from '@riophae/vue-treeselect'
|
|
|
|
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
|
|
|
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
|
|
|
@ -96,10 +96,9 @@
|
|
|
|
import * as echarts from 'echarts'
|
|
|
|
import * as echarts from 'echarts'
|
|
|
|
import {pointSteamInstantList} from "@/api/ems/report/reportPointSteam";
|
|
|
|
import {pointSteamInstantList} from "@/api/ems/report/reportPointSteam";
|
|
|
|
import {listRecordSteamInstant, steamInstantAvg, steamInstantList} from "@/api/ems/record/recordSteamInstant";
|
|
|
|
import {listRecordSteamInstant, steamInstantAvg, steamInstantList} from "@/api/ems/record/recordSteamInstant";
|
|
|
|
import DatePicker from 'vue2-datepicker';
|
|
|
|
import DatePicker from 'vue-datepicker-next';
|
|
|
|
import 'vue2-datepicker/index.css';
|
|
|
|
import 'vue-datepicker-next/index.css';
|
|
|
|
import 'vue2-datepicker/locale/zh-cn';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
export default {
|
|
|
|
name: 'currentSteamCurve',
|
|
|
|
name: 'currentSteamCurve',
|
|
|
|
dicts: ['collect_type'],
|
|
|
|
dicts: ['collect_type'],
|
|
|
|
@ -213,11 +212,11 @@
|
|
|
|
const lastDate = new Date();
|
|
|
|
const lastDate = new Date();
|
|
|
|
lastDate.setDate(nowDate.getDate() - 1)
|
|
|
|
lastDate.setDate(nowDate.getDate() - 1)
|
|
|
|
const yesterday = parseTime(lastDate, '{y}-{m}-{d}')
|
|
|
|
const yesterday = parseTime(lastDate, '{y}-{m}-{d}')
|
|
|
|
|
|
|
|
|
|
|
|
console.log(today,yesterday)
|
|
|
|
console.log(today,yesterday)
|
|
|
|
this.daterangeRecordTime[0] = yesterday+ ' 08:00:00'
|
|
|
|
this.daterangeRecordTime[0] = yesterday+ ' 08:00:00'
|
|
|
|
this.daterangeRecordTime[1] = today + ' 08:00:00'
|
|
|
|
this.daterangeRecordTime[1] = today + ' 08:00:00'
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化图表基础配置
|
|
|
|
// 初始化图表基础配置
|
|
|
|
this.initBaseChartOptions()
|
|
|
|
this.initBaseChartOptions()
|
|
|
|
this.getTreeselect()
|
|
|
|
this.getTreeselect()
|
|
|
|
@ -296,7 +295,7 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 转换计量设备信息数据结构 */
|
|
|
|
/** 转换计量设备信息数据结构 */
|
|
|
|
normalizer(node) {
|
|
|
|
normalizer(node) {
|
|
|
|
if (node.children && !node.children.length) {
|
|
|
|
if (node.children && !node.children.length) {
|
|
|
|
@ -308,7 +307,7 @@
|
|
|
|
children: node.children
|
|
|
|
children: node.children
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 查询电实时数据列表 */
|
|
|
|
/** 查询电实时数据列表 */
|
|
|
|
getList() {
|
|
|
|
getList() {
|
|
|
|
this.loading = true
|
|
|
|
this.loading = true
|
|
|
|
@ -319,13 +318,13 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.getChart()
|
|
|
|
this.getChart()
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 取消按钮
|
|
|
|
// 取消按钮
|
|
|
|
cancel() {
|
|
|
|
cancel() {
|
|
|
|
this.open = false
|
|
|
|
this.open = false
|
|
|
|
this.reset()
|
|
|
|
this.reset()
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 表单重置
|
|
|
|
// 表单重置
|
|
|
|
reset() {
|
|
|
|
reset() {
|
|
|
|
this.form = {
|
|
|
|
this.form = {
|
|
|
|
@ -344,33 +343,33 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.resetForm('form')
|
|
|
|
this.resetForm('form')
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 搜索按钮操作 */
|
|
|
|
/** 搜索按钮操作 */
|
|
|
|
handleQuery() {
|
|
|
|
handleQuery() {
|
|
|
|
this.getList()
|
|
|
|
this.getList()
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 重置按钮操作 */
|
|
|
|
/** 重置按钮操作 */
|
|
|
|
resetQuery() {
|
|
|
|
resetQuery() {
|
|
|
|
this.queryParams.monitorCode = null
|
|
|
|
this.queryParams.monitorCode = null
|
|
|
|
this.resetForm('queryForm')
|
|
|
|
this.resetForm('queryForm')
|
|
|
|
this.handleQuery()
|
|
|
|
this.handleQuery()
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 导出按钮操作 */
|
|
|
|
/** 导出按钮操作 */
|
|
|
|
handleExport() {
|
|
|
|
handleExport() {
|
|
|
|
this.download('ems/record/recordSteamInstant/export', {
|
|
|
|
this.download('ems/record/recordSteamInstant/export', {
|
|
|
|
...this.queryParams
|
|
|
|
...this.queryParams
|
|
|
|
}, `recordSteamInstant_${new Date().getTime()}.xlsx`)
|
|
|
|
}, `recordSteamInstant_${new Date().getTime()}.xlsx`)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 导出停电数据 */
|
|
|
|
/** 导出停电数据 */
|
|
|
|
exportPowerOutageData() {
|
|
|
|
exportPowerOutageData() {
|
|
|
|
if (this.powerOutageList.length === 0) {
|
|
|
|
if (this.powerOutageList.length === 0) {
|
|
|
|
this.$message.warning('没有停电数据可导出');
|
|
|
|
this.$message.warning('没有停电数据可导出');
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 准备导出数据
|
|
|
|
// 准备导出数据
|
|
|
|
const columns = [
|
|
|
|
const columns = [
|
|
|
|
{label: '序号', prop: 'index'},
|
|
|
|
{label: '序号', prop: 'index'},
|
|
|
|
@ -378,7 +377,7 @@
|
|
|
|
{label: '结束时间', prop: 'endTime'},
|
|
|
|
{label: '结束时间', prop: 'endTime'},
|
|
|
|
{label: '持续时间(小时)', prop: 'duration'}
|
|
|
|
{label: '持续时间(小时)', prop: 'duration'}
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
let table = '<table border="1" cellspacing="0" cellpadding="5">';
|
|
|
|
let table = '<table border="1" cellspacing="0" cellpadding="5">';
|
|
|
|
// 添加表头
|
|
|
|
// 添加表头
|
|
|
|
table += '<tr>';
|
|
|
|
table += '<tr>';
|
|
|
|
@ -386,7 +385,7 @@
|
|
|
|
table += `<th>${col.label}</th>`;
|
|
|
|
table += `<th>${col.label}</th>`;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
table += '</tr>';
|
|
|
|
table += '</tr>';
|
|
|
|
|
|
|
|
|
|
|
|
// 添加数据行
|
|
|
|
// 添加数据行
|
|
|
|
this.powerOutageList.forEach(item => {
|
|
|
|
this.powerOutageList.forEach(item => {
|
|
|
|
table += '<tr>';
|
|
|
|
table += '<tr>';
|
|
|
|
@ -396,7 +395,7 @@
|
|
|
|
table += '</tr>';
|
|
|
|
table += '</tr>';
|
|
|
|
});
|
|
|
|
});
|
|
|
|
table += '</table>';
|
|
|
|
table += '</table>';
|
|
|
|
|
|
|
|
|
|
|
|
// 创建临时HTML文件下载
|
|
|
|
// 创建临时HTML文件下载
|
|
|
|
const deviceName = this.selectMonitorName || '设备';
|
|
|
|
const deviceName = this.selectMonitorName || '设备';
|
|
|
|
const fileName = `${deviceName}停电记录_${new Date().getTime()}.xls`;
|
|
|
|
const fileName = `${deviceName}停电记录_${new Date().getTime()}.xls`;
|
|
|
|
@ -407,27 +406,27 @@
|
|
|
|
link.click();
|
|
|
|
link.click();
|
|
|
|
URL.revokeObjectURL(link.href);
|
|
|
|
URL.revokeObjectURL(link.href);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 查询计量设备信息下拉树结构 */
|
|
|
|
/** 查询计量设备信息下拉树结构 */
|
|
|
|
getTreeselect() {
|
|
|
|
getTreeselect() {
|
|
|
|
getMonitorInfoTree({ monitorType: 4 }).then(response => {
|
|
|
|
getMonitorInfoTree({ monitorType: 4 }).then(response => {
|
|
|
|
this.monitorInfoOptions = response.data
|
|
|
|
this.monitorInfoOptions = response.data
|
|
|
|
})
|
|
|
|
})
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 筛选节点 */
|
|
|
|
/** 筛选节点 */
|
|
|
|
filterNode(value, data) {
|
|
|
|
filterNode(value, data) {
|
|
|
|
if (!value) return true
|
|
|
|
if (!value) return true
|
|
|
|
return data.label.indexOf(value) !== -1
|
|
|
|
return data.label.indexOf(value) !== -1
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 节点单击事件 */
|
|
|
|
/** 节点单击事件 */
|
|
|
|
handleNodeClick(data) {
|
|
|
|
handleNodeClick(data) {
|
|
|
|
this.queryParams.monitorCode = data.code
|
|
|
|
this.queryParams.monitorCode = data.code
|
|
|
|
this.selectMonitorName = data.label
|
|
|
|
this.selectMonitorName = data.label
|
|
|
|
this.handleQuery()
|
|
|
|
this.handleQuery()
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 数据抽样处理,当数据量大时进行抽样
|
|
|
|
* 数据抽样处理,当数据量大时进行抽样
|
|
|
|
* @param {Array} dataArray 原始数据数组
|
|
|
|
* @param {Array} dataArray 原始数据数组
|
|
|
|
@ -437,24 +436,24 @@
|
|
|
|
if (!dataArray || dataArray.length <= this.samplingThreshold) {
|
|
|
|
if (!dataArray || dataArray.length <= this.samplingThreshold) {
|
|
|
|
return dataArray;
|
|
|
|
return dataArray;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 计算抽样间隔
|
|
|
|
// 计算抽样间隔
|
|
|
|
const interval = Math.ceil(dataArray.length / this.samplingThreshold);
|
|
|
|
const interval = Math.ceil(dataArray.length / this.samplingThreshold);
|
|
|
|
const sampledData = [];
|
|
|
|
const sampledData = [];
|
|
|
|
|
|
|
|
|
|
|
|
// 抽样处理,保留首尾数据
|
|
|
|
// 抽样处理,保留首尾数据
|
|
|
|
for (let i = 0; i < dataArray.length; i += interval) {
|
|
|
|
for (let i = 0; i < dataArray.length; i += interval) {
|
|
|
|
sampledData.push(dataArray[i]);
|
|
|
|
sampledData.push(dataArray[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确保最后一个数据点被包含
|
|
|
|
// 确保最后一个数据点被包含
|
|
|
|
if (sampledData[sampledData.length - 1] !== dataArray[dataArray.length - 1]) {
|
|
|
|
if (sampledData[sampledData.length - 1] !== dataArray[dataArray.length - 1]) {
|
|
|
|
sampledData.push(dataArray[dataArray.length - 1]);
|
|
|
|
sampledData.push(dataArray[dataArray.length - 1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return sampledData;
|
|
|
|
return sampledData;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 处理时间间隔大于1小时的数据,插入标红的0值点
|
|
|
|
* 处理时间间隔大于1小时的数据,插入标红的0值点
|
|
|
|
* @param {Array} originalData 原始数据数组
|
|
|
|
* @param {Array} originalData 原始数据数组
|
|
|
|
@ -464,7 +463,7 @@
|
|
|
|
processDataBreaks(originalData, valueField) {
|
|
|
|
processDataBreaks(originalData, valueField) {
|
|
|
|
// 先进行数据抽样处理
|
|
|
|
// 先进行数据抽样处理
|
|
|
|
const sampledData = this.sampleData(originalData);
|
|
|
|
const sampledData = this.sampleData(originalData);
|
|
|
|
|
|
|
|
|
|
|
|
if (!sampledData || sampledData.length < 2) {
|
|
|
|
if (!sampledData || sampledData.length < 2) {
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
processedData: sampledData || [],
|
|
|
|
processedData: sampledData || [],
|
|
|
|
@ -474,28 +473,28 @@
|
|
|
|
markAreas: []
|
|
|
|
markAreas: []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 按时间排序(确保数据按时间顺序)
|
|
|
|
// 按时间排序(确保数据按时间顺序)
|
|
|
|
const sortedData = [...sampledData].sort((a, b) => {
|
|
|
|
const sortedData = [...sampledData].sort((a, b) => {
|
|
|
|
return new Date(a.recordTime) - new Date(b.recordTime)
|
|
|
|
return new Date(a.recordTime) - new Date(b.recordTime)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const processedData = []
|
|
|
|
const processedData = []
|
|
|
|
const markPoints = []
|
|
|
|
const markPoints = []
|
|
|
|
const markAreas = []
|
|
|
|
const markAreas = []
|
|
|
|
const powerOutages = []
|
|
|
|
const powerOutages = []
|
|
|
|
const oneHourMs = 60 * 60 * 1000 // 1小时的毫秒数
|
|
|
|
const oneHourMs = 60 * 60 * 1000 // 1小时的毫秒数
|
|
|
|
|
|
|
|
|
|
|
|
// 遍历并处理数据
|
|
|
|
// 遍历并处理数据
|
|
|
|
for (let i = 0; i < sortedData.length; i++) {
|
|
|
|
for (let i = 0; i < sortedData.length; i++) {
|
|
|
|
processedData.push(sortedData[i])
|
|
|
|
processedData.push(sortedData[i])
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否有数据中断
|
|
|
|
// 检查是否有数据中断
|
|
|
|
if (i < sortedData.length - 1) {
|
|
|
|
if (i < sortedData.length - 1) {
|
|
|
|
const currentTime = new Date(sortedData[i].recordTime).getTime()
|
|
|
|
const currentTime = new Date(sortedData[i].recordTime).getTime()
|
|
|
|
const nextTime = new Date(sortedData[i + 1].recordTime).getTime()
|
|
|
|
const nextTime = new Date(sortedData[i + 1].recordTime).getTime()
|
|
|
|
const timeDiff = nextTime - currentTime
|
|
|
|
const timeDiff = nextTime - currentTime
|
|
|
|
|
|
|
|
|
|
|
|
// 如果时间间隔大于1小时,插入中断点
|
|
|
|
// 如果时间间隔大于1小时,插入中断点
|
|
|
|
if (timeDiff > oneHourMs) {
|
|
|
|
if (timeDiff > oneHourMs) {
|
|
|
|
// 计算中断点时间(当前时间点后1分钟)
|
|
|
|
// 计算中断点时间(当前时间点后1分钟)
|
|
|
|
@ -503,15 +502,15 @@
|
|
|
|
const breakTimeStr = parseTime(breakTime, '{y}-{m}-{d} {h}:{i}:{s}')
|
|
|
|
const breakTimeStr = parseTime(breakTime, '{y}-{m}-{d} {h}:{i}:{s}')
|
|
|
|
const endBreakTime = new Date(nextTime - 60000)
|
|
|
|
const endBreakTime = new Date(nextTime - 60000)
|
|
|
|
const endBreakTimeStr = parseTime(endBreakTime, '{y}-{m}-{d} {h}:{i}:{s}')
|
|
|
|
const endBreakTimeStr = parseTime(endBreakTime, '{y}-{m}-{d} {h}:{i}:{s}')
|
|
|
|
|
|
|
|
|
|
|
|
// 创建中断数据点
|
|
|
|
// 创建中断数据点
|
|
|
|
const breakPoint = { ...sortedData[i] }
|
|
|
|
const breakPoint = { ...sortedData[i] }
|
|
|
|
breakPoint.recordTime = breakTimeStr
|
|
|
|
breakPoint.recordTime = breakTimeStr
|
|
|
|
breakPoint[valueField] = 0
|
|
|
|
breakPoint[valueField] = 0
|
|
|
|
breakPoint.isBreakPoint = true // 标记为中断点
|
|
|
|
breakPoint.isBreakPoint = true // 标记为中断点
|
|
|
|
|
|
|
|
|
|
|
|
processedData.push(breakPoint)
|
|
|
|
processedData.push(breakPoint)
|
|
|
|
|
|
|
|
|
|
|
|
// 添加标记点信息
|
|
|
|
// 添加标记点信息
|
|
|
|
markPoints.push({
|
|
|
|
markPoints.push({
|
|
|
|
value: '停电',
|
|
|
|
value: '停电',
|
|
|
|
@ -524,7 +523,7 @@
|
|
|
|
color: 'red'
|
|
|
|
color: 'red'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 标记区域
|
|
|
|
// 标记区域
|
|
|
|
markAreas.push([
|
|
|
|
markAreas.push([
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -535,7 +534,7 @@
|
|
|
|
xAxis: endBreakTimeStr,
|
|
|
|
xAxis: endBreakTimeStr,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
])
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
// 记录停电信息
|
|
|
|
// 记录停电信息
|
|
|
|
const durationHours = (timeDiff / (1000 * 60 * 60)).toFixed(2);
|
|
|
|
const durationHours = (timeDiff / (1000 * 60 * 60)).toFixed(2);
|
|
|
|
powerOutages.push({
|
|
|
|
powerOutages.push({
|
|
|
|
@ -546,20 +545,20 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新停电统计信息
|
|
|
|
// 更新停电统计信息
|
|
|
|
this.updatePowerOutageSummary(powerOutages);
|
|
|
|
this.updatePowerOutageSummary(powerOutages);
|
|
|
|
|
|
|
|
|
|
|
|
// 提取时间和数值数据
|
|
|
|
// 提取时间和数值数据
|
|
|
|
const timeData = processedData.map(e => e.recordTime)
|
|
|
|
const timeData = processedData.map(e => e.recordTime)
|
|
|
|
const valueData = processedData.map(e => e[valueField])
|
|
|
|
const valueData = processedData.map(e => e[valueField])
|
|
|
|
|
|
|
|
|
|
|
|
// 计算平均值时排除中断点
|
|
|
|
// 计算平均值时排除中断点
|
|
|
|
const validData = processedData.filter(item => !item.isBreakPoint)
|
|
|
|
const validData = processedData.filter(item => !item.isBreakPoint)
|
|
|
|
const validValues = validData.map(e => parseFloat(e[valueField]))
|
|
|
|
const validValues = validData.map(e => parseFloat(e[valueField]))
|
|
|
|
const average = validValues.length > 0 ?
|
|
|
|
const average = validValues.length > 0 ?
|
|
|
|
(validValues.reduce((a, b) => a + b, 0) / validValues.length).toFixed(2) : 0
|
|
|
|
(validValues.reduce((a, b) => a + b, 0) / validValues.length).toFixed(2) : 0
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
processedData,
|
|
|
|
processedData,
|
|
|
|
timeData,
|
|
|
|
timeData,
|
|
|
|
@ -569,7 +568,7 @@
|
|
|
|
average
|
|
|
|
average
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 更新停电统计信息
|
|
|
|
* 更新停电统计信息
|
|
|
|
* @param {Array} powerOutages 停电记录数组
|
|
|
|
* @param {Array} powerOutages 停电记录数组
|
|
|
|
@ -584,24 +583,24 @@
|
|
|
|
this.powerOutageList = [];
|
|
|
|
this.powerOutageList = [];
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 计算总停电时长和最长停电时长
|
|
|
|
// 计算总停电时长和最长停电时长
|
|
|
|
let totalDuration = 0;
|
|
|
|
let totalDuration = 0;
|
|
|
|
let longestDuration = 0;
|
|
|
|
let longestDuration = 0;
|
|
|
|
|
|
|
|
|
|
|
|
powerOutages.forEach((outage, index) => {
|
|
|
|
powerOutages.forEach((outage, index) => {
|
|
|
|
const duration = parseFloat(outage.duration);
|
|
|
|
const duration = parseFloat(outage.duration);
|
|
|
|
totalDuration += duration;
|
|
|
|
totalDuration += duration;
|
|
|
|
longestDuration = Math.max(longestDuration, duration);
|
|
|
|
longestDuration = Math.max(longestDuration, duration);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 更新停电统计信息
|
|
|
|
// 更新停电统计信息
|
|
|
|
this.powerOutageSummary = {
|
|
|
|
this.powerOutageSummary = {
|
|
|
|
count: powerOutages.length,
|
|
|
|
count: powerOutages.length,
|
|
|
|
totalDuration: totalDuration.toFixed(2),
|
|
|
|
totalDuration: totalDuration.toFixed(2),
|
|
|
|
longestDuration: longestDuration.toFixed(2)
|
|
|
|
longestDuration: longestDuration.toFixed(2)
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 更新停电详情列表
|
|
|
|
// 更新停电详情列表
|
|
|
|
this.powerOutageList = powerOutages.map((outage, index) => ({
|
|
|
|
this.powerOutageList = powerOutages.map((outage, index) => ({
|
|
|
|
index: index + 1,
|
|
|
|
index: index + 1,
|
|
|
|
@ -610,7 +609,7 @@
|
|
|
|
duration: outage.duration
|
|
|
|
duration: outage.duration
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 创建图表配置
|
|
|
|
* 创建图表配置
|
|
|
|
* @param {String} title 图表标题
|
|
|
|
* @param {String} title 图表标题
|
|
|
|
@ -623,7 +622,7 @@
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
createChartOption(title, dataResult, name, yAxisName, color, tooltipFormatter) {
|
|
|
|
createChartOption(title, dataResult, name, yAxisName, color, tooltipFormatter) {
|
|
|
|
const option = JSON.parse(JSON.stringify(this.baseChartOptions));
|
|
|
|
const option = JSON.parse(JSON.stringify(this.baseChartOptions));
|
|
|
|
|
|
|
|
|
|
|
|
// 设置标题
|
|
|
|
// 设置标题
|
|
|
|
option.title = {
|
|
|
|
option.title = {
|
|
|
|
text: this.selectMonitorName + ' ' + title + ' (平均值:' + dataResult.average + ")",
|
|
|
|
text: this.selectMonitorName + ' ' + title + ' (平均值:' + dataResult.average + ")",
|
|
|
|
@ -632,16 +631,16 @@
|
|
|
|
fontSize: 15
|
|
|
|
fontSize: 15
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 设置X轴数据
|
|
|
|
// 设置X轴数据
|
|
|
|
option.xAxis.data = dataResult.timeData;
|
|
|
|
option.xAxis.data = dataResult.timeData;
|
|
|
|
|
|
|
|
|
|
|
|
// 设置Y轴名称
|
|
|
|
// 设置Y轴名称
|
|
|
|
option.yAxis.name = yAxisName;
|
|
|
|
option.yAxis.name = yAxisName;
|
|
|
|
option.yAxis.nameTextStyle = {
|
|
|
|
option.yAxis.nameTextStyle = {
|
|
|
|
color: '#000000'
|
|
|
|
color: '#000000'
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 设置提示格式化
|
|
|
|
// 设置提示格式化
|
|
|
|
option.tooltip.formatter = tooltipFormatter || function(params) {
|
|
|
|
option.tooltip.formatter = tooltipFormatter || function(params) {
|
|
|
|
const dataIndex = params[0].dataIndex;
|
|
|
|
const dataIndex = params[0].dataIndex;
|
|
|
|
@ -651,7 +650,7 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return params[0].seriesName + ': ' + params[0].value + '<br/>时间: ' + params[0].axisValue;
|
|
|
|
return params[0].seriesName + ': ' + params[0].value + '<br/>时间: ' + params[0].axisValue;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 设置数据系列
|
|
|
|
// 设置数据系列
|
|
|
|
option.series = [{
|
|
|
|
option.series = [{
|
|
|
|
name: name,
|
|
|
|
name: name,
|
|
|
|
@ -687,55 +686,55 @@
|
|
|
|
silent: true
|
|
|
|
silent: true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
return option;
|
|
|
|
return option;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 曲线 */
|
|
|
|
/** 曲线 */
|
|
|
|
async getChart() {
|
|
|
|
async getChart() {
|
|
|
|
this.loading = true;
|
|
|
|
this.loading = true;
|
|
|
|
let query = JSON.parse(JSON.stringify(this.queryParams))
|
|
|
|
let query = JSON.parse(JSON.stringify(this.queryParams))
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const {data} = await steamInstantList(query)
|
|
|
|
const {data} = await steamInstantList(query)
|
|
|
|
|
|
|
|
|
|
|
|
// 处理瞬时流量数据
|
|
|
|
// 处理瞬时流量数据
|
|
|
|
const fluxFlowResult = this.processDataBreaks(data, 'fluxFlow')
|
|
|
|
const fluxFlowResult = this.processDataBreaks(data, 'fluxFlow')
|
|
|
|
// 处理温度数据
|
|
|
|
// 处理温度数据
|
|
|
|
const temperatureResult = this.processDataBreaks(data, 'temperature')
|
|
|
|
const temperatureResult = this.processDataBreaks(data, 'temperature')
|
|
|
|
// 处理压力数据
|
|
|
|
// 处理压力数据
|
|
|
|
const pressResult = this.processDataBreaks(data, 'press')
|
|
|
|
const pressResult = this.processDataBreaks(data, 'press')
|
|
|
|
|
|
|
|
|
|
|
|
// 创建图表配置
|
|
|
|
// 创建图表配置
|
|
|
|
const option1 = this.createChartOption(
|
|
|
|
const option1 = this.createChartOption(
|
|
|
|
'瞬时流量',
|
|
|
|
'瞬时流量',
|
|
|
|
fluxFlowResult,
|
|
|
|
fluxFlowResult,
|
|
|
|
'瞬时流量',
|
|
|
|
'瞬时流量',
|
|
|
|
'瞬时流量y',
|
|
|
|
'瞬时流量y',
|
|
|
|
'#5470c6'
|
|
|
|
'#5470c6'
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const option2 = this.createChartOption(
|
|
|
|
const option2 = this.createChartOption(
|
|
|
|
'温度',
|
|
|
|
'温度',
|
|
|
|
temperatureResult,
|
|
|
|
temperatureResult,
|
|
|
|
'温度',
|
|
|
|
'温度',
|
|
|
|
'温度y',
|
|
|
|
'温度y',
|
|
|
|
'#91cc75'
|
|
|
|
'#91cc75'
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const option3 = this.createChartOption(
|
|
|
|
const option3 = this.createChartOption(
|
|
|
|
'压力',
|
|
|
|
'压力',
|
|
|
|
pressResult,
|
|
|
|
pressResult,
|
|
|
|
'压力',
|
|
|
|
'压力',
|
|
|
|
'压力y',
|
|
|
|
'压力y',
|
|
|
|
'#fac858'
|
|
|
|
'#fac858'
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
this.$refs.Chart1.setData(option1)
|
|
|
|
this.$refs.Chart1.setData(option1)
|
|
|
|
this.$refs.Chart2.setData(option2)
|
|
|
|
this.$refs.Chart2.setData(option2)
|
|
|
|
this.$refs.Chart3.setData(option3)
|
|
|
|
this.$refs.Chart3.setData(option3)
|
|
|
|
|
|
|
|
|
|
|
|
echarts.connect(this.$refs.Chart1.chart, this.$refs.Chart2.chart, this.$refs.Chart3.chart)
|
|
|
|
echarts.connect(this.$refs.Chart1.chart, this.$refs.Chart2.chart, this.$refs.Chart3.chart)
|
|
|
|
|
|
|
|
|
|
|
|
// 同步缩放
|
|
|
|
// 同步缩放
|
|
|
|
this.$refs.Chart1.chart.on('datazoom', (e) => {
|
|
|
|
this.$refs.Chart1.chart.on('datazoom', (e) => {
|
|
|
|
option2.dataZoom[0].start = e.start
|
|
|
|
option2.dataZoom[0].start = e.start
|
|
|
|
@ -745,7 +744,7 @@
|
|
|
|
option3.dataZoom[0].end = e.end
|
|
|
|
option3.dataZoom[0].end = e.end
|
|
|
|
this.$refs.Chart3.setData(option3)
|
|
|
|
this.$refs.Chart3.setData(option3)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
this.$refs.Chart2.chart.on('datazoom', (e) => {
|
|
|
|
this.$refs.Chart2.chart.on('datazoom', (e) => {
|
|
|
|
option1.dataZoom[0].start = e.start
|
|
|
|
option1.dataZoom[0].start = e.start
|
|
|
|
option1.dataZoom[0].end = e.end
|
|
|
|
option1.dataZoom[0].end = e.end
|
|
|
|
@ -754,7 +753,7 @@
|
|
|
|
option3.dataZoom[0].end = e.end
|
|
|
|
option3.dataZoom[0].end = e.end
|
|
|
|
this.$refs.Chart3.setData(option3)
|
|
|
|
this.$refs.Chart3.setData(option3)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
this.$refs.Chart3.chart.on('datazoom', (e) => {
|
|
|
|
this.$refs.Chart3.chart.on('datazoom', (e) => {
|
|
|
|
option2.dataZoom[0].start = e.start
|
|
|
|
option2.dataZoom[0].start = e.start
|
|
|
|
option2.dataZoom[0].end = e.end
|
|
|
|
option2.dataZoom[0].end = e.end
|
|
|
|
@ -770,7 +769,7 @@
|
|
|
|
this.loading = false
|
|
|
|
this.loading = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 查询树形结构 */
|
|
|
|
/** 查询树形结构 */
|
|
|
|
getTreeMonitorInfo() {
|
|
|
|
getTreeMonitorInfo() {
|
|
|
|
getMonitorInfoTree({ monitorType: 4 }).then(response => {
|
|
|
|
getMonitorInfoTree({ monitorType: 4 }).then(response => {
|
|
|
|
@ -784,43 +783,43 @@
|
|
|
|
.app-container {
|
|
|
|
.app-container {
|
|
|
|
padding: 10px;
|
|
|
|
padding: 10px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.charts-container {
|
|
|
|
.charts-container {
|
|
|
|
margin-top: 10px;
|
|
|
|
margin-top: 10px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chart1 {
|
|
|
|
.chart1 {
|
|
|
|
width: 50%;
|
|
|
|
width: 50%;
|
|
|
|
height: 40vh;
|
|
|
|
height: 40vh;
|
|
|
|
display: inline-block;
|
|
|
|
display: inline-block;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chart2 {
|
|
|
|
.chart2 {
|
|
|
|
width: 50%;
|
|
|
|
width: 50%;
|
|
|
|
height: 40vh;
|
|
|
|
height: 40vh;
|
|
|
|
display: inline-block;
|
|
|
|
display: inline-block;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chart3 {
|
|
|
|
.chart3 {
|
|
|
|
width: 50%;
|
|
|
|
width: 50%;
|
|
|
|
height: 40vh;
|
|
|
|
height: 40vh;
|
|
|
|
display: inline-block;
|
|
|
|
display: inline-block;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.power-outage-summary {
|
|
|
|
.power-outage-summary {
|
|
|
|
margin-bottom: 10px;
|
|
|
|
margin-bottom: 10px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.power-outage-info {
|
|
|
|
.power-outage-info {
|
|
|
|
display: flex;
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
justify-content: space-between;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.power-outage-info p {
|
|
|
|
.power-outage-info p {
|
|
|
|
margin: 5px 10px;
|
|
|
|
margin: 5px 10px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 选中节点的样式 */
|
|
|
|
/* 选中节点的样式 */
|
|
|
|
::v-deep .el-tree .el-tree-node.is-current > .el-tree-node__content {
|
|
|
|
::v-deep .el-tree .el-tree-node.is-current > .el-tree-node__content {
|
|
|
|
background-color: #67C23A !important; /* 选中节点的背景色 */
|
|
|
|
background-color: #67C23A !important; /* 选中节点的背景色 */
|
|
|
|
@ -829,15 +828,14 @@
|
|
|
|
margin: 0; /* 清除外边距 */
|
|
|
|
margin: 0; /* 清除外边距 */
|
|
|
|
z-index: 1; /* 确保在其他元素之上 */
|
|
|
|
z-index: 1; /* 确保在其他元素之上 */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 鼠标悬停时的样式 */
|
|
|
|
/* 鼠标悬停时的样式 */
|
|
|
|
.el-tree .el-tree-node__content:hover {
|
|
|
|
.el-tree .el-tree-node__content:hover {
|
|
|
|
background-color: #e6f7ff; /* 鼠标悬停时的背景色 */
|
|
|
|
background-color: #e6f7ff; /* 鼠标悬停时的背景色 */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 闪电图标 */
|
|
|
|
/* 闪电图标 */
|
|
|
|
.el-icon-lightning:before {
|
|
|
|
.el-icon-lightning:before {
|
|
|
|
content: "\e6a8"; /* 使用现有的element-ui图标字体 */
|
|
|
|
content: "\e6a8"; /* 使用现有的element-ui图标字体 */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|