15 Commits

Author SHA1 Message Date
84f454ea8a screen 2026-01-28 20:33:31 +08:00
ac1d1ae154 更新workStatus状态枚举 2026-01-25 16:45:33 +08:00
825243e741 电池簇备注 2026-01-25 16:36:23 +08:00
0389ed85f3 Merge branch 'develop' of http://101.43.41.9:13000/xzzn/emsfront into develop 2026-01-25 16:33:00 +08:00
aef94f406a 电池簇、电池堆工作状态更新 2026-01-25 16:30:43 +08:00
95d69fb7b1 簇枚举变更 2026-01-25 16:27:35 +08:00
684002ffc8 簇枚举变更 2026-01-25 15:12:07 +08:00
098dfa05f8 簇枚举变更 2026-01-25 14:34:01 +08:00
d6c9310e50 净置改成静置 2026-01-25 13:54:23 +08:00
142de3102b 大数据图片更新 2026-01-24 21:14:43 +08:00
9b5806a2c0 0或没有返回值隐藏alarmNum的展示 2026-01-24 10:27:43 +08:00
2b6697fa5a pointName改成 dataPointName 2026-01-24 10:02:11 +08:00
3bb859b693 BMS电池簇数据同步 2026-01-23 22:32:12 +08:00
5b3701afd0 BMS总览数据同步 2026-01-23 22:02:02 +08:00
f531075853 电表数据同步 2026-01-23 21:46:02 +08:00
15 changed files with 478 additions and 236 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 MiB

After

Width:  |  Height:  |  Size: 11 MiB

View File

@ -41,7 +41,6 @@
<svg-icon icon-class="more-up"/>
</div>
</div>
<BigDataPopup ref="bigDataPopup"/>
</div>
</template>
@ -53,7 +52,6 @@ import Hamburger from '@/components/Hamburger'
import Screenfull from '@/components/Screenfull'
import SizeSelect from '@/components/SizeSelect'
import Search from '@/components/HeaderSearch'
import BigDataPopup from '@/components/BigDataPopup'
export default {
emits: ['setLayout'],
@ -63,8 +61,7 @@ export default {
Hamburger,
Screenfull,
SizeSelect,
Search,
BigDataPopup
Search
},
computed: {
...mapGetters([
@ -86,7 +83,10 @@ export default {
},
methods: {
showBigDataImg() {
this.$refs.bigDataPopup.show = true
const routeUrl = this.$router.resolve({
path: '/screen'
})
window.open(routeUrl.href, '_blank')
},
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')

View File

@ -52,6 +52,11 @@ export const constantRoutes = [
component: () => import('@/views/register'),
hidden: true
},
{
path: '/screen',
component: () => import('@/views/screen/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/error/404'),

View File

@ -5,9 +5,17 @@ const ems = {
dzjkAlarmLighting: false,//单站监控 告警统计红点标志
zdList: [],
zdDeviceCategoryOptions: {},//站点各个站点包含的设备种类 {021_DDS_01:["BATTERY","CLUSTER","STACK", "DH", "AMMETER", "PCS", "XF"],021_DDS_02:[]...}
workStatusOptions: {'0': '运行', '1': '机', '2': '故障'},//工作状态
CLUSTERWorkStatusOptions: {'0': '静置', '1': '充电', '2': '放电', '3': '待机', '5': '运行', '9': "故障"},//电池簇工作状态
PCSWorkStatusOptions: {'0': '运行', '1': '停机', '2': '故障', '3': '待机', '4': '充电', '5': '放电'},//PCS工作状态
STACKWorkStatusOptions: {"0": "净置", "1": "充电", "2": "放电", "3": "浮充", '9': "故障"},//STACK电池簇工作状态
STACKWorkStatusOptions: {
"0": "静置",
"1": "充电",
"2": "放电",
"3": "浮充",
'4': '待机',
'5': '运行',
'9': "故障"
},//STACKBMS总览工作状态
deviceStatusOptions: {'0': '离线', '1': '在线'},//设备状态
gridStatusOptions: {'0': '并网', '1': '未并网'},//并网状态
controlModeOptions: {'0': '远程', '1': '本地'},//控制模式

View File

@ -3,11 +3,7 @@
<div v-for="(baseInfo,index) in baseInfoList" :key="index+'bmsdccContainer'" style="margin-bottom:25px;">
<el-card shadow="always"
class="sbjk-card-container common-card-container-body-no-padding common-card-container-no-title-bg"
:class="{
'timing-card-container':!['0','2'].includes(baseInfo.workStatus),
'warning-card-container':baseInfo.workStatus === '2',
'running-card-container':baseInfo.workStatus === '0'
}">
:class="handleCardClass(baseInfo)">
<div slot="header">
<span
class="large-title">{{
@ -20,7 +16,7 @@
<el-button type="primary" round size="small" style="margin-right:20px;"
@click="pointDetail(baseInfo,'point')">详细
</el-button>
<el-badge :value="baseInfo.alarmNum || 0" class="item">
<el-badge :hidden="!baseInfo.alarmNum" :value="baseInfo.alarmNum || 0" class="item">
<i
class="el-icon-message-solid alarm-icon"
@click="pointDetail(baseInfo,'alarmPoint')"
@ -30,16 +26,16 @@
</div>
<div class="descriptions-main">
<el-descriptions direction="vertical" :column="3" :colon="false">
<el-descriptions-item labelClassName="descriptions-label"
:contentClassName="`descriptions-direction ${baseInfo.workStatus === '0' ? 'save' :'danger'}`"
<el-descriptions-item
contentClassName="descriptions-direction work-status"
:span="1" label="工作状态">
{{ $store.state.ems.workStatusOptions[baseInfo.workStatus] }}
{{ CLUSTERWorkStatusOptions[baseInfo.workStatus] }}
</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction"
<el-descriptions-item contentClassName="descriptions-direction"
:span="1" label="与PCS通信">
{{ $store.state.ems.communicationStatusOptions[baseInfo.pcsCommunicationStatus] }}
</el-descriptions-item>
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction"
<el-descriptions-item contentClassName="descriptions-direction"
:span="1" label="与EMS通信">
{{ $store.state.ems.communicationStatusOptions[baseInfo.emsCommunicationStatus] }}
</el-descriptions-item>
@ -132,11 +128,17 @@ import PointTable from "@/views/ems/site/sblb/PointTable.vue";
import {getBMSBatteryCluster} from '@/api/ems/dzjk'
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
import intervalUpdate from "@/mixins/ems/intervalUpdate";
import {mapState} from "vuex";
export default {
name: 'DzjkSbjkBmsdcc',
mixins: [getQuerySiteId, intervalUpdate],
components: {PointTable, pointChart},
computed: {
...mapState({
CLUSTERWorkStatusOptions: state => state?.ems?.CLUSTERWorkStatusOptions || {},
})
},
data() {
return {
loading: false,
@ -171,6 +173,10 @@ export default {
}
},
methods: {
handleCardClass(item) {
const {workStatus = ''} = item
return !(Object.keys(this.CLUSTERWorkStatusOptions).includes(item.workStatus)) ? "timing-card-container" : workStatus === '9' ? 'warning-card-container' : 'running-card-container'
},
// 查看设备电位表格
pointDetail(row, dataType) {
const {siteId, deviceId} = row

View File

@ -14,7 +14,7 @@
<el-button type="primary" round size="small" style="margin-right:20px;"
@click="pointDetail(baseInfo,'point')">详细
</el-button>
<el-badge :value="baseInfo.alarmNum || 0" class="item">
<el-badge :hidden="!baseInfo.alarmNum" :value="baseInfo.alarmNum || 0" class="item">
<i
class="el-icon-message-solid alarm-icon"
@click="pointDetail(baseInfo,'alarmPoint')"
@ -170,7 +170,7 @@ export default {
mixins: [getQuerySiteId, intervalUpdate],
computed: {
...mapState({
STACKWorkStatusOptions: state => state?.ems?.PCSWorkStatusOptions || {},
STACKWorkStatusOptions: state => state?.ems?.STACKWorkStatusOptions || {},
})
},
data() {

View File

@ -6,7 +6,8 @@
shadow="always"
class="sbjk-card-container list"
:class="{
'warning-card-container':item.emsCommunicationStatus && item.emsCommunicationStatus !== '0',
'timing-card-container':!['0','2'].includes(item.emsCommunicationStatus),
'warning-card-container':item.emsCommunicationStatus === '2',
'running-card-container':item.emsCommunicationStatus === '0'
}"
>
@ -15,18 +16,16 @@
<div class="info">
<div>
{{
$store.state.ems.communicationStatusOptions[
item.emsCommunicationStatus
]
communicationStatusOptions[item.emsCommunicationStatus] || '-'
}}
</div>
<div>数据更新时间{{ item.dataUpdateTime }}</div>
<div>数据更新时间{{ item.dataUpdateTime || '-' }}</div>
</div>
<div class="alarm">
<el-button type="primary" round size="small" style="margin-right:20px;" @click="pointDetail(item,'point')">
详细
</el-button>
<el-badge :value="item.alarmNum || 0" class="item">
<el-badge :hidden="!item.alarmNum" :value="item.alarmNum || 0" class="item">
<i
class="el-icon-message-solid alarm-icon"
@click="pointDetail(item,'alarmPoint')"
@ -57,11 +56,18 @@ import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
import {getAmmeterDataList} from "@/api/ems/dzjk";
import intervalUpdate from "@/mixins/ems/intervalUpdate";
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
import {mapState} from "vuex";
export default {
name: "DzjkSbjkDb",
mixins: [getQuerySiteId, intervalUpdate],
components: {PointTable, pointChart},
computed: {
...mapState({
communicationStatusOptions: state => state?.ems?.communicationStatusOptions || {},
})
},
data() {
return {
loading: false,

View File

@ -14,7 +14,7 @@
<el-button type="primary" round size="small" style="margin-right:20px;" @click="pointDetail(item,'point')">
详细
</el-button>
<el-badge :value="item.alarmNum || 0" class="item">
<el-badge :hidden="!item.alarmNum" :value="item.alarmNum || 0" class="item">
<i
class="el-icon-message-solid alarm-icon"
@click="pointDetail(item,'alarmPoint')"

View File

@ -1,206 +1,5 @@
<template>
<div v-loading="loading" class="ems">
<!-- <div-->
<!-- v-for="(item, index) in list"-->
<!-- :key="index + 'PcsHome'"-->
<!-- style="margin-bottom: 25px"-->
<!-- >-->
<!-- <el-card-->
<!-- :class="{-->
<!-- 'warning-card-container': item.workStatus === '1',-->
<!-- 'timing-card-container': item.workStatus === '2',-->
<!-- 'running-card-container': !['1', '2'].includes(item.workStatus),-->
<!-- }"-->
<!-- class="sbjk-card-container common-card-container-body-no-padding common-card-container-no-title-bg"-->
<!-- shadow="always"-->
<!-- >-->
<!-- &lt;!&ndash; 标题&ndash;&gt;-->
<!-- <div slot="header">-->
<!-- <span class="large-title"-->
<!-- >{{ item.deviceName }}</span-->
<!-- >-->
<!-- <div class="info">-->
<!-- <div>-->
<!-- {{-->
<!-- $store.state.ems.workStatusOptions[item.workStatus]-->
<!-- }}-->
<!-- </div>-->
<!-- <div>数据更新时间{{ item.dataUpdateTime }}</div>-->
<!-- </div>-->
<!-- <div class="alarm">-->
<!-- <el-button type="primary" size="small" style="margin-right:20px;" @click="pointDetail(item,'point')">-->
<!-- 详细-->
<!-- </el-button>-->
<!-- <el-badge :value="item.alarmNum || 0" class="item">-->
<!-- <i-->
<!-- class="el-icon-message-solid alarm-icon"-->
<!-- @click="pointDetail(item,'alarmPoint')"-->
<!-- ></i>-->
<!-- </el-badge>-->
<!-- </div>-->
<!-- </div>-->
<!-- &lt;!&ndash; 工作状态&ndash;&gt;-->
<!-- <div class="descriptions-main">-->
<!-- <el-descriptions :colon="false" :column="5" direction="vertical">-->
<!-- <el-descriptions-item-->
<!-- :contentClassName="`descriptions-direction ${-->
<!-- item.workStatus === '0' ? 'save' : 'danger'-->
<!-- }`"-->
<!-- :span="1"-->
<!-- label="工作状态"-->
<!-- labelClassName="descriptions-label"-->
<!-- >{{-->
<!-- $store.state.ems.workStatusOptions[item.workStatus]-->
<!-- }}-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- <el-descriptions-item-->
<!-- :span="1"-->
<!-- contentClassName="descriptions-direction"-->
<!-- label="工作模式"-->
<!-- labelClassName="descriptions-label"-->
<!-- >-->
<!-- todo 手动/自动-->
<!-- {{-->
<!-- $store.state.ems.gridStatusOptions[item.gridStatus]-->
<!-- }}-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- <el-descriptions-item-->
<!-- :span="1"-->
<!-- contentClassName="descriptions-direction"-->
<!-- label="并网状态"-->
<!-- labelClassName="descriptions-label"-->
<!-- >{{-->
<!-- $store.state.ems.gridStatusOptions[item.gridStatus]-->
<!-- }}-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- <el-descriptions-item-->
<!-- :span="1"-->
<!-- contentClassName="descriptions-direction"-->
<!-- label="告警状态"-->
<!-- labelClassName="descriptions-label"-->
<!-- >-->
<!-- todo-->
<!-- &lt;!&ndash;-->
<!-- {{-->
<!-- $store.state.ems.warnOptions[item.warnMode]-->
<!-- }}&ndash;&gt;-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- <el-descriptions-item-->
<!-- :contentClassName="`descriptions-direction ${-->
<!-- item.deviceStatus === '2' ? 'save' : 'danger'-->
<!-- }`"-->
<!-- :span="1"-->
<!-- label="设备状态"-->
<!-- labelClassName="descriptions-label"-->
<!-- >{{-->
<!-- $store.state.ems.deviceStatusOptions[item.deviceStatus]-->
<!-- }}-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- </el-descriptions>-->
<!-- </div>-->
<!-- &lt;!&ndash; 用电量&ndash;&gt;-->
<!-- <div class="descriptions-main descriptions-main-bg-color">-->
<!-- <el-descriptions :colon="false" :column="5" direction="vertical">-->
<!-- <el-descriptions-item-->
<!-- :span="5"-->
<!-- contentClassName="descriptions-direction"-->
<!-- label="当日用电量:"-->
<!-- labelClassName="descriptions-label"-->
<!-- >-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- <el-descriptions-item-->
<!-- :span="1"-->
<!-- contentClassName="descriptions-direction"-->
<!-- label="电网用电量"-->
<!-- labelClassName="descriptions-label"-->
<!-- >-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- <el-descriptions-item-->
<!-- :span="1"-->
<!-- contentClassName="descriptions-direction"-->
<!-- label="储能放电量"-->
<!-- labelClassName="descriptions-label"-->
<!-- >-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- <el-descriptions-item-->
<!-- :span="1"-->
<!-- contentClassName="descriptions-direction"-->
<!-- label="储能充电量"-->
<!-- labelClassName="descriptions-label"-->
<!-- >-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- <el-descriptions-item-->
<!-- :span="1"-->
<!-- contentClassName="descriptions-direction"-->
<!-- label="负荷用电量"-->
<!-- labelClassName="descriptions-label"-->
<!-- >-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- <el-descriptions-item-->
<!-- :span="1"-->
<!-- contentClassName="descriptions-direction"-->
<!-- label="光伏发电量"-->
<!-- labelClassName="descriptions-label"-->
<!-- >-->
<!-- </el-descriptions-item-->
<!-- >-->
<!-- </el-descriptions>-->
<!-- </div>-->
<!-- &lt;!&ndash; 表格&ndash;&gt;-->
<!-- <el-table-->
<!-- class="common-table"-->
<!-- stripe-->
<!-- style="width: 100%;margin-top:25px;">-->
<!-- <el-table-column-->
<!-- label="功率"-->
<!-- prop="type">-->
<!-- </el-table-column>-->
<!-- <el-table-column-->
<!-- label="电网"-->
<!-- >-->
<!-- <template slot-scope="scope">-->
<!-- <span class="pointer"-->
<!-- @click="showChart('簇电压',scope.row.clusterId)">{{ scope.row.clusterVoltage }} V</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column-->
<!-- label="储能">-->
<!-- <template slot-scope="scope">-->
<!-- <span class="pointer"-->
<!-- @click="showChart('簇电流',scope.row.clusterId)">{{ scope.row.clusterCurrent }} A</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column-->
<!-- label="负荷">-->
<!-- <template slot-scope="scope">-->
<!-- <span class="pointer"-->
<!-- @click="showChart('簇电流',scope.row.clusterId)">{{ scope.row.clusterCurrent }} A</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column-->
<!-- label="光伏">-->
<!-- <template slot-scope="scope">-->
<!-- <span class="pointer"-->
<!-- @click="showChart('当前SOC',scope.row.clusterId)">{{ scope.row.currentSoc }} %</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- </el-table>-->
<!-- &lt;!&ndash; 图表&ndash;&gt;-->
<!-- <div id="emsChart" style="height: 350px"></div>-->
<!-- </el-card>-->
<!-- </div>-->
<el-card
v-for="(item,index) in list"
:key="index+'emsList'"
@ -220,7 +19,7 @@
<div class="alarm">
<el-button size="small" round style="margin-right:20px;" type="primary" @click="pointDetail(item,'point')">详细
</el-button>
<el-badge :value="item.alarmNum || 0" class="item">
<el-badge :hidden="!item.alarmNum" :value="item.alarmNum || 0" class="item">
<i
class="el-icon-message-solid alarm-icon"
@click="pointDetail(item,'alarmPoint')"

View File

@ -31,7 +31,7 @@
@click="pointDetail(pcsItem,'point')">
详细
</el-button>
<el-badge :value="pcsItem.alarmNum || 0" class="item">
<el-badge :hidden="!pcsItem.alarmNum" :value="pcsItem.alarmNum || 0" class="item">
<i
class="el-icon-message-solid alarm-icon"
@click="pointDetail(pcsItem,'alarmPoint')"

View File

@ -25,7 +25,7 @@
<el-button type="primary" round size="small" style="margin-right:20px;" @click="pointDetail(item,'point')">
详细
</el-button>
<el-badge :value="item.alarmNum || 0" class="item">
<el-badge :hidden="!item.alarmNum" :value="item.alarmNum || 0" class="item">
<i
class="el-icon-message-solid alarm-icon"
@click="pointDetail(item,'alarmPoint')"

View File

@ -14,7 +14,7 @@
<el-button type="primary" round size="small" style="margin-right:20px;" @click="pointDetail(item,'point')">
详细
</el-button>
<el-badge :value="item.alarmNum || 0" class="item">
<el-badge :hidden="!item.alarmNum" :value="item.alarmNum || 0" class="item">
<i
class="el-icon-message-solid alarm-icon"
@click="pointDetail(item,'alarmPoint')"

View File

@ -80,7 +80,7 @@
<el-table-column label="数据点位" prop="dataPoint"></el-table-column>
<el-table-column
label="数据点位名称"
prop="pointName"
prop="dataPointName"
></el-table-column>
<!-- <el-table-column label="modbus地址">-->
<!-- <template slot-scope="scope">-->
@ -88,8 +88,8 @@
<!-- `${scope.row.ipAddress || ""} ${scope.row.ipPort || ""}`-->
<!-- }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="寄存器地址" prop="寄存器地址"></el-table-column>
<!-- </el-table-column>
<el-table-column label="寄存器地址" prop="寄存器地址"></el-table-column>-->
<el-table-column
label="最新值"
prop="pointValue"

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 MiB

418
src/views/screen/index.vue Normal file
View File

@ -0,0 +1,418 @@
<template>
<div class="big-screen-container">
<!-- 背景容器 -->
<div class="bg-wrapper">
<!-- 右侧功率曲线图表 -->
<div class="chart-box power-chart">
<div ref="powerChart" class="chart-content"></div>
</div>
<!-- 底部中间电力需求曲线图表width:980px, bottom:26px -->
<div class="chart-box demand-chart">
<div ref="demandChart" class="chart-content"></div>
</div>
</div>
</div>
</template>
<script>
import * as echarts from 'echarts'
import { getPointData } from '@/api/ems/dzjk'
export default {
name: 'PowerCurveScreen',
data() {
return {
powerChartInstance: null, // 功率曲线实例
demandChartInstance: null, // 电力需求曲线实例
timer: null,
siteId: '021_DDS_01',
}
},
mounted() {
this.initPowerChart() // 初始化功率曲线
this.initDemandChart() // 初始化电力需求曲线
// Initial fetch
this.fetchData()
// Polling every 5 seconds
this.timer = setInterval(() => {
this.fetchData()
}, 5000)
window.addEventListener('resize', this.resizeAllCharts)
},
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
// 销毁两个图表实例
if (this.powerChartInstance) {
this.powerChartInstance.dispose()
this.powerChartInstance = null
}
if (this.demandChartInstance) {
this.demandChartInstance.dispose()
this.demandChartInstance = null
}
window.removeEventListener('resize', this.resizeAllCharts)
},
methods: {
getTodayDate() {
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0')
const day = String(now.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
},
fetchData() {
const today = this.getTodayDate()
getPointData({
siteId: this.siteId,
startDate: today,
endDate: today
}).then(response => {
if (response.code === 200 && response.data) {
this.updateCharts(response.data)
}
}).catch(error => {
console.error('Failed to fetch point data:', error)
})
},
updateCharts(data) {
if (!data || !Array.isArray(data)) return
const source = [['日期', '电网功率', '负载功率', '储能功率', '光伏功率']];
const demandSource = [['日期', '电网功率', '负载功率']]
data.forEach(item => {
source.push([
item.statisDate,
item.gridPower,
item.loadPower,
item.storagePower,
item.pvPower
]);
demandSource.push([
item.statisDate,
item.gridPower, // Mapping Grid Power to Plan Demand (or just as 2nd series)
item.loadPower, // Mapping Load Power to Actual Demand
])
})
if (this.powerChartInstance) {
this.powerChartInstance.setOption({
dataset: {
source: source
}
})
}
if (this.demandChartInstance) {
this.demandChartInstance.setOption({
dataset: {
source: demandSource
}
})
}
},
// 初始化右侧功率曲线
initPowerChart() {
this.powerChartInstance = echarts.init(this.$refs.powerChart)
const option = {
backgroundColor: 'transparent',
tooltip: {
trigger: 'axis',
confine: true,
backgroundColor: 'rgba(0, 30, 60, 0.9)',
borderColor: '#00ccff',
textStyle: { color: '#fff' },
axisPointer: {
type: 'line',
lineStyle: {
color: 'rgba(0, 204, 255, 0.5)',
type: 'dashed'
}
}
},
legend: {
textStyle: { color: '#00ccff', fontSize: 10 },
bottom: 0,
left: 'center',
itemWidth: 9,
itemHeight: 9,
itemGap: 8,
padding: [0, 0, 0, 0]
},
grid: {
left: '2%',
right: '2%',
top: '15%',
bottom: '12%',
containLabel: true
},
dataset: {
source: [] // Initial empty source
},
xAxis: {
type: 'category',
boundaryGap: false,
axisLabel: {
color: '#00ccff',
fontSize: 10,
rotate: 0, // 取消旋转,因为标签较少
margin: 10,
},
axisLine: {
show: true,
lineStyle: { color: '#006699', width: 1.5 }
},
splitLine: { show: false },
axisTick: { show: true }
},
yAxis: {
type: 'value',
min: 0, // Remove fixed min/max to let it auto-scale
max: 350,
interval: 50,
axisLabel: {
color: '#00ccff',
fontSize: 12,
margin: 10,
fontWeight: 'bold'
},
axisLine: {
show: false,
lineStyle: { color: '#006699', width: 1.5 }
},
splitLine: { lineStyle: { color: 'rgba(0, 100, 150, 0.2)' } },
axisTick: { show: false }
},
series: [
{
// name: '电网功率', // Removed, auto-matched from dataset header
type: 'line',
// data: [], // Removed
smooth: true,
symbol: 'none',
lineStyle: { color: '#0099ff', width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(0, 153, 255, 0.4)' },
{ offset: 1, color: 'rgba(0, 153, 255, 0.05)' }
])
}
},
{
// name: '负载功率',
type: 'line',
// data: [],
smooth: true,
symbol: 'none',
lineStyle: { color: '#00cc66', width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(0, 204, 102, 0.4)' },
{ offset: 1, color: 'rgba(0, 204, 102, 0.05)' }
])
}
},
{
// name: '储能功率',
type: 'line',
// data: [],
smooth: true,
symbol: 'none',
lineStyle: { color: '#ffcc00', width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(255, 204, 0, 0.4)' },
{ offset: 1, color: 'rgba(255, 204, 0, 0.05)' }
])
}
},
{
// name: '光伏功率',
type: 'line',
// data: [],
smooth: true,
symbol: 'none',
lineStyle: { color: '#ff3333', width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(255, 51, 51, 0.4)' },
{ offset: 1, color: 'rgba(255, 51, 51, 0.05)' }
])
}
}
]
}
this.powerChartInstance.setOption(option)
},
// 初始化底部中间电力需求曲线适配980px宽度+130px高度+bottom:26px两条曲线区分配色
initDemandChart() {
this.demandChartInstance = echarts.init(this.$refs.demandChart)
const option = {
backgroundColor: 'transparent', // 透明背景
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(0, 30, 60, 0.9)',
borderColor: '#00ccff', // 匹配图片主色
textStyle: { color: '#fff' },
axisPointer: { type: 'shadow' },
confine: true,
},
grid: {
left: '2%',
right: '2%',
top: '5%',
bottom: '8%',
containLabel: true
},
dataset: {
source: [] // Initial empty
},
xAxis: {
type: 'category',
boundaryGap: false,
// data: [], // Handled by dataset
axisLabel: {
color: '#00ccff', // 匹配图片主色
fontSize: 10,
margin: 10,
},
axisLine: {
show: true,
lineStyle: { color: '#006699', width: 1.5 }
},
splitLine: { show: false },
axisTick: { show: true }
},
yAxis: {
type: 'value',
min: 0,
max: 300,
interval: 50,
axisLabel: {
color: '#00ccff', // 匹配图片主色
fontSize: 12,
margin: 10,
fontWeight: 'bold'
},
axisLine: {
show: false,
// lineStyle: { color: '#006699', width: 1.5 }
},
splitLine: { lineStyle: { color: 'rgba(0, 100, 150, 0.2)' } },
axisTick: { show: false }
},
series: [
{
type: 'line',
// data: [],
smooth: true, // 平滑曲线
symbol: 'none', // 无数据点
// lineStyle: { color: '#00F2FF', width: 2.5 }, // 匹配图片主题色
// areaStyle: {
// // 匹配图片的线性渐变:#00F2FF 从100%不透明到0%不透明
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// { offset: 0, color: 'rgba(0, 242, 255, 1)' }, // 0%位置:#00F2FF 100%不透明
// { offset: 1, color: 'rgba(0, 242, 255, 0)' } // 100%位置:#00F2FF 0%不透明
// ])
// }
lineStyle: { color: '#0099ff', width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(0, 153, 255, 0.4)' },
{ offset: 1, color: 'rgba(0, 153, 255, 0.05)' }
])
}
},
{
// name: '负载功率',
type: 'line',
// data: [],
smooth: true,
symbol: 'none',
lineStyle: { color: '#00cc66', width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(0, 204, 102, 0.4)' },
{ offset: 1, color: 'rgba(0, 204, 102, 0.05)' }
])
}
},
]
}
this.demandChartInstance.setOption(option)
},
// 统一处理窗口缩放(适配两个图表)
resizeAllCharts() {
if (this.powerChartInstance) this.powerChartInstance.resize()
if (this.demandChartInstance) this.demandChartInstance.resize()
}
}
}
</script>
<style scoped>
/* 大屏容器固定1920x1080尺寸 */
.big-screen-container {
width: 1920px;
height: 1080px;
margin: 0;
padding: 0;
overflow: hidden;
position: relative;
}
/* 背景容器:相对路径 ./background.png */
.bg-wrapper {
width: 100%;
height: 100%;
background-image: url("./background.png");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
position: relative;
}
/* 通用图表容器样式 */
.chart-box {
background-color: transparent;
padding: 0;
border: none;
box-shadow: none;
border-radius: 0;
z-index: 10;
}
/* 右侧功率曲线图表定位+尺寸 */
.power-chart {
position: absolute;
top: 143px;
right: 40px;
width: 380px;
height: 270px;
}
/* 底部中间电力需求曲线图表核心修改width:980px, bottom:26px, height:130px */
.demand-chart {
position: absolute;
bottom: 26px; /* 修改为26px底部间距 */
left: 50%;
transform: translateX(-50%);
width: 980px; /* 修改为980px宽度 */
height: 130px; /* 保持130px高度不变 */
}
/* 图表内容区:填满容器 */
.chart-content {
width: 100%;
height: 100%;
}
</style>