This commit is contained in:
GGJ
2024-01-02 16:35:07 +08:00
5 changed files with 473 additions and 17 deletions

View File

@@ -9,9 +9,13 @@ import 'echarts/lib/component/dataZoom'
const chartRef = ref<HTMLDivElement>() const chartRef = ref<HTMLDivElement>()
const props = defineProps(['options']) const props = defineProps(['options'])
let chart: echarts.ECharts | null = null let chart: echarts.ECharts | any = null
const resizeHandler = () => { const resizeHandler = () => {
chart?.resize() chart.getZr().painter.getViewportRoot().style.display = "none";
requestAnimationFrame(() => {
chart.resize()
chart.getZr().painter.getViewportRoot().style.display = "";
})
} }
const initChart = () => { const initChart = () => {
chart?.dispose() chart?.dispose()
@@ -88,7 +92,6 @@ const initChart = () => {
], ],
yAxis: [ yAxis: [
{ {
type: 'value', type: 'value',
nameTextStyle: { nameTextStyle: {
@@ -148,9 +151,7 @@ const initChart = () => {
}) })
} }
onMounted(() => { onMounted(() => {
setTimeout(() => { initChart()
// initChart()
}, 20)
window.addEventListener('resize', resizeHandler) window.addEventListener('resize', resizeHandler)
}) })
defineExpose({ initChart }) defineExpose({ initChart })

View File

@@ -0,0 +1,11 @@
export const defaultAttribute = {
align: 'center',
class: 'ba-data-table w100',
headerCellClassName: 'table-header-cell',
border: true,
stripe: true,
size: 'small',
columnConfig: { resizable: true },
rowConfig: { isCurrent: true, isHover: true },
scrollX: { scrollToLeftOnChange: true },
}

View File

@@ -1,18 +1,9 @@
<template> <template>
<vxe-table <vxe-table
ref='tableRef' ref='tableRef'
class='ba-data-table w100'
header-cell-class-name='table-header-cell'
:data='tableStore.table.data' :data='tableStore.table.data'
:border='true'
v-loading='tableStore.table.loading' v-loading='tableStore.table.loading'
stripe v-bind='Object.assign({}, defaultAttribute, $attrs)'
size='small'
@checkbox-change='onSelectionChange'
v-bind='$attrs'
:column-config='{resizable: true}'
:tree-config='{}'
:row-config='{isCurrent: true, isHover: true}'
> >
<!-- Column 组件内部是 el-table-column --> <!-- Column 组件内部是 el-table-column -->
<template v-if='isGroup'> <template v-if='isGroup'>
@@ -88,6 +79,7 @@ import FieldRender from '@/components/table/fieldRender/index.vue'
import Column from '@/components/table/column/index.vue' import Column from '@/components/table/column/index.vue'
import { useConfig } from '@/stores/config' import { useConfig } from '@/stores/config'
import type TableStoreClass from '@/utils/tableStore' import type TableStoreClass from '@/utils/tableStore'
import { defaultAttribute } from '@/components/table/defaultAttribute'
const config = useConfig() const config = useConfig()
const tableRef = ref<TableInstance>() const tableRef = ref<TableInstance>()
@@ -102,7 +94,7 @@ const props = withDefaults(defineProps<Props>(), {
pagination: true, pagination: true,
isGroup: false isGroup: false
}) })
console.log(props)
const onTableSizeChange = (val: number) => { const onTableSizeChange = (val: number) => {
tableStore.onTableAction('page-size-change', { size: val }) tableStore.onTableAction('page-size-change', { size: val })
} }

View File

@@ -144,6 +144,21 @@ const init = async () => {
extend: 'none', extend: 'none',
children: [] children: []
}, },
{
id: 1,
pid: 3,
type: 'menu',
title: '终端运行统计',
name: 'voltage/sags/operationsManagement/statistics',
path: 'voltage/sags/operationsManagement/statistics',
icon: 'fa-solid fa-chart-column',
menu_type: 'tab',
url: '',
component: '/src/views/voltage/sags/operationsManagement/statistics.vue',
keepalive: 'voltage/sags/operationsManagement/statistics',
extend: 'none',
children: []
},
{ {
id: 1, id: 1,
pid: 3, pid: 3,

View File

@@ -0,0 +1,437 @@
<template>
<div class='default-main'>
<TableHeader date-picker :showOperation='false' showSelect>
<template v-slot:select>
<el-form-item label='区域'>
<Area v-model='tableStore.table.params.deptIndex' />
</el-form-item>
</template>
</TableHeader>
<div style='font-weight: bold; background: #fff;text-indent: 1em'>
<span style='color: #000'>
(左柱):
<span style='color: #0099cc'>
<span class='smallBlock' style='background: #0099cc'></span>
投运
</span>
<span style='color: #996600'>
<span class='smallBlock' style='background: #996600'></span>
热备用
</span>
<span style='color: #cc0000'>
<span class='smallBlock' style='background: #cc0000'></span>
停运
</span>
</span>
&nbsp;&nbsp;
<span style='color: #000'>
(右柱):
<span style='color: #2e8b57'>
<span class='smallBlock' style='background: #2e8b57'></span>
{{ '在线率≥90 %' }}
</span>
<span style='color: #daa520'>
<span class='smallBlock' style='background: #daa520'></span>
{{ '60 %≤在线率 < 90 %' }}
</span>
<span style='color: #cc0000'>
<span class='smallBlock' style='background: #cc0000'></span>
{{ '在线率 < 60 %' }}
</span>
</span>
</div>
<div class='statistics-main' v-loading='tableStore.table.loading'>
<template v-if='!tableStore.table.loading'>
<div>
<my-echart :options='areaStatistics' />
</div>
<div>
<vxe-table
height='auto'
auto-resize
:data='tableStore.table.data.area.areaInfo'
v-bind='defaultAttribute'
>
<vxe-column field='areaName' title='区域'></vxe-column>
<vxe-column field='numberOfTerminals' title='终端个数' width='80'></vxe-column>
<vxe-column field='normal' title='投运' width='80'></vxe-column>
<vxe-column field='breaks' title='热备用' width='80'></vxe-column>
<vxe-column field='shutdown' title='停运' width='80'></vxe-column>
<vxe-column field='onlineRate' title='在线率(%'>
<template v-slot:default='scoped'>
{{ scoped.row.onlineRate === 3.14159 ? '/' : scoped.row.onlineRate }}
</template>
</vxe-column>
</vxe-table>
</div>
<div>
<my-echart :options='factoryStatistics' />
</div>
<div>
<vxe-table
height='auto'
auto-resize
:data='tableStore.table.data.factory.areaInfo'
v-bind='defaultAttribute'
>
<vxe-column field='areaName' title='厂家'></vxe-column>
<vxe-column field='numberOfTerminals' title='终端个数' width='80'></vxe-column>
<vxe-column field='normal' title='投运' width='80'></vxe-column>
<vxe-column field='breaks' title='热备用' width='80'></vxe-column>
<vxe-column field='shutdown' title='停运' width='80'></vxe-column>
<vxe-column field='onlineRate' title='在线率(%'>
<template v-slot:default='scoped'>
{{ scoped.row.onlineRate === 3.14159 ? '/' : scoped.row.onlineRate }}
</template>
</vxe-column>
</vxe-table>
</div>
</template>
</div>
</div>
</template>
<script setup lang='ts'>
import TableHeader from '@/components/table/header/index.vue'
import Area from '@/components/form/area/index.vue'
import TableStore from '@/utils/tableStore'
import { onMounted, provide, reactive, ref } from 'vue'
import { useDictData } from '@/stores/dictData'
import { mainHeight } from '@/utils/layout'
import MyEchart from '@/components/echarts/MyEchart.vue'
import * as echarts from 'echarts/core'
import { defaultAttribute } from '@/components/table/defaultAttribute'
defineOptions({
name: 'voltage/sags/operationsManagement/statistics'
})
const dictData = useDictData()
const areaStatistics = ref(null)
const factoryStatistics = ref(null)
const tableStore = new TableStore({
url: '/event-boot/area/getTerminalRunningStatistics',
method: 'POST',
loadCallback: () => {
areaStatistics.value = {
legend: {
show: false
},
title: {
text: '区域'
},
xAxis: {
type: 'category',
data: tableStore.table.data.area.areaInfo.map(
(item: any) => item.areaName + `(${item.numberOfTerminals})`
)
},
yAxis: {
type: 'value'
},
options: {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
color: '#fff',
fontSize: 16
}
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
opacity: 0.35,
fontSize: 14
},
backgroundColor: 'rgba(0,0,0,0.35)',
formatter: function(params) {
var tips = ''
tips += params[0].name + '</br/>'
for (var i = 0; i < params.length; i++) {
if (params[i].value == 3.14159) {
tips += params[i].seriesName + ':暂无数据<br/>'
} else {
tips += params[i].seriesName + ':' + params[i].value + '%<br/>'
}
}
return tips
}
},
series: [
{
stack: 'one',
name: '投运',
data: tableStore.table.data.area.areaInfo.map((item: any) => item.normalRate),
itemStyle: {
normal: {
color: function(params) {
if (params.value != 3.14159) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#0099CC'
}
])
} else if ((params.value = 3.14159)) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#ccc'
}
])
}
}
}
},
type: 'bar'
},
{
name: '热备用',
stack: 'one',
data: tableStore.table.data.area.areaInfo.map((item: any) => item.shutdownRate),
type: 'bar',
itemStyle: {
normal: {
color: function(params) {
if (params.value != 3.14159) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#cc0000'
}
])
} else if ((params.value = 3.14159)) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#ccc'
}
])
}
}
}
}
},
{
name: '在线率',
stack: 'two',
data: tableStore.table.data.area.areaInfo.map((item: any) => item.onlineRate),
itemStyle: {
normal: {
color: function(params) {
if (params.value >= 90) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#339966'
}
])
} else if (params.value >= 60 && params.value <= 90) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#FFCC33'
}
])
} else if (params.value <= 60 && params.value != 3.14159) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#CC0000'
}
])
} else if ((params.value = 3.14159)) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#ccc'
}
])
}
}
}
},
type: 'bar'
}
]
}
}
factoryStatistics.value = {
legend: {
show: false
},
title: {
text: '终端厂家'
},
xAxis: {
type: 'category',
data: tableStore.table.data.factory.areaInfo.map(
(item: any) => item.areaName + `(${item.numberOfTerminals})`
)
},
yAxis: {
type: 'value'
},
options: {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
color: '#fff',
fontSize: 16
}
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
opacity: 0.35,
fontSize: 14
},
backgroundColor: 'rgba(0,0,0,0.35)',
formatter: function(params) {
var tips = ''
tips += params[0].name + '</br/>'
for (var i = 0; i < params.length; i++) {
if (params[i].value == 3.14159) {
tips += params[i].seriesName + ':暂无数据<br/>'
} else {
tips += params[i].seriesName + ':' + params[i].value + '%<br/>'
}
}
return tips
}
},
series: [
{
stack: 'one',
name: '投运',
data: tableStore.table.data.factory.areaInfo.map((item: any) => item.normalRate),
itemStyle: {
normal: {
color: function(params) {
if (params.value != 3.14159) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#0099CC'
}
])
} else if ((params.value = 3.14159)) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#ccc'
}
])
}
}
}
},
type: 'bar'
},
{
name: '热备用',
stack: 'one',
data: tableStore.table.data.factory.areaInfo.map((item: any) => item.shutdownRate),
type: 'bar',
itemStyle: {
normal: {
color: function(params) {
if (params.value != 3.14159) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#cc0000'
}
])
} else if ((params.value = 3.14159)) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#ccc'
}
])
}
}
}
}
},
{
name: '在线率',
stack: 'two',
data: tableStore.table.data.factory.areaInfo.map((item: any) => item.onlineRate),
itemStyle: {
normal: {
color: function(params) {
if (params.value >= 90) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#339966'
}
])
} else if (params.value >= 60 && params.value <= 90) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#FFCC33'
}
])
} else if (params.value <= 60 && params.value != 3.14159) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#CC0000'
}
])
} else if ((params.value = 3.14159)) {
return new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 1,
color: '#ccc'
}
])
}
}
}
},
type: 'bar'
}
]
}
}
}
})
provide('tableStore', tableStore)
tableStore.table.params.deptIndex = dictData.state.area[0].id
tableStore.table.params.serverName = 'event-boot'
tableStore.table.params.monitorFlag = 2
tableStore.table.params.powerFlag = 2
tableStore.table.params.statisticalType = {
name: '电网拓扑',
id: 'cc28974d259ad22642f6a1bff708f967',
code: 'Power_Network',
value: 'cc28974d259ad22642f6a1bff708f967',
gvalue: null,
label: '电网拓扑',
sort: 0
}
onMounted(() => {
tableStore.index()
})
const layout = mainHeight(104) as any
</script>
<style lang='scss' scoped>
.statistics-main {
box-sizing: border-box;
height: v-bind('layout.height');
padding: 0 10px 10px;
display: grid;
grid-template-columns: 1fr 600px;
grid-template-rows: 1fr 1fr;
grid-gap: 10px;
background: #fff;
}
</style>