312 lines
9.4 KiB
Vue
312 lines
9.4 KiB
Vue
<template>
|
||
<div>
|
||
<!--暂态事件概率分布 -->
|
||
<TableHeader
|
||
ref="TableHeaderRef"
|
||
:timeKeyList="prop.timeKey"
|
||
:showReset="false"
|
||
@selectChange="selectChange"
|
||
datePicker
|
||
v-if="fullscreen"
|
||
></TableHeader>
|
||
<my-echart
|
||
class="tall"
|
||
:options="echartList"
|
||
:style="{
|
||
width: prop.width,
|
||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||
}"
|
||
/>
|
||
<!-- <my-echart
|
||
class="mt10"
|
||
:options="echartList1"
|
||
:style="{
|
||
width: prop.width,
|
||
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||
}"
|
||
/> -->
|
||
</div>
|
||
</template>
|
||
<script setup lang="ts">
|
||
import { ref, onMounted, provide, reactive, watch } from 'vue'
|
||
import TableStore from '@/utils/tableStore'
|
||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||
import { useConfig } from '@/stores/config'
|
||
import TableHeader from '@/components/table/header/index.vue'
|
||
import { getTime } from '@/utils/formatTime'
|
||
|
||
const prop = defineProps({
|
||
w: { type: [String, Number] },
|
||
h: { type: [String, Number] },
|
||
width: { type: [String, Number] },
|
||
height: { type: [String, Number] },
|
||
timeKey: { type: Array as () => string[] },
|
||
timeValue: { type: Object },
|
||
interval: { type: Number }
|
||
})
|
||
|
||
const TableHeaderRef = ref()
|
||
|
||
const headerHeight = ref(57)
|
||
|
||
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 config = useConfig()
|
||
|
||
const echartList = ref({})
|
||
|
||
const echartList1 = ref({})
|
||
|
||
const processDataForChart = (rawData: any[]) => {
|
||
// 将后端返回的扁平数据转换为 ECharts 需要的三维坐标格式 [x, y, z]
|
||
const chartData = rawData.map(item => [item.x, item.y, item.z])
|
||
|
||
return chartData
|
||
}
|
||
|
||
const tableStore: any = new TableStore({
|
||
url: '/cs-harmonic-boot/csevent/getEventCoords',
|
||
method: 'POST',
|
||
showPage: false,
|
||
column: [],
|
||
beforeSearchFun: () => {
|
||
setTime()
|
||
},
|
||
loadCallback: () => {
|
||
const processedData = processDataForChart(tableStore.table.data.innerList || [])
|
||
const trendList = tableStore.table.data.trendList || []
|
||
const xlist = tableStore.table.data.xlist || []
|
||
|
||
// 处理趋势图数据
|
||
const seriesData = trendList.map((item: any) => {
|
||
// 根据接口返回的name字段确定系列名称和颜色
|
||
let name = ''
|
||
let color = ''
|
||
|
||
switch (item.name) {
|
||
case 'Evt_Sys_DipStr':
|
||
name = '电压暂降'
|
||
color = '#FFBF00'
|
||
break
|
||
case 'Evt_Sys_IntrStr':
|
||
name = '电压中断'
|
||
color = '#FF9100'
|
||
break
|
||
case 'Evt_Sys_SwlStr':
|
||
name = '电压暂升'
|
||
color = config.layout.elementUiPrimary[0]
|
||
break
|
||
default:
|
||
name = item.name
|
||
color = '#000000'
|
||
}
|
||
|
||
return {
|
||
name: name,
|
||
type: 'line',
|
||
showSymbol: false,
|
||
color: color,
|
||
data: item.trendList?.map((value: number, index: number) => [xlist[index], value]) || []
|
||
}
|
||
})
|
||
|
||
// 获取x轴和y轴的标签值
|
||
const xLabels = [
|
||
'0-10%',
|
||
'10%-20%',
|
||
'20%-30%',
|
||
'30%-40%',
|
||
'40%-50%',
|
||
'50%-60%',
|
||
'60%-70%',
|
||
'70%-80%',
|
||
'80%-90%',
|
||
'90%-100%'
|
||
]
|
||
const yLabels = ['0-0.01s', '0.01s-0.1s', '0.1s-1s', '1s-10s', '10s']
|
||
|
||
echartList.value = {
|
||
options: {
|
||
xAxis: null,
|
||
yAxis: null,
|
||
dataZoom: null,
|
||
backgroundColor: '#fff',
|
||
tooltip: {
|
||
textStyle: {
|
||
color: '#fff',
|
||
fontStyle: 'normal',
|
||
opacity: 0.35,
|
||
fontSize: 14
|
||
},
|
||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||
borderWidth: 0,
|
||
formatter: function (params: any) {
|
||
var tips = ''
|
||
tips += '持续时间: ' + yLabels[params.value[1]] + '</br>'
|
||
tips += '特征幅值: ' + xLabels[params.value[0]] + '</br>'
|
||
tips += '事件次数: ' + params.value[2] + '</br>'
|
||
return tips
|
||
}
|
||
},
|
||
title: {
|
||
text: '暂态事件概率分布',
|
||
x: 'center'
|
||
},
|
||
visualMap: {
|
||
max: 500,
|
||
show: false,
|
||
inRange: {
|
||
color: ['#313695', '#00BB00', '#ff8000', '#a50026']
|
||
}
|
||
},
|
||
xAxis3D: {
|
||
type: 'category',
|
||
name: '特征幅值',
|
||
data: xLabels,
|
||
nameGap: 40
|
||
},
|
||
yAxis3D: {
|
||
type: 'category',
|
||
name: '持续时间',
|
||
data: yLabels,
|
||
nameGap: 40,
|
||
|
||
splitLine: {
|
||
lineStyle: {
|
||
type: 'dashed',
|
||
opacity: 0.5
|
||
}
|
||
}
|
||
},
|
||
zAxis3D: {
|
||
type: 'value',
|
||
minInterval: 10,
|
||
name: '暂态事件次数',
|
||
nameGap: 30
|
||
},
|
||
grid3D: {
|
||
viewControl: {
|
||
projection: 'perspective',
|
||
distance: 260,
|
||
rotateSensitivity: 10,
|
||
zoomSensitivity: 2
|
||
},
|
||
boxWidth: 150,
|
||
boxDepth: 100,
|
||
boxHeight: 100,
|
||
light: {
|
||
main: {
|
||
intensity: 1.2
|
||
},
|
||
ambient: {
|
||
intensity: 0.4
|
||
}
|
||
}
|
||
},
|
||
series: [
|
||
{
|
||
type: 'bar3D',
|
||
data: processedData,
|
||
shading: 'realistic',
|
||
label: {
|
||
show: false,
|
||
textStyle: {
|
||
fontSize: 16,
|
||
borderWidth: 1
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
|
||
echartList1.value = {
|
||
title: {
|
||
text: '越限时间概率分布'
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: xlist,
|
||
axisLabel: {
|
||
formatter: '{value}'
|
||
}
|
||
},
|
||
yAxis: {
|
||
name: '次'
|
||
},
|
||
grid: {
|
||
left: '10px',
|
||
right: '20px'
|
||
},
|
||
series: seriesData
|
||
}
|
||
}
|
||
})
|
||
|
||
const tableRef = ref()
|
||
provide('tableRef', tableRef)
|
||
|
||
provide('tableStore', tableStore)
|
||
|
||
onMounted(() => {
|
||
tableStore.index()
|
||
})
|
||
|
||
const setTime = () => {
|
||
const time = getTime(
|
||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||
prop.timeKey,
|
||
fullscreen.value
|
||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||
: prop.timeValue
|
||
)
|
||
|
||
if (Array.isArray(time)) {
|
||
tableStore.table.params.searchBeginTime = time[0]
|
||
tableStore.table.params.searchEndTime = time[1]
|
||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||
} else {
|
||
console.warn('获取时间失败,time 不是一个有效数组')
|
||
}
|
||
}
|
||
|
||
watch(
|
||
() => prop.timeKey,
|
||
val => {
|
||
tableStore.index()
|
||
}
|
||
)
|
||
|
||
watch(
|
||
() => prop.timeValue,
|
||
(newVal, oldVal) => {
|
||
tableStore.index()
|
||
},
|
||
{
|
||
deep: true
|
||
}
|
||
)
|
||
</script>
|
||
<style lang="scss" scoped></style>
|