添加工程树

This commit is contained in:
guanj
2026-03-06 09:36:42 +08:00
parent 3fdb41c468
commit 1171d37a86
22 changed files with 1757 additions and 1249 deletions

View File

@@ -0,0 +1,165 @@
<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>