Files
svgeditor2.0/src/components/mt-preview-ypt/iframeDia.vue
2025-12-05 11:27:44 +08:00

361 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="container">
<!-- 使用 v-for 遍历四个角落 -->
<div v-for="corner in corners" :key="corner.id" :class="['corner', corner.className]">
<div class="content">
<div class="title">{{ corner.title }}</div>
<el-descriptions :column="1" size="small" label-width="70px" border>
<el-descriptions-item v-for="(item, index) in corner.data" :key="index" :label="item.label">
<div v-html="item.value"></div>
</el-descriptions-item>
</el-descriptions>
</div>
<span class="close-btn" @click="closeCorner(corner.id)">
<Close />
</span>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue'
import { Close } from '@element-plus/icons-vue'
// 定义 emits
const emit = defineEmits<{
(e: 'lineListChange', lineList: string[]): void
}>()
// 定义接收的 props
const props = defineProps<{
eventList?: []
steadyState?: [
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-W1O31AjTAx'
lineId: '00B78D0171091'
phaseType: 'Pq_RmsU'
statisticalName: '统计数据 / 相电压总有效值 / A / 平均值'
target: '统计数据$Pq_RmsU$A'
value: 45
valueType: 'A'
},
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-W1O31AjTAx'
lineId: '00B78D0171091'
phaseType: 'Pq_RmsU'
statisticalName: '统计数据 / 相电压总有效值 / A / CP95'
target: '统计数据$Pq_RmsU$A'
value: 3.1415926
valueType: 'A'
},
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-W1O31AjTAx'
lineId: '00B78D0171091'
phaseType: 'Pq_RmsU'
statisticalName: '统计数据 / 相电压总有效值 / A / 最大值'
target: '统计数据$Pq_RmsU$A'
value: 3.1415926
valueType: 'A'
},
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-W1O31AjTAx'
lineId: '00B78D0171091'
phaseType: 'Pq_RmsU'
statisticalName: '统计数据 / 相电压总有效值 / A / 最小值'
target: '统计数据$Pq_RmsU$A'
value: 3.1415926
valueType: 'A'
},
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-zOXUxFQ6Vt'
lineId: '00B78D0171092'
phaseType: 'Pq_RmsLU'
statisticalName: '统计数据 / 线电压总有效值 / BC / 平均值'
target: '统计数据$Pq_RmsLU$BC'
value: 3.1415926
valueType: 'BC'
},
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-zOXUxFQ6Vt'
lineId: '00B78D0171092'
phaseType: 'Pq_RmsLU'
statisticalName: '统计数据 / 线电压总有效值 / BC / CP95'
target: '统计数据$Pq_RmsLU$BC'
value: 3.1415926
valueType: 'BC'
}
]
}>()
// 定义四个角落的数据
const corners = ref([
{
id: 'topLeft',
title: '左上',
className: 'top-left',
show: false,
data: [] as { label: string; value: string }[],
elementId: '' // 记录该角落对应的元素ID
},
{
id: 'topRight',
title: '右上',
className: 'top-right',
show: false,
data: [] as { label: string; value: string }[],
elementId: ''
}
])
const displayOrder = ref<number[]>([])
const lineList = ref<string[]>([]) // 缓存打开的lineId
// 处理稳态指标数据
const processSteadyStateData = (cornerIndex: number, elementId: string) => {
nextTick(() => {
if (!props.steadyState || props.steadyState.length == 0) {
if (corners.value[cornerIndex].data.length > 0) {
corners.value[cornerIndex].data[0].value = '暂无稳态指标数据'
}
return
}
let str = ``
props.steadyState
.filter(item => item.lineId === elementId)
.forEach(item => {
if (item.value == 3.1415926) {
str += `<div>${item.statisticalName}/</div>`
} else {
str += `<div>${item.statisticalName}${item.value}</div>`
}
})
if (str) {
if (corners.value[cornerIndex].data.length > 0) {
corners.value[cornerIndex].data[0].value =
`<div style="max-height: 100px;overflow-y: auto;">${str}</div>`
}
} else {
if (corners.value[cornerIndex].data.length > 0) {
corners.value[cornerIndex].data[0].value = '暂无稳态指标数据'
}
}
})
}
// 截取线路名称的最后一部分作为标题
const extractTitleFromLineName = (lineName: string): string => {
if (!lineName) return '未知监测点'
// 按照 "/" 分割字符串,取最后一部分
const parts = lineName.split('/')
return parts.length > 0 ? parts[parts.length - 1].trim() : lineName
}
// 更新指定角落数据的函数
const updateCornerData = (cornerIndex: number, elementId: string, lineName: string) => {
// 更新标题为传入的 lineName 的最后一部分
corners.value[cornerIndex].title = extractTitleFromLineName(lineName)
// 格式化数据(只保留稳态指标一项)
corners.value[cornerIndex].data = [
{
label: '稳态指标',
value: '正在加载...'
}
]
// 记录该角落对应的元素ID
corners.value[cornerIndex].elementId = elementId
corners.value[cornerIndex].show = true
// 处理稳态指标数据
processSteadyStateData(cornerIndex, elementId)
}
// 显示下一个角落的函数
const showNextCorner = (elementId: string, lineName: string) => {
// 检查该元素ID是否已经显示过
const existingCornerIndex = corners.value.findIndex(corner => corner.elementId === elementId && corner.show)
if (existingCornerIndex !== -1) {
// 如果该元素已经显示过,更新标题
corners.value[existingCornerIndex].title = extractTitleFromLineName(lineName)
return
}
// 查找一个未显示的角落
const availableCornerIndex = corners.value.findIndex(corner => !corner.show)
if (availableCornerIndex !== -1) {
// 有空闲角落,显示在该角落
updateCornerData(availableCornerIndex, elementId, lineName)
// 记录显示顺序
displayOrder.value.push(availableCornerIndex)
} else {
// 没有空闲角落,按顺序替换角落
// 获取需要替换的角落索引(循环替换)
const replaceIndex = displayOrder.value.shift() || 0
updateCornerData(replaceIndex, elementId, lineName)
// 将替换的索引重新加入队列末尾
displayOrder.value.push(replaceIndex)
}
// 更新 lineList去重并触发事件
updateLineList(elementId)
}
// 更新 lineList去重并触发事件
const updateLineList = (elementId: string) => {
// 检查是否已存在
if (!lineList.value.includes(elementId)) {
lineList.value.push(elementId)
// 触发事件,传递更新后的 lineList
emit('lineListChange', [...lineList.value])
}
}
// 关闭指定角落的函数
const closeCorner = (id: string) => {
const cornerIndex = corners.value.findIndex(c => c.id === id)
if (cornerIndex !== -1) {
const elementId = corners.value[cornerIndex].elementId
corners.value[cornerIndex].show = false
corners.value[cornerIndex].elementId = '' // 清空元素ID记录
// 从显示顺序中移除该角落索引
const orderIndex = displayOrder.value.indexOf(cornerIndex)
if (orderIndex !== -1) {
displayOrder.value.splice(orderIndex, 1)
}
// 从 lineList 中移除对应的 elementId
const lineIndex = lineList.value.indexOf(elementId)
if (lineIndex !== -1) {
lineList.value.splice(lineIndex, 1)
// 触发事件,传递更新后的 lineList
emit('lineListChange', [...lineList.value])
}
}
}
// 关闭所有角落的函数
const closeAllCorners = () => {
corners.value.forEach(corner => {
corner.show = false
corner.elementId = ''
})
displayOrder.value = []
lineList.value = [] // 清空 lineList
// 触发事件,传递清空后的 lineList
emit('lineListChange', [])
}
onMounted(() => {
nextTick(() => {
showNextCorner('00B78D0171091', '在线设备 / 灿能测试 / EMC实验室 / 装置一 / 监测点1')
})
})
// 暴露方法给父组件使用
defineExpose({
showNextCorner,
closeCorner,
closeAllCorners
})
</script>
<style scoped lang="less">
.corner {
width: 240px;
background-color: #2b2d3a90;
position: absolute;
color: 000;
opacity: 0;
transform: scale(0.3);
transition: all 0.4s ease-out;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
/* 显示状态的样式 */
.corner:not([style*='display: none']):not([style*='display:none']) {
opacity: 1;
transform: scale(1);
}
.top-left {
top: 10px;
left: 10px;
}
.top-right {
top: 10px;
right: 10px;
}
.bottom-left {
top: 170px;
left: 10px;
}
.bottom-right {
top: 170px;
right: 10px;
}
.content {
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.title {
font-size: 16px;
padding: 8px;
border-bottom: 1px solid #fff;
background-color: #fff;
border-radius: 8px 8px 0 0;
}
.data-item {
display: flex;
margin-bottom: 4px;
font-size: 12px;
}
.label {
width: 55px;
flex-shrink: 0;
}
.value {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 关闭按钮样式 */
.close-btn {
position: absolute;
top: 10px;
right: 10px;
width: 14px;
color: #000;
font-size: 14px;
font-weight: bold;
cursor: pointer;
}
.indicator {
display: flex;
}
</style>