166 lines
5.6 KiB
Vue
166 lines
5.6 KiB
Vue
<template>
|
||
<div :style="height">
|
||
<MyEchart v-if="list.length != 0" :options="options1" style="height: 100%; width: 100%" class="pt10" />
|
||
<el-empty description="暂无数据" style="width: 100%; height: 100%" v-else></el-empty>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||
import { ref, reactive } from 'vue'
|
||
import { mainHeight } from '@/utils/layout'
|
||
import { max } from 'lodash'
|
||
const height = ref(mainHeight(290))
|
||
const list = ref([])
|
||
const options1 = ref({})
|
||
const setData = (data: any) => {
|
||
// list.value = [...fillDataFromFirstTime(data),...data]
|
||
list.value = data
|
||
init()
|
||
}
|
||
/**
|
||
* 补全离散数据(严格从数组第一个time开始,最后一个time结束)
|
||
* @param {Array} data 原始离散数据数组
|
||
* @param {number} interval 补全时间间隔(秒,默认10秒)
|
||
* @returns {Array} 补全后的连续数据
|
||
*/
|
||
function fillDataFromFirstTime(data, interval = 10) {
|
||
// 1. 基础校验
|
||
if (!Array.isArray(data) || data.length === 0) {
|
||
console.error('原始数据必须是非空数组')
|
||
return []
|
||
}
|
||
|
||
// 2. 锁定起始时间:直接取数组第一个元素的time(不做任何偏移)
|
||
const firstItem = data[0]
|
||
const startTime = new Date(firstItem.time)
|
||
const startTimestamp = startTime.getTime()
|
||
|
||
// 3. 锁定结束时间:取数组最后一个元素的time
|
||
const lastItem = data[data.length - 1]
|
||
const endTime = new Date(lastItem.time)
|
||
const endTimestamp = endTime.getTime()
|
||
|
||
// 4. 预处理:按时间排序(防止原始数据乱序)
|
||
const sortedData = [...data].sort((a, b) => new Date(a.time) - new Date(b.time))
|
||
|
||
// 5. 初始化状态(继承第一个数据的type)
|
||
let currentType = firstItem.type
|
||
let currentDesc = firstItem.description
|
||
let nextStatusIndex = 1 // 指向待切换的下一个状态点
|
||
|
||
const filledData = []
|
||
|
||
// 6. 核心循环:从第一个time开始,按间隔补全到最后一个time
|
||
for (let ts = startTimestamp; ts <= endTimestamp; ts += interval * 1000) {
|
||
const currentDate = new Date(ts)
|
||
// 格式化时间为和原始数据一致的 "YYYY-MM-DD HH:mm:ss" 格式
|
||
const formattedTime = `${currentDate.getFullYear()}-${String(currentDate.getMonth() + 1).padStart(
|
||
2,
|
||
'0'
|
||
)}-${String(currentDate.getDate()).padStart(2, '0')} ${String(currentDate.getHours()).padStart(
|
||
2,
|
||
'0'
|
||
)}:${String(currentDate.getMinutes()).padStart(2, '0')}:${String(currentDate.getSeconds()).padStart(2, '0')}`
|
||
|
||
// 7. 检查是否到达下一个状态切换点
|
||
if (nextStatusIndex < sortedData.length) {
|
||
const nextStatusTime = new Date(sortedData[nextStatusIndex].time).getTime()
|
||
if (ts >= nextStatusTime) {
|
||
currentType = sortedData[nextStatusIndex].type
|
||
currentDesc = sortedData[nextStatusIndex].description
|
||
nextStatusIndex++
|
||
}
|
||
}
|
||
|
||
// 8. 生成补全数据项(结构与原始数据完全一致)
|
||
filledData.push({
|
||
time: formattedTime,
|
||
devId: firstItem.devId,
|
||
description: currentDesc,
|
||
type: currentType
|
||
})
|
||
}
|
||
|
||
return filledData
|
||
}
|
||
|
||
const init = () => {
|
||
options1.value = {
|
||
title: {
|
||
text: '运行状态'
|
||
},
|
||
legend: {
|
||
show: false
|
||
},
|
||
tooltip: {
|
||
formatter: function (params: any) {
|
||
var res = params[0].data[0] + '<br/>运行状态:'
|
||
var texts = ''
|
||
if (params[0].data[1] === 1 || params[0].data[1] === '1') {
|
||
texts = '中断'
|
||
} else if (params[0].data[1] === 10 || params[0].data[1] === '10') {
|
||
texts = '正常'
|
||
}
|
||
res = res + texts
|
||
return res
|
||
}
|
||
},
|
||
xAxis: {
|
||
// type: 'category',
|
||
// data: data.updateTime
|
||
type: 'time',
|
||
name: '时间',
|
||
//
|
||
axisLabel: {
|
||
formatter: {
|
||
day: '{MM}-{dd}',
|
||
month: '{MM}',
|
||
year: '{yyyy}'
|
||
}
|
||
}
|
||
},
|
||
yAxis: {
|
||
name: '',
|
||
type: 'value',
|
||
max: 11,
|
||
interval: 1,
|
||
splitLine: {
|
||
lineStyle: {
|
||
// 使用深浅的间隔色
|
||
color: ['#ccc'],
|
||
type: 'dashed',
|
||
opacity: 0
|
||
}
|
||
},
|
||
axisLabel: {
|
||
// 这里重新定义就可以
|
||
formatter: function (value: number) {
|
||
var texts = []
|
||
if (value === 1) {
|
||
texts.push('中断')
|
||
} else if (value === 10) {
|
||
texts.push('正常')
|
||
}
|
||
return texts
|
||
}
|
||
}
|
||
},
|
||
series: [
|
||
{
|
||
name: '运行状态',
|
||
data: list.value.map((item: any, index: number) => [item.time, item.type == 0 ? 1 : 10]),
|
||
type: 'line',
|
||
showSymbol: false,
|
||
|
||
step: 'end'
|
||
}
|
||
]
|
||
}
|
||
}
|
||
defineExpose({
|
||
setData
|
||
})
|
||
</script>
|
||
<style lang="scss" scoped></style>
|