Files
admin-govern/src/views/govern/device/control/tabs/components/realtrend.vue
2024-09-14 10:32:01 +08:00

502 lines
16 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="realtrend">
<el-tabs type="border-card" v-model="activeName" @tab-click="handleClick">
<el-tab-pane v-for="(item, index) in tabsList" :label="item.groupName" :name="index" :key="index">
<div v-loading="loading">
<div class="realtrend_top">
<div class="thead">
<ul v-for="(table, tableIndex) in newTableList" :key="tableIndex">
<li>
{{ table[0].value }}
</li>
</ul>
</div>
<div class="table">
<ul v-for="(table, tableIndex) in newTableList" :key="tableIndex">
<span v-for="(key, keys) in table">
<li v-if="keys != 0">
{{ key?.value }}
</li>
</span>
</ul>
</div>
</div>
<div class="tab_info">
<div class="charts">
<MyEchart ref="barCharts" :options="echartsData"></MyEchart>
</div>
</div>
</div>
</el-tab-pane>
<!-- <el-tab-pane label="谐波电压含有率" name="0">
<template #label>
<span class="custom-tabs-label">
<el-icon><TrendCharts /></el-icon>
谐波电压含有率
</span>
</template>
<div class="tab_info">
<vxe-grid v-if="activeName == '0'" class="reverse-table" v-bind="gridOptions"></vxe-grid>
<div class="charts">
<MyEchart ref="barCharts1" :options="echartsData1"></MyEchart>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="间谐波电压含有率" name="1">
<template #label>
<span class="custom-tabs-label">
<el-icon><TrendCharts /></el-icon>
间谐波电压含有率
</span>
</template>
<div class="tab_info">
<vxe-grid v-if="activeName == '1'" class="reverse-table" v-bind="gridOptions"></vxe-grid>
<div class="charts">
<MyEchart ref="barCharts2" :options="echartsData2"></MyEchart>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="谐波电流幅值" name="2">
<template #label>
<span class="custom-tabs-label">
<el-icon><DataLine /></el-icon>
谐波电流幅值
</span>
</template>
<div class="tab_info">
<vxe-grid v-if="activeName == '2'" class="reverse-table" v-bind="gridOptions"></vxe-grid>
<div class="charts">
<MyEchart ref="barCharts3" :options="echartsData3"></MyEchart>
</div>
</div>
</el-tab-pane> -->
</el-tabs>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, reactive, nextTick } from 'vue'
import { VxeGridProps, VxeGridPropTypes } from 'vxe-table'
import { defaultAttribute } from '@/components/table/defaultAttribute'
import MyEchart from '@/components/echarts/MyEchart.vue'
import { Platform, TrendCharts, DataLine } from '@element-plus/icons-vue'
import { getDeviceTrendDataGroup, getDeviceTrendData } from '@/api/cs-device-boot/EquipmentDelivery.ts'
import Index from '@/components/wangEditor/index.vue'
const activeName = ref(0)
const tableList: any = []
interface RowVO {
[key: string]: any
}
//谐波电压含有率
const gridOptions = ref<VxeGridProps<RowVO>>({
border: true,
showOverflow: true,
showHeader: false,
columns: [],
data: [],
columnConfig: {
resizable: true
},
align: 'center'
})
gridOptions.value = { ...defaultAttribute, ...gridOptions.value }
const myColumns: any = ref([
// { field: 'name', title: '次数' }
// { field: 'value', title: '谐波电压含有率(%)' }
])
const yAxisUnit: any = ref('')
// myColumns.value.map(item => {
// if (item.field == 'value') {
// item.title =
// activeName.value == '0'
// ? '谐波电压含有率(%)'
// : activeName.value == '1'
// ? '间谐波电压含有率(%)'
// : activeName.value == '2'
// ? '谐波电流幅值(A)'
// : ''
// yAxisUnit.value = item.title.split('(')[0]
// }
// })
const myData = tableList
const tabsList = ref([])
//接收参数
const params = ref({})
const open = (val: any) => {
//获取指标tab
getDeviceTrendDataGroup().then(res => {
tabsList.value = res.data
if (tabsList.value.length != 0) {
// activeName.value = tabsList.value[0]?.id
activeName.value = 0
}
params.value = { groupId: tabsList.value[activeName.value]?.id, ...val }
findRealTrendDataByGroupId(params.value)
})
return
}
const newTableList: any = ref([])
//根据指标tab查询实时趋势
const loading: any = ref(false)
//echarts数据
const chartsData: any = ref([])
const chartsYxiasData: any = ref([])
const findRealTrendDataByGroupId = (obj: any) => {
loading.value = true
chartsData.value = []
chartsYxiasData.value = []
getDeviceTrendData(obj).then(res => {
let list: any = []
let countList: any = []
myColumns.value = [{ field: 'name', title: '次数' }]
chartsData.value = res.data[0].thdDataTdVODatas
//处理实时趋势表格
let arr = res.data[0].thdDataVOS
arr.map((item: any, index: any) => {
myColumns.value.push({ field: item.phase, title: item.name })
chartsYxiasData.value.push({ phase: item.phase, title: item.name, phaseList: [], gbList: [] })
//循环第二层数据
item.list = []
item.data.map((vv: any, vvs: any) => {
if (!(vv.statisticalData + '')) {
vv.statisticalData = '/'
}
item.list.push({ value: vv.statisticalData, count: vv.frequency - 0 })
})
list[index + 1] = item.list
const minCount = Math.min(...item.list.map((item: any) => item.count))
const maxCount = Math.max(...item.list.map((item: any) => item.count))
for (let i = 0; i < 50; i++) {
countList[i] = { value: i + minCount + '次', count: i + minCount }
}
countList.map((item: any, index: any) => {
if (item.value.replace('次', '') - 0 > 50) {
countList.splice(index, 1)
}
})
list[0] = countList
if (item.list.length == 0) {
for (let i = 0; i < countList.length; i++) {
item.list.push({
value: '/',
count: index
})
}
}
if (item.list.length != 0) {
const maxCount1 = Math.max(...countList.map((item: any) => item.count))
const maxCount2 = Math.max(...item.list.map((item: any) => item.count))
console.log(maxCount2, maxCount1)
if (maxCount2 < maxCount1) {
for (let i = 0; i < maxCount1 - maxCount2; i++) {
item.list.push({
value: '/',
count: index
})
}
}
}
})
// 转换为对象数组
list.map((item: any, index: any) => {
item.unshift({ value: myColumns.value[index].title, count: '' })
})
newTableList.value = list
loading.value = false
init()
})
}
//反转表格
const reverseTable = () => {
const buildData = myColumns.value.map(column => {
const item: any = { col0: column.title }
myData.forEach((row, index) => {
item[`col${index + 1}`] = row[column.field]
})
return item
})
const buildColumns: VxeGridPropTypes.Columns = [
{
field: 'col0',
fixed: 'left',
width: 200
}
]
myData.forEach((item, index) => {
buildColumns.push({
field: `col${index + 1}`,
minWidth: 120
})
})
gridOptions.value.data = buildData
gridOptions.value.columns = buildColumns
}
reverseTable()
const echartsData: any = ref([]),
echartsData1: any = ref([]),
echartsData2: any = ref([]),
echartsData3: any = ref([]),
barCharts = ref(),
barCharts1 = ref(),
barCharts2 = ref(),
barCharts3 = ref()
//加载echarts
const init = () => {
// let list: any = []
let timeList: any = []
let xAxisList: any = []
chartsData.value.map((item: any, index: any) => {
chartsYxiasData.value.map((vv: any, vvs: any) => {
if (item.phase == vv.phase) {
if (vvs == 0) {
vv.gbList.push(item.internationalValue)
}
vv.phaseList.push(item.statisticalData)
}
})
xAxisList.push(item.frequency + '次')
})
xAxisList = [...new Set(xAxisList)]
echartsData.value = {
options: {
// backgroundColor: '#0f375f',
dataZoom: [
{
show: true,
start: 0,
end: 20
},
{
type: 'inside',
start: 0,
end: 20
}
],
grid: {
top: '14%',
bottom: '22%', //也可设置left和right设置距离来控制图表的大小
left: '3%',
right: '5%'
},
// tooltip: {
// trigger: 'axis',
// axisPointer: {
// type: 'cross',
// label: {
// show: false
// }
// }
// },
legend: {
data: [],
itemGap: 15,
type: 'scroll', // 开启滚动分页
// orient: 'vertical', // 垂直排列
right: '3%', // 位置调整
top: 0,
bottom: 20,
width: 400,
height: 50
},
xAxis: {
name: '次数',
data: xAxisList,
axisLine: {
show: true, //隐藏X轴轴线
lineStyle: {
color: '#000'
}
},
axisTick: {
show: true //隐藏X轴刻度
},
axisPointer: {
type: 'shadow'
},
axisLabel: {
show: true,
textStyle: {
color: '#000' //X轴文字颜色
}
}
},
yAxis: [
{
type: 'value',
name: chartsData?.value[0]?.unit ? '单位(' + chartsData?.value[0]?.unit+ ')' : '' ,
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000'
}
}
}
],
series: []
}
}
let list: any = []
list = []
chartsYxiasData.value.map((item: any) => {
console.log(item.gbList, 'guobialist340')
if (item.gbList.length != 0) {
list.push({ phase: item.phase, title: '国标限值', list: item.gbList })
}
if (item.phaseList.length != 0) {
list.push({ phase: item.phase, title: item.title, list: item.phaseList })
}
})
const colorList = ['#0e8780', '#FFCC00', '#009900', '#CC0000', ]
list.map((item: any, index: any) => {
echartsData.value.options.legend.data.push(item.title)
echartsData.value.options.series.push({
name: item.title,
type: 'bar',
barMaxWidth: 16, //使用的 y 轴的 index在单个图表实例中存在多个 y轴的时候有用
itemStyle: {
// normal: {
barBorderRadius: [3, 3, 0, 0],
// color: '#00CC99'
// }e
color: colorList[index]
},
data: item.list
})
})
nextTick(() => {
barCharts.value && barCharts.value.initChart()
})
return
}
const handleClick = (tab: any, event: any) => {
// activeName.value = tabsList.value[tab.index].id
// activeName.value = tab.index
params.value.groupId = tabsList.value[tab.index].id
findRealTrendDataByGroupId(params.value)
// reverseTable()
init()
}
onMounted(() => {
// init()
})
defineExpose({ open })
</script>
<style lang="scss" scoped>
.realtrend {
width: 100%;
height: 100%;
.realtrend_top {
width: 100%;
height: auto;
display: flex;
justify-content: space-between;
align-items: center;
.thead {
height: 100%;
overflow-y: hidden;
border: 1px solid #eee;
border-right: 0;
ul {
width: auto;
height: 40px;
display: flex;
li {
flex: none;
width: 100px;
line-height: 40px;
border: 1px solid #eee;
text-align: center;
list-style: none;
}
li:nth-child(1) {
flex: none;
width: 200px;
}
}
ul:nth-child(1) {
li {
font-weight: 800;
background: #f4f6f9;
}
}
}
.table {
flex: 1;
// min-height: 80px;
cursor: pointer;
min-height: 90px;
max-height: 170px;
border: 1px solid #eee;
overflow-x: auto;
overflow-y: hidden;
position: relative;
ul {
width: auto;
height: 40px;
display: flex;
li {
flex: none;
width: 100px;
line-height: 40px;
border: 1px solid #eee;
text-align: center;
list-style: none;
}
}
ul:nth-child(1) {
li {
font-weight: 800;
background: #f4f6f9;
}
}
}
.table::-webkit-scrollbar {
display: none;
}
}
}
.reverse-table .vxe-body--row .vxe-body--column:first-child {
background-color: #f8f8f9;
}
::v-deep .vxe-table--render-wrapper {
height: 90px !important;
max-height: 90px !important;
overflow-x: auto !important;
min-height: 0 !important;
}
::v-deep .body--wrapper {
height: 90px !important;
max-height: 90px !important;
min-height: 0 !important;
}
.tab_info {
width: 100%;
height: calc(100vh - 450px);
// overflow: auto;
// padding-bottom: 20px;
.charts {
width: 100%;
margin-top: 10px;
height: calc(100vh - 550px);
}
}
.custom-tabs-label {
display: flex;
align-items: center;
}
</style>