Files
admin-govern/src/components/cockpit/F47Curve/index.vue
2025-12-02 16:03:04 +08:00

488 lines
16 KiB
Vue

<template>
<div>
<!--F47曲线 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
<el-descriptions class="mt2" direction="vertical" :column="4" border>
<el-descriptions-item align="center" label="名称">{{ data.name }}</el-descriptions-item>
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
<el-descriptions-item align="center" label="可容忍">{{ data.krr }}</el-descriptions-item>
<el-descriptions-item align="center" label="不可容忍">{{ data.bkrr }}</el-descriptions-item>
</el-descriptions>
<my-echart
v-loading="tableStore.table.loading"
ref="chartRef"
class="tall"
:options="echartList"
:style="{
width: prop.width,
height: `calc(${prop.height} - 80px - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
}"
@chart-click="handleChartClick"
/>
<el-dialog v-model="isWaveCharts" v-if="isWaveCharts" draggable :title="dialogTitle" append-to-body width="70%">
<waveFormAnalysis
v-loading="loading"
ref="waveFormAnalysisRef"
@handleHideCharts="isWaveCharts = false"
:wp="wp"
/>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
import TableStore from '@/utils/tableStore'
import MyEchart from '@/components/echarts/MyEchart.vue'
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
import TableHeader from '@/components/table/header/index.vue'
import { analyseWave } from '@/api/common'
import { ElMessage } from 'element-plus'
const prop = defineProps({
w: { type: [String, Number] },
h: { type: [String, Number] },
width: { type: [String, Number] },
height: { type: [String, Number] },
timeKey: { type: [String, Number] },
timeValue: { type: Object }
})
const headerHeight = ref(57)
const dialogTitle = ref('波形分析')
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
headerHeight.value = height
if (datePickerValue && datePickerValue.timeValue) {
// 更新时间参数
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
}
}
// 计算是否全屏展示
const fullscreen = computed(() => {
const w = Number(prop.w)
const h = Number(prop.h)
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
// 执行相应逻辑
return true
} else {
return false
}
})
const echartList = ref()
const chartRef = ref()
// 波形
const isWaveCharts = ref(false)
const loading = ref(false)
const wp = ref({})
const boxoList: any = ref({})
const waveFormAnalysisRef: any = ref(null)
const data = reactive({
name: '事件个数',
gs: 0,
krr: 0,
bkrr: 0
})
const tableStore: any = new TableStore({
url: '/cs-harmonic-boot/csevent/f47Curve',
method: 'POST',
showPage: false,
column: [],
beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
},
loadCallback: () => {
const gongData = gongfunction(tableStore.table.data)
data.gs = tableStore.table.data.length
data.krr = gongData.pointI.length
data.bkrr = gongData.pointIun.length
echartList.value = {
title: {
text: `F47曲线`
},
legend: {
data: ['可容忍事件', '不可容忍事件'],
itemWidth: 10,
itemHeight: 10,
itemGap: 15
},
tooltip: {
trigger: 'item',
show: true,
axisPointer: {
type: 'shadow',
label: {
color: '#fff',
fontSize: 16
}
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
opacity: 0.35,
fontSize: 14
},
backgroundColor: 'rgba(0,0,0,0.55)',
borderWidth: 0,
formatter: function (a: any) {
var relVal = ''
relVal = "<font style='color:" + "'>发生时间:" + a.value[2] + '</font><br/>'
relVal += "<font style='color:" + "'>持续时间:" + a.value[0] + 's</font><br/>'
relVal += "<font style='color:" + "'>特征幅值:" + a.value[1].toFixed(2) + '%</font>'
return relVal
}
},
xAxis: [
{
type: 'log',
min: 0.001,
max: 1000,
splitLine: {
show: false
},
name: 's'
}
],
yAxis: [
{
type: 'value',
max: function (value: any) {
return value.max + 20
},
splitNumber: 10,
minInterval: 0.1,
name: '%'
}
],
color: ['#DAA520', 'green', 'red'],
options: {
dataZoom: null,
series: [
{
name: '边界线',
type: 'line',
data: [
[0.05, 0],
[0.05, 50],
[0.2, 50],
[0.2, 70],
[0.5, 70],
[0.5, 80],
[10, 80],
[1000, 80]
],
showSymbol: false,
tooltips: {
show: false
}
},
{
name: '可容忍事件',
type: 'scatter',
symbol: 'circle',
symbolSize: 8,
data: gongData.pointF,
// data: [
// [0.2, 10, '2023-01-01 10:00:00'],
// [0.4, 50, '2023-01-01 11:00:00']
// ],
legendSymbol: 'circle',
emphasis: {
focus: 'series',
itemStyle: {
borderColor: '#fff',
borderWidth: 2,
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
tooltip: {
show: true,
trigger: 'item',
formatter: function (params: any) {
return `<strong>可容忍事件</strong><br/>
持续时间: ${params.value[0]}s<br/>
特征幅值: ${params.value[1].toFixed(2)}%<br/>
发生时间: ${params.value[2] || 'N/A'}`
}
}
},
{
name: '不可容忍事件',
type: 'scatter',
symbol: 'circle',
symbolSize: 8,
data: gongData.pointFun,
legendSymbol: 'rect'
}
]
}
}
}
})
const tableRef = ref()
provide('tableRef', tableRef)
provide('tableStore', tableStore)
function gongfunction(arr: any) {
let standI = 0
let unstandI = 0
let standF = 0
let unstandF = 0
let total = 0
let pointIun = []
let pointI = []
let pointF = []
let pointFun = []
total = arr.length
if (total == 0) {
} else {
for (let i = 0; i < arr.length; i++) {
let point = []
let xx = arr[i].persistTime
let yy = arr[i].eventValue
let time = arr[i].time
let eventId = arr[i].eventId
let lineName = arr[i].lineName
// let index =arr[i].eventDetailIndex;
point = [xx, yy, time, eventId, lineName]
if (xx <= 0.003) {
let line = 0
line = 250 - 30000 * xx
if (yy > line) {
unstandI++
pointIun.push({
value: point,
itemStyle: { normal: { color: 'red' } }
})
} else {
standI++
pointI.push({
value: point,
itemStyle: { normal: { color: 'green' } }
})
}
} else if (xx <= 0.02) {
if (yy > 120) {
unstandI++
pointIun.push({
value: point,
itemStyle: { normal: { color: 'red' } }
})
} else {
standI++
pointI.push({
value: point,
itemStyle: { normal: { color: 'green' } }
})
}
} else if (xx <= 0.5) {
if (yy > 120 || yy < 70) {
unstandI++
pointIun.push({
value: point,
itemStyle: { normal: { color: 'red' } }
})
} else {
standI++
pointI.push({
value: point,
itemStyle: { normal: { color: 'green' } }
})
}
} else if (xx <= 10) {
if (yy > 110 || yy < 80) {
unstandI++
pointIun.push({
value: point,
itemStyle: { normal: { color: 'red' } }
})
} else {
standI++
pointI.push({
value: point,
itemStyle: { normal: { color: 'green' } }
})
}
} else {
if (yy > 110 || yy < 90) {
unstandI++
pointIun.push({
value: point,
itemStyle: { normal: { color: 'red' } }
})
} else {
standI++
pointI.push({
value: point,
itemStyle: { normal: { color: 'green' } }
})
}
}
if (xx < 0.05) {
standF++
pointF.push({
value: point,
itemStyle: { normal: { color: 'green' } }
})
} else if (xx < 0.2) {
if (yy > 50) {
standF++
pointF.push({
value: point,
itemStyle: { normal: { color: 'green' } }
})
} else {
unstandF++
pointFun.push({
value: point,
itemStyle: { normal: { color: 'red' } }
})
}
} else if (xx < 0.5) {
if (yy > 70) {
standF++
pointF.push({
value: point,
itemStyle: { normal: { color: 'green' } }
})
} else {
unstandF++
pointFun.push({
value: point,
itemStyle: { normal: { color: 'red' } }
})
}
} else {
if (yy > 80) {
standF++
pointF.push({
value: point,
itemStyle: { normal: { color: 'green' } }
})
} else {
unstandF++
pointFun.push({
value: point,
itemStyle: { normal: { color: 'red' } }
})
}
}
}
}
return {
standI,
unstandI,
pointI,
pointIun,
standF,
unstandF,
pointF,
pointFun
}
}
onMounted(() => {
setTimeout(() => {
tableStore.index()
}, 100)
})
// 点击事件处理函数
const handleChartClick = (params: any) => {
if (params.seriesName === '可容忍事件') {
// 处理可容忍事件点击
dialogTitle.value = '可容忍事件波形分析'
handleTolerableEventClick(params)
} else if (params.seriesName === '不可容忍事件') {
dialogTitle.value = '不可容忍事件波形分析'
// 处理不可容忍事件点击
// ElMessage.info(`点击了不可容忍事件: 持续时间${params.value[0]}s, 幅值${params.value[1].toFixed(2)}%`)
handleTolerableEventClick(params)
}
}
// 可容忍事件点击处理函数
const handleTolerableEventClick = async (row: any) => {
loading.value = true
nextTick(() => {
if (waveFormAnalysisRef.value) {
//waveFormAnalysisRef.value.setHeight(false, 360)
waveFormAnalysisRef.value.setHeight(999, 130, 1.6666666)
}
})
const messageInstance = ElMessage.info(`正在加载,请稍等...`)
await analyseWave(row.value[3]) //eventId
.then(res => {
row.loading1 = false
if (res != undefined) {
boxoList.value = {
persistTime: row.value[0], //持续时间
featureAmplitude: (row.value[1] / 100).toFixed(2), //残余电压
startTime: row.value[2], //时间
lineName: row.value[4] //监测点名称
}
boxoList.value.systemType = 'YPT'
wp.value = res.data
}
isWaveCharts.value = true
loading.value = false
})
.catch(() => {
messageInstance.close()
row.loading1 = false
loading.value = false
})
nextTick(() => {
waveFormAnalysisRef.value && waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
})
}
// 不可容忍事件点击处理函数
const handleIntolerableEventClick = (params: any) => {
console.log('不可容忍事件详情:', params)
}
watch(
() => prop.timeKey,
val => {
tableStore.index()
}
)
watch(
() => prop.timeValue,
(newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
tableStore.table.params.searchBeginTime = newVal[0]
tableStore.table.params.searchEndTime = newVal[1]
tableStore.index()
}
},
{
deep: true
}
)
const addMenu = () => {}
</script>
<style lang="scss" scoped></style>