41 changed files with 49244 additions and 17 deletions
@ -0,0 +1,170 @@ |
|||||||
|
<!-- ChillerLoadEvent.vue --> |
||||||
|
<template> |
||||||
|
<div class="app-container"> |
||||||
|
<el-card shadow="hover"> |
||||||
|
<div slot="header" class="clearfix"> |
||||||
|
<span>冷水机组加减载事件</span> |
||||||
|
<el-button style="float:right;" size="mini" @click="clearList">清空</el-button> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table |
||||||
|
:data="list" |
||||||
|
stripe |
||||||
|
height="750" |
||||||
|
:row-class-name="tableRowClassName" |
||||||
|
@row-click="openDetail" |
||||||
|
> |
||||||
|
<el-table-column prop="time" label="时间" /> |
||||||
|
<el-table-column prop="chillerName" label="机组" /> |
||||||
|
<el-table-column prop="action" label="动作" > |
||||||
|
<template slot-scope="{ row }"> |
||||||
|
<el-tag size="mini" :type="row.action === '加载' ? 'danger' : 'primary'"> |
||||||
|
{{ row.action }} |
||||||
|
</el-tag> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="cause" label="触发原因" show-overflow-tooltip /> |
||||||
|
<el-table-column prop="targetLoad" label="目标负荷%" /> |
||||||
|
<el-table-column prop="actualLoad" label="实际负荷%" /> |
||||||
|
</el-table> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<!-- 详情抽屉 --> |
||||||
|
<el-drawer title="原始数据" :visible.sync="drawer" direction="rtl" size="50%"> |
||||||
|
<div style="padding:0 20px;"> |
||||||
|
<json-viewer :value="currentRow.raw" :expand-depth="3" copyable boxed sort /> |
||||||
|
</div> |
||||||
|
</el-drawer> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'ChillerLoadEvent', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
list: [ |
||||||
|
{ |
||||||
|
time: '2026-03-03 08:10:01', |
||||||
|
chillerName: 'CH-01', |
||||||
|
action: '加载', |
||||||
|
cause: '供水温度高于设定值 1.2 ℃', |
||||||
|
targetLoad: 75, |
||||||
|
actualLoad: 73, |
||||||
|
raw: { supplyTemp: 8.2, setpoint: 7.0, deltaT: 1.2, compCurrent: 92.3, compFreq: 45.0 } |
||||||
|
}, |
||||||
|
{ |
||||||
|
time: '2026-03-03 08:15:23', |
||||||
|
chillerName: 'CH-02', |
||||||
|
action: '减载', |
||||||
|
cause: '供水温度低于设定值 0.9 ℃', |
||||||
|
targetLoad: 60, |
||||||
|
actualLoad: 62, |
||||||
|
raw: { supplyTemp: 6.1, setpoint: 7.0, deltaT: 0.9, compCurrent: 68.5, compFreq: 38.2 } |
||||||
|
}, |
||||||
|
{ |
||||||
|
time: '2026-03-03 08:22:45', |
||||||
|
chillerName: 'CH-03', |
||||||
|
action: '加载', |
||||||
|
cause: '系统负荷增加 15%', |
||||||
|
targetLoad: 80, |
||||||
|
actualLoad: 78, |
||||||
|
raw: { supplyTemp: 8.5, setpoint: 7.0, deltaT: 1.5, compCurrent: 95.1, compFreq: 48.6 } |
||||||
|
}, |
||||||
|
{ |
||||||
|
time: '2026-03-03 08:28:12', |
||||||
|
chillerName: 'CH-01', |
||||||
|
action: '减载', |
||||||
|
cause: '电动阀开度 < 25%', |
||||||
|
targetLoad: 55, |
||||||
|
actualLoad: 57, |
||||||
|
raw: { supplyTemp: 6.3, setpoint: 7.0, deltaT: 0.7, compCurrent: 65.4, compFreq: 35.0 } |
||||||
|
}, |
||||||
|
{ |
||||||
|
time: '2026-03-03 08:33:56', |
||||||
|
chillerName: 'CH-02', |
||||||
|
action: '加载', |
||||||
|
cause: '回水温度超上限 0.8 ℃', |
||||||
|
targetLoad: 78, |
||||||
|
actualLoad: 76, |
||||||
|
raw: { supplyTemp: 8.0, setpoint: 7.0, deltaT: 1.0, compCurrent: 90.0, compFreq: 46.2 } |
||||||
|
}, |
||||||
|
{ |
||||||
|
time: '2026-03-03 08:39:30', |
||||||
|
chillerName: 'CH-03', |
||||||
|
action: '减载', |
||||||
|
cause: '回水温度低于下限 1.1 ℃', |
||||||
|
targetLoad: 50, |
||||||
|
actualLoad: 52, |
||||||
|
raw: { supplyTemp: 5.9, setpoint: 7.0, deltaT: 1.1, compCurrent: 60.0, compFreq: 32.5 } |
||||||
|
}, |
||||||
|
{ |
||||||
|
time: '2026-03-03 08:45:11', |
||||||
|
chillerName: 'CH-01', |
||||||
|
action: '加载', |
||||||
|
cause: '电动阀开度 > 95%', |
||||||
|
targetLoad: 85, |
||||||
|
actualLoad: 83, |
||||||
|
raw: { supplyTemp: 8.7, setpoint: 7.0, deltaT: 1.7, compCurrent: 98.2, compFreq: 49.8 } |
||||||
|
}, |
||||||
|
{ |
||||||
|
time: '2026-03-03 08:51:44', |
||||||
|
chillerName: 'CH-02', |
||||||
|
action: '减载', |
||||||
|
cause: '系统负荷下降 12%', |
||||||
|
targetLoad: 65, |
||||||
|
actualLoad: 67, |
||||||
|
raw: { supplyTemp: 6.5, setpoint: 7.0, deltaT: 0.5, compCurrent: 70.1, compFreq: 37.0 } |
||||||
|
}, |
||||||
|
{ |
||||||
|
time: '2026-03-03 08:57:25', |
||||||
|
chillerName: 'CH-03', |
||||||
|
action: '加载', |
||||||
|
cause: '供水温度高于设定值 1.0 ℃', |
||||||
|
targetLoad: 72, |
||||||
|
actualLoad: 70, |
||||||
|
raw: { supplyTemp: 8.0, setpoint: 7.0, deltaT: 1.0, compCurrent: 88.5, compFreq: 44.3 } |
||||||
|
}, |
||||||
|
{ |
||||||
|
time: '2026-03-03 09:03:05', |
||||||
|
chillerName: 'CH-01', |
||||||
|
action: '减载', |
||||||
|
cause: '供水温度低于设定值 1.2 ℃', |
||||||
|
targetLoad: 48, |
||||||
|
actualLoad: 50, |
||||||
|
raw: { supplyTemp: 5.8, setpoint: 7.0, deltaT: 1.2, compCurrent: 58.7, compFreq: 30.2 } |
||||||
|
} |
||||||
|
], |
||||||
|
drawer: false, |
||||||
|
currentRow: {} |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
clearList() { |
||||||
|
this.$confirm('确定清空所有记录?', '提示', { type: 'warning' }).then(() => { |
||||||
|
this.list = [] |
||||||
|
}) |
||||||
|
}, |
||||||
|
tableRowClassName({ row }) { |
||||||
|
return row.action === '加载' ? 'load-row' : 'unload-row' |
||||||
|
}, |
||||||
|
openDetail(row) { |
||||||
|
this.currentRow = row |
||||||
|
this.drawer = true |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
.app-container { |
||||||
|
padding: 20px; |
||||||
|
} |
||||||
|
.load-row { |
||||||
|
background-color: #fff5f5 !important; |
||||||
|
} |
||||||
|
.unload-row { |
||||||
|
background-color: #f0f9ff !important; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,538 @@ |
|||||||
|
<template> |
||||||
|
<div class="main-body"> |
||||||
|
<div class="irregular-border"> |
||||||
|
<div class="export main-content"> |
||||||
|
<div class="condition"> |
||||||
|
<div class="condition-left"> |
||||||
|
<div class="condition-btn"> |
||||||
|
<div |
||||||
|
class="legend-li" |
||||||
|
v-for="(item, index) in timeData" |
||||||
|
:key="index" |
||||||
|
@click="handleEnter(index)" |
||||||
|
:class="{ timeStyle: timeIndex == index }" |
||||||
|
> |
||||||
|
{{ item.title }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div v-if="this.timeIndex == '0'"> |
||||||
|
<el-date-picker |
||||||
|
v-model="dayData" |
||||||
|
type="date" |
||||||
|
value-format="yyyy-MM-dd" |
||||||
|
placeholder="选择日期" |
||||||
|
></el-date-picker> |
||||||
|
</div> |
||||||
|
<div v-if="this.timeIndex == '1'"> |
||||||
|
<el-date-picker |
||||||
|
v-model="monthData" |
||||||
|
type="month" |
||||||
|
value-format="yyyy-MM" |
||||||
|
placeholder="选择月" |
||||||
|
></el-date-picker> |
||||||
|
</div> |
||||||
|
<el-button |
||||||
|
type="success" |
||||||
|
style="margin-left: 0.24rem" |
||||||
|
@click="findData" |
||||||
|
>查询</el-button |
||||||
|
> |
||||||
|
</div> |
||||||
|
<div class="condition-right"> |
||||||
|
<el-button type="warning" @click="exportData">导出</el-button> |
||||||
|
<el-button type="primary" @click="leadingPrint">打印</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="table-content"> |
||||||
|
<div class="table-title">{{ this.curDate }}{{ this.tableTitle }}</div> |
||||||
|
<el-table |
||||||
|
:data="tableData" |
||||||
|
border |
||||||
|
v-loading="listLoading" |
||||||
|
:cell-style="cellStyle" |
||||||
|
> |
||||||
|
<el-table-column label="项目" prop="name"></el-table-column> |
||||||
|
<el-table-column |
||||||
|
:label="this.tableTitle === '日报表' ? '当日数据' : '当月数据'" |
||||||
|
prop="value" |
||||||
|
></el-table-column> |
||||||
|
<el-table-column |
||||||
|
:label="this.tableTitle === '日报表' ? '上日数据' : '上月数据'" |
||||||
|
prop="lastValue" |
||||||
|
></el-table-column> |
||||||
|
<el-table-column label="同期数据" prop="yoyValue"></el-table-column> |
||||||
|
<el-table-column label="环比" prop="mom"></el-table-column> |
||||||
|
<el-table-column label="同比" prop="yoy"></el-table-column> |
||||||
|
</el-table> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-dialog |
||||||
|
:visible.sync="dialogPrintVisible" |
||||||
|
title="打印预览" |
||||||
|
width="900px" |
||||||
|
> |
||||||
|
<div id="report" ref="report" class="report"> |
||||||
|
<!-- <div class="print-title">铭汉云热水充值明细</div> --> |
||||||
|
<table |
||||||
|
border="1" |
||||||
|
style=" |
||||||
|
table-layout: fixed; |
||||||
|
width: 100%; |
||||||
|
border: 1px solid #e2e6f0; |
||||||
|
margin-bottom: 35px; |
||||||
|
" |
||||||
|
> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th align="center">项目</th> |
||||||
|
<th align="center" v-if="this.tableTitle == '日报表'"> |
||||||
|
当日数据 |
||||||
|
</th> |
||||||
|
<th align="center" v-else>当月数据</th> |
||||||
|
<th align="center" v-if="this.tableTitle == '日报表'"> |
||||||
|
上日数据 |
||||||
|
</th> |
||||||
|
<th align="center" v-else>上月数据</th> |
||||||
|
<th align="center">同期数据</th> |
||||||
|
<th align="center">环比</th> |
||||||
|
<th align="center">同比</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tr v-for="(item, index) in tableData" :key="index"> |
||||||
|
<td style="word-break: break-word" align="center"> |
||||||
|
{{ item.name }} |
||||||
|
</td> |
||||||
|
<td align="center">{{ item.value }}</td> |
||||||
|
<td align="center">{{ item.lastValue }}</td> |
||||||
|
<td align="center">{{ item.yoyValue }}</td> |
||||||
|
<td style="word-break: break-word" align="center"> |
||||||
|
{{ item.mom }} |
||||||
|
</td> |
||||||
|
<td style="word-break: break-word" align="center"> |
||||||
|
{{ item.yoy }} |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</table> |
||||||
|
<div |
||||||
|
class="detail" |
||||||
|
style=" |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
font-size: 14px; |
||||||
|
justify-content: space-between; |
||||||
|
flex-wrap: nowrap; |
||||||
|
width: 40%; |
||||||
|
color: #ffffff; |
||||||
|
" |
||||||
|
> |
||||||
|
<div>操作员: {{ this.userName }}</div> |
||||||
|
<div class="print-date">日期: {{ this.operationDate }}</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-row type="flex" justify="end" style="margin-top: 0.2rem"> |
||||||
|
<el-col :span="2"> |
||||||
|
<el-button type="info" @click="dialogPrintVisible = false" |
||||||
|
>取消</el-button |
||||||
|
> |
||||||
|
</el-col> |
||||||
|
<el-col :span="2" style="margin-left: 60px"> |
||||||
|
<el-button type="success" @click="surePrint">确认</el-button> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { getDay, getMonth, getYear } from "@/utils/datetime"; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
listLoading: false, |
||||||
|
timeData: [{ title: "日报表" }, { title: "月报表" }, { title: "年报表" }], |
||||||
|
timeIndex: 0, //日报表 |
||||||
|
tableTitle: "日报表", |
||||||
|
dayData: "", |
||||||
|
monthData: "", |
||||||
|
type: "", //传给后端的查询类型 |
||||||
|
curDate: "", //传给后端的当前时间 |
||||||
|
tableData: [], |
||||||
|
dialogPrintVisible: false, |
||||||
|
userName: "", //操作员 |
||||||
|
operationDate: getDay(0), //操作日期 |
||||||
|
}; |
||||||
|
}, |
||||||
|
created() { |
||||||
|
this.getInitializeDate(); //获取当月默认日期(当月1号到当天) |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.userName = sessionStorage.getItem("userName"); |
||||||
|
this.getTableData(); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
cellStyle({ row, column, rowIndex, columnIndex }) { |
||||||
|
if ( |
||||||
|
(parseFloat(row.mom) < 0 && columnIndex === 4) || |
||||||
|
(parseFloat(row.yoy) < 0 && columnIndex === 5) |
||||||
|
) { |
||||||
|
return { color: "#dc6565" }; |
||||||
|
} else if ( |
||||||
|
(parseFloat(row.mom) > 0 && columnIndex === 4) || |
||||||
|
(parseFloat(row.yoy) > 0 && columnIndex === 5) |
||||||
|
) { |
||||||
|
return { color: "#11dbb1" }; |
||||||
|
} else { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
}, |
||||||
|
// 默认时间时间 |
||||||
|
getInitializeDate() { |
||||||
|
this.dayData = getDay(0); |
||||||
|
this.monthData = getMonth(0); |
||||||
|
}, |
||||||
|
handleEnter(index) { |
||||||
|
this.timeIndex = index; |
||||||
|
}, |
||||||
|
getTableData() { |
||||||
|
if (this.timeIndex == "0") { |
||||||
|
(this.type = "day"), (this.curDate = this.dayData); |
||||||
|
} else { |
||||||
|
(this.type = "month"), (this.curDate = this.monthData); |
||||||
|
} |
||||||
|
let data = { |
||||||
|
type: this.type, |
||||||
|
curDate: this.curDate, |
||||||
|
}; |
||||||
|
this.listLoading = true; |
||||||
|
console.log("用户管理-查询", data); |
||||||
|
this.tableData = [ |
||||||
|
{ |
||||||
|
name: "气温(℃)", |
||||||
|
value: "0.00~0.00", |
||||||
|
lastValue: "0.00~0.00", |
||||||
|
yoyValue: "0.00~0.00", |
||||||
|
mom: "", |
||||||
|
yoy: "", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "开机时间", |
||||||
|
value: "2026-03-04 00:01:29", |
||||||
|
lastValue: "2026-03-03 00:00:30", |
||||||
|
yoyValue: "", |
||||||
|
mom: "开机延迟0.98分钟", |
||||||
|
yoy: "同期无数据", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "关机时间", |
||||||
|
value: "2026-03-04 08:41:30", |
||||||
|
lastValue: "2026-03-03 23:57:36", |
||||||
|
yoyValue: "", |
||||||
|
mom: "关机提前916.10分钟", |
||||||
|
yoy: "同期无数据", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "运行时长", |
||||||
|
value: "0天8小时40分", |
||||||
|
lastValue: "0天23小时57分", |
||||||
|
yoyValue: "", |
||||||
|
mom: "运行减少917.08分钟", |
||||||
|
yoy: "同期无数据", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "产冷量(kwr)", |
||||||
|
value: "230", |
||||||
|
lastValue: "505", |
||||||
|
yoyValue: "", |
||||||
|
mom: "-54.00%", |
||||||
|
yoy: "同期无数据", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "耗电量(kwh)", |
||||||
|
value: "498", |
||||||
|
lastValue: "1096", |
||||||
|
yoyValue: "332", |
||||||
|
mom: "-55.00%", |
||||||
|
yoy: "50.00%", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "主机耗电量(kwh)", |
||||||
|
value: "170", |
||||||
|
lastValue: "321", |
||||||
|
yoyValue: "192", |
||||||
|
mom: "-47.00%", |
||||||
|
yoy: "-11.00%", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "主机COP", |
||||||
|
value: "1.35", |
||||||
|
lastValue: "1.57", |
||||||
|
yoyValue: "0", |
||||||
|
mom: "-14.00%", |
||||||
|
yoy: "0%", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "主机耗电占比(%)", |
||||||
|
value: "34.14", |
||||||
|
lastValue: "29.29", |
||||||
|
yoyValue: "0", |
||||||
|
mom: "17.00%", |
||||||
|
yoy: "0%", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "冷站EER", |
||||||
|
value: "0.46", |
||||||
|
lastValue: "0.46", |
||||||
|
yoyValue: "0", |
||||||
|
mom: "0%", |
||||||
|
yoy: "0%", |
||||||
|
}, |
||||||
|
]; |
||||||
|
// this.$api.dataReport.dataReport(data).then((res) => { |
||||||
|
// console.log("查询返回", res); |
||||||
|
// if (res.code == 200) { |
||||||
|
// this.tableData = res.data.map(obj => { |
||||||
|
// if (obj.name == 'startupTime') { |
||||||
|
// obj.name = '开机时间' |
||||||
|
// } else if (obj.name == 'shutdownTime') { |
||||||
|
// obj.name = '关机时间' |
||||||
|
// } else if (obj.name == 'runTime') { |
||||||
|
// obj.name = '运行时长' |
||||||
|
// } else if (obj.name == 'totalCoolCap') { |
||||||
|
// obj.name = '产冷量(kwr)' |
||||||
|
// } else if (obj.name == 'totalEleUsed') { |
||||||
|
// obj.name = '耗电量(kwh)' |
||||||
|
// } else if (obj.name == 'cop') { |
||||||
|
// obj.name = '冷站EER' |
||||||
|
// } else if (obj.name == 'temp') { |
||||||
|
// obj.name = '气温(℃)' |
||||||
|
// } else if (obj.name == 'hostEleUsed') { |
||||||
|
// obj.name = '主机耗电量(kwh)' |
||||||
|
// } else if (obj.name == 'hostCop') { |
||||||
|
// obj.name = '主机COP' |
||||||
|
// } else if (obj.name == 'hostEleLoad') { |
||||||
|
// obj.name = '主机耗电占比(%)' |
||||||
|
// } |
||||||
|
// return obj |
||||||
|
// }); |
||||||
|
|
||||||
|
// } |
||||||
|
// }); |
||||||
|
// Just to simulate the time of the request |
||||||
|
setTimeout(() => { |
||||||
|
this.listLoading = false; |
||||||
|
}, 1.0 * 1000); |
||||||
|
}, |
||||||
|
// 查询 |
||||||
|
findData() { |
||||||
|
console.log( |
||||||
|
"this.curDate", |
||||||
|
this.tableTitle, |
||||||
|
this.curDate, |
||||||
|
this.dayData, |
||||||
|
this.monthData |
||||||
|
); |
||||||
|
if (this.timeIndex == 0) { |
||||||
|
this.tableTitle = "日报表"; |
||||||
|
} else { |
||||||
|
this.tableTitle = "月报表"; |
||||||
|
} |
||||||
|
console.log("标题", this.tableTitle); |
||||||
|
if (this.dayData === null || this.monthData === null) { |
||||||
|
this.getInitializeDate(); |
||||||
|
this.getTableData(); |
||||||
|
} else { |
||||||
|
this.getTableData(); |
||||||
|
} |
||||||
|
}, |
||||||
|
// 导出 |
||||||
|
exportData() { |
||||||
|
import("@/assets/excel/Export2Excel").then((excel) => { |
||||||
|
let outTitle = ""; |
||||||
|
let ourDate = ""; |
||||||
|
if (this.dayData === null || this.monthData === null) { |
||||||
|
this.getInitializeDate(); |
||||||
|
} |
||||||
|
if (this.timeIndex == "0") { |
||||||
|
(this.type = "day"), (outTitle = "日报表"); |
||||||
|
ourDate = this.dayData; |
||||||
|
} else { |
||||||
|
(this.type = "month"), (outTitle = "月报表"); |
||||||
|
ourDate = this.monthData; |
||||||
|
} |
||||||
|
let data = { |
||||||
|
type: this.type, |
||||||
|
curDate: ourDate, |
||||||
|
}; |
||||||
|
console.log("导出标题日期", outTitle, ourDate); |
||||||
|
console.log("报表导出-导出", data); |
||||||
|
this.$api.dataReport |
||||||
|
.dataReport(data) |
||||||
|
.then((res) => { |
||||||
|
if (res.code == 200) { |
||||||
|
const filterVal = [ |
||||||
|
"name", |
||||||
|
"value", |
||||||
|
"lastValue", |
||||||
|
"yoyValue", |
||||||
|
"mom", |
||||||
|
"yoy", |
||||||
|
]; // 导出的excel表头字段名,需要导出表格字段名 |
||||||
|
|
||||||
|
let tHeader; |
||||||
|
if (this.timeIndex == "0") { |
||||||
|
tHeader = [ |
||||||
|
"项目", |
||||||
|
"当日数据", |
||||||
|
"上日数据", |
||||||
|
"同期数据", |
||||||
|
"环比", |
||||||
|
"同比", |
||||||
|
]; // 导出的excel表头名信息 |
||||||
|
} else { |
||||||
|
tHeader = [ |
||||||
|
"项目", |
||||||
|
"当月数据", |
||||||
|
"上月数据", |
||||||
|
"同期数据", |
||||||
|
"环比", |
||||||
|
"同比", |
||||||
|
]; // 导出的excel表头名信息 |
||||||
|
} |
||||||
|
const outTableData = res.data.map((obj) => { |
||||||
|
if (obj.name == "startupTime") { |
||||||
|
obj.name = "开机时间"; |
||||||
|
} else if (obj.name == "shutdownTime") { |
||||||
|
obj.name = "关机时间"; |
||||||
|
} else if (obj.name == "runTime") { |
||||||
|
obj.name = "运行时长"; |
||||||
|
} else if (obj.name == "totalCoolCap") { |
||||||
|
obj.name = "产冷量(kwr)"; |
||||||
|
} else if (obj.name == "totalEleUsed") { |
||||||
|
obj.name = "耗电量(kwh)"; |
||||||
|
} else if (obj.name == "cop") { |
||||||
|
obj.name = "冷站EER"; |
||||||
|
} else if (obj.name == "temp") { |
||||||
|
obj.name = "气温(℃)"; |
||||||
|
} else if (obj.name == "hostEleUsed") { |
||||||
|
obj.name = "主机耗电量(kwh)"; |
||||||
|
} else if (obj.name == "hostCop") { |
||||||
|
obj.name = "主机COP"; |
||||||
|
} else if (obj.name == "hostEleLoad") { |
||||||
|
obj.name = "主机耗电占比(%)"; |
||||||
|
} |
||||||
|
return obj; |
||||||
|
}); |
||||||
|
const data = this.formatJson(filterVal, outTableData); |
||||||
|
const autoWidth = true; |
||||||
|
excel.export_json_to_excel({ |
||||||
|
header: tHeader, //表头 |
||||||
|
data, //数据 |
||||||
|
filename: `${outTitle + "_" + ourDate}`, //名称, //名称 |
||||||
|
autoWidth: true, //宽度自适应 |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.$message.error("导出失败!"); |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch((err) => { |
||||||
|
this.$message.error("导出失败!"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}, |
||||||
|
//格式转换,不需要改动 |
||||||
|
formatJson(filterVal, jsonData) { |
||||||
|
return jsonData.map((v) => |
||||||
|
filterVal.map((j) => { |
||||||
|
if (j === "installDate") { |
||||||
|
return format(v[j]); |
||||||
|
} else { |
||||||
|
return v[j]; |
||||||
|
} |
||||||
|
}) |
||||||
|
); |
||||||
|
}, |
||||||
|
// 打印 |
||||||
|
leadingPrint() { |
||||||
|
this.dialogPrintVisible = true; |
||||||
|
}, |
||||||
|
// 打印 |
||||||
|
surePrint() { |
||||||
|
const printHTML = document.querySelector("#report").innerHTML; |
||||||
|
// 将打印的区域赋值,进行打印 |
||||||
|
window.document.body.innerHTML = printHTML; |
||||||
|
window.print(); // 调用window打印方法 |
||||||
|
window.location.reload(); // 打印完成后重新加载页面 |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.export { |
||||||
|
align-items: center; |
||||||
|
min-height: 7.4rem; |
||||||
|
|
||||||
|
.condition { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
width: 100%; |
||||||
|
|
||||||
|
.condition-left { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: center; |
||||||
|
|
||||||
|
.condition-btn { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
overflow: hidden; |
||||||
|
cursor: pointer; |
||||||
|
border-radius: 4px; |
||||||
|
margin-right: 0.24rem; |
||||||
|
background-color: #1c285c; |
||||||
|
|
||||||
|
.legend-li { |
||||||
|
text-align: center; |
||||||
|
padding: 10px 26px; |
||||||
|
white-space: nowrap; |
||||||
|
font-size: 16px; |
||||||
|
color: #7394a8; |
||||||
|
} |
||||||
|
|
||||||
|
.timeStyle { |
||||||
|
color: #ffffff !important; |
||||||
|
background-color: #0c3ec7; |
||||||
|
border: 1px solid #0c3ec7; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.condition-right { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.table-content { |
||||||
|
width: 100%; |
||||||
|
margin-top: 20px; |
||||||
|
padding: 0 0.2rem; |
||||||
|
font-size: 0.22rem; |
||||||
|
line-height: 0.13rem; |
||||||
|
color: #ffffff; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
|
||||||
|
.table-title { |
||||||
|
margin-bottom: 0.2rem; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,943 @@ |
|||||||
|
<template> |
||||||
|
<div class="carbon-emissions-analysis"> |
||||||
|
<!-- 时间选择器 --> |
||||||
|
<div class="time-selector"> |
||||||
|
<div class="selector-label">时间维度</div> |
||||||
|
<div class="time-periods"> |
||||||
|
<div |
||||||
|
v-for="(period, index) in timePeriods" |
||||||
|
:key="index" |
||||||
|
:class="['period-item', { active: activePeriod === index }]" |
||||||
|
@click="handlePeriodChange(index)" |
||||||
|
> |
||||||
|
{{ period }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="date-range" v-if="activePeriod === 3"> |
||||||
|
<el-date-picker |
||||||
|
v-model="dateRange" |
||||||
|
type="daterange" |
||||||
|
range-separator="至" |
||||||
|
start-placeholder="开始日期" |
||||||
|
end-placeholder="结束日期" |
||||||
|
value-format="yyyy-MM-dd" |
||||||
|
@change="handleDateChange" |
||||||
|
class="custom-picker" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 碳排放核心指标 --> |
||||||
|
<div class="carbon-indicators"> |
||||||
|
<div class="indicator-card primary"> |
||||||
|
<div class="card-header"> |
||||||
|
<div class="card-icon"> |
||||||
|
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> |
||||||
|
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="currentColor"/> |
||||||
|
<path d="M464 336a48 48 0 1096 0 48 48 0 10-96 0zm72 112h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V456c0-4.4-3.6-8-8-8z" fill="currentColor"/> |
||||||
|
</svg> |
||||||
|
</div> |
||||||
|
<div class="card-title">累计碳排放</div> |
||||||
|
</div> |
||||||
|
<div class="card-value">{{ carbonIndicators.totalCarbon }} <span class="unit">tCO₂e</span></div> |
||||||
|
<div class="card-trend" :class="carbonIndicators.carbonTrend >= 0 ? 'up' : 'down'"> |
||||||
|
<span v-if="carbonIndicators.carbonTrend >= 0">↑</span> |
||||||
|
<span v-else>↓</span> |
||||||
|
{{ Math.abs(carbonIndicators.carbonTrend) }}% |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="indicator-card success"> |
||||||
|
<div class="card-header"> |
||||||
|
<div class="card-icon"> |
||||||
|
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> |
||||||
|
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="currentColor"/> |
||||||
|
<path d="M672 464H352c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h320c8.8 0 16-7.2 16-16v-64c0-8.8-7.2-16-16-16z" fill="currentColor"/> |
||||||
|
<path d="M512 592c-4.4 0-8 3.6-8 8v256c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V600c0-4.4-3.6-8-8-8h-48z" fill="currentColor"/> |
||||||
|
</svg> |
||||||
|
</div> |
||||||
|
<div class="card-title">累计碳减排</div> |
||||||
|
</div> |
||||||
|
<div class="card-value">{{ carbonIndicators.totalReduction }} <span class="unit">tCO₂e</span></div> |
||||||
|
<div class="card-trend" :class="carbonIndicators.reductionTrend >= 0 ? 'up' : 'down'"> |
||||||
|
<span v-if="carbonIndicators.reductionTrend >= 0">↑</span> |
||||||
|
<span v-else>↓</span> |
||||||
|
{{ Math.abs(carbonIndicators.reductionTrend) }}% |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="indicator-card warning"> |
||||||
|
<div class="card-header"> |
||||||
|
<div class="card-icon"> |
||||||
|
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> |
||||||
|
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="currentColor"/> |
||||||
|
<path d="M512 352c-8.8 0-16 7.2-16 16v224c0 8.8 7.2 16 16 16h48c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16h-48z" fill="currentColor"/> |
||||||
|
<path d="M536 672h-72c-4.4 0-8 3.6-8 8v72c0 4.4 3.6 8 8 8h72c4.4 0 8-3.6 8-8v-72c0-4.4-3.6-8-8-8z" fill="currentColor"/> |
||||||
|
</svg> |
||||||
|
</div> |
||||||
|
<div class="card-title">碳强度</div> |
||||||
|
</div> |
||||||
|
<div class="card-value">{{ carbonIndicators.carbonIntensity }} <span class="unit">kgCO₂/kWh</span></div> |
||||||
|
<div class="card-trend" :class="carbonIndicators.intensityTrend >= 0 ? 'up' : 'down'"> |
||||||
|
<span v-if="carbonIndicators.intensityTrend >= 0">↑</span> |
||||||
|
<span v-else>↓</span> |
||||||
|
{{ Math.abs(carbonIndicators.intensityTrend) }}% |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="indicator-card info"> |
||||||
|
<div class="card-header"> |
||||||
|
<div class="card-icon"> |
||||||
|
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> |
||||||
|
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="currentColor"/> |
||||||
|
<path d="M688 464H336c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h352c8.8 0 16-7.2 16-16v-64c0-8.8-7.2-16-16-16z" fill="currentColor"/> |
||||||
|
<path d="M688 592H336c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h352c8.8 0 16-7.2 16-16v-64c0-8.8-7.2-16-16-16z" fill="currentColor"/> |
||||||
|
</svg> |
||||||
|
</div> |
||||||
|
<div class="card-title">节能率</div> |
||||||
|
</div> |
||||||
|
<div class="card-value">{{ carbonIndicators.energySavingRate }} <span class="unit">%</span></div> |
||||||
|
<div class="card-trend" :class="carbonIndicators.savingTrend >= 0 ? 'up' : 'down'"> |
||||||
|
<span v-if="carbonIndicators.savingTrend >= 0">↑</span> |
||||||
|
<span v-else>↓</span> |
||||||
|
{{ Math.abs(carbonIndicators.savingTrend) }}% |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 碳排放趋势图 --> |
||||||
|
<div class="chart-section"> |
||||||
|
<div class="chart-header"> |
||||||
|
<div class="chart-title">碳排放趋势</div> |
||||||
|
<div class="chart-legend"> |
||||||
|
<div class="legend-item"> |
||||||
|
<span class="legend-dot" style="background: #EE6666;"></span> |
||||||
|
<span>碳排放量</span> |
||||||
|
</div> |
||||||
|
<div class="legend-item"> |
||||||
|
<span class="legend-dot" style="background: #91CC75;"></span> |
||||||
|
<span>碳减排量</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="chart" ref="carbonTrendChartRef"></div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 碳排放来源分布 --> |
||||||
|
<div class="chart-section half-width"> |
||||||
|
<div class="chart-header"> |
||||||
|
<div class="chart-title">碳排放来源分布</div> |
||||||
|
</div> |
||||||
|
<div class="chart" ref="carbonSourceChartRef"></div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 能耗与碳排放对比 --> |
||||||
|
<div class="chart-section half-width"> |
||||||
|
<div class="chart-header"> |
||||||
|
<div class="chart-title">能耗与碳排放对比</div> |
||||||
|
</div> |
||||||
|
<div class="chart" ref="energyCarbonChartRef"></div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 碳减排量详情表格 --> |
||||||
|
<div class="table-section"> |
||||||
|
<div class="section-header"> |
||||||
|
<div class="section-title">碳减排量详情</div> |
||||||
|
<el-button type="primary" size="small" @click="exportData">导出数据</el-button> |
||||||
|
</div> |
||||||
|
<div class="table-container"> |
||||||
|
<table class="data-table"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>日期</th> |
||||||
|
<th>用电量(kWh)</th> |
||||||
|
<th>碳排放量(tCO₂e)</th> |
||||||
|
<th>基准碳排放(tCO₂e)</th> |
||||||
|
<th>碳减排量(tCO₂e)</th> |
||||||
|
<th>碳减排率(%)</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr v-for="(item, index) in carbonDetailList" :key="index"> |
||||||
|
<td>{{ item.date }}</td> |
||||||
|
<td>{{ item.energy }}</td> |
||||||
|
<td>{{ item.carbon }}</td> |
||||||
|
<td>{{ item.baselineCarbon }}</td> |
||||||
|
<td>{{ item.reduction }}</td> |
||||||
|
<td>{{ item.reductionRate }}%</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 碳减排贡献分析 --> |
||||||
|
<div class="contribution-section"> |
||||||
|
<div class="section-header"> |
||||||
|
<div class="section-title">碳减排贡献分析</div> |
||||||
|
</div> |
||||||
|
<div class="contribution-grid"> |
||||||
|
<div class="contribution-item" v-for="item in contributionList" :key="item.name"> |
||||||
|
<div class="contribution-icon" :style="{ background: item.bg }"> |
||||||
|
<span>{{ item.icon }}</span> |
||||||
|
</div> |
||||||
|
<div class="contribution-info"> |
||||||
|
<div class="contribution-name">{{ item.name }}</div> |
||||||
|
<div class="contribution-value">{{ item.value }} <span class="unit">tCO₂e</span></div> |
||||||
|
<div class="contribution-percent">{{ item.percent }}%</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import * as echarts from "echarts"; |
||||||
|
|
||||||
|
export default { |
||||||
|
name: "CarbonEmissionsAnalysis", |
||||||
|
data() { |
||||||
|
return { |
||||||
|
// 时间段选项 |
||||||
|
timePeriods: ["近七日", "近一月", "近三月", "自定义"], |
||||||
|
activePeriod: 0, |
||||||
|
// 日期范围 |
||||||
|
dateRange: [], |
||||||
|
// 碳排放核心指标 |
||||||
|
carbonIndicators: { |
||||||
|
totalCarbon: 1256.8, |
||||||
|
carbonTrend: -5.2, |
||||||
|
totalReduction: 89.6, |
||||||
|
reductionTrend: 12.5, |
||||||
|
carbonIntensity: 0.52, |
||||||
|
intensityTrend: -3.8, |
||||||
|
energySavingRate: 28.5, |
||||||
|
savingTrend: 2.3 |
||||||
|
}, |
||||||
|
// 碳排放详情列表 |
||||||
|
carbonDetailList: [ |
||||||
|
{ date: "2024-03-01", energy: 178000, carbon: 92.56, baselineCarbon: 129.5, reduction: 36.94, reductionRate: 28.5 }, |
||||||
|
{ date: "2024-03-02", energy: 189000, carbon: 98.28, baselineCarbon: 137.5, reduction: 39.22, reductionRate: 28.5 }, |
||||||
|
{ date: "2024-03-03", energy: 197000, carbon: 102.44, baselineCarbon: 143.3, reduction: 40.86, reductionRate: 28.5 }, |
||||||
|
{ date: "2024-03-04", energy: 181000, carbon: 94.12, baselineCarbon: 131.6, reduction: 37.48, reductionRate: 28.5 }, |
||||||
|
{ date: "2024-03-05", energy: 204000, carbon: 106.08, baselineCarbon: 148.4, reduction: 42.32, reductionRate: 28.5 } |
||||||
|
], |
||||||
|
// 碳减排贡献分析 |
||||||
|
contributionList: [ |
||||||
|
{ name: "能效提升", icon: "EER", value: 45.6, percent: 50.9, bg: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)" }, |
||||||
|
{ name: "设备优化", icon: "设备", value: 25.8, percent: 28.8, bg: "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)" }, |
||||||
|
{ name: "运行策略", icon: "策略", value: 12.3, percent: 13.7, bg: "linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)" }, |
||||||
|
{ name: "其他措施", icon: "其他", value: 5.9, percent: 6.6, bg: "linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)" } |
||||||
|
], |
||||||
|
// 图表实例 |
||||||
|
carbonTrendChart: null, |
||||||
|
carbonSourceChart: null, |
||||||
|
energyCarbonChart: null |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.initCarbonTrendChart(); |
||||||
|
this.initCarbonSourceChart(); |
||||||
|
this.initEnergyCarbonChart(); |
||||||
|
window.addEventListener("resize", this.handleResize); |
||||||
|
}, |
||||||
|
beforeDestroy() { |
||||||
|
window.removeEventListener("resize", this.handleResize); |
||||||
|
if (this.carbonTrendChart) this.carbonTrendChart.dispose(); |
||||||
|
if (this.carbonSourceChart) this.carbonSourceChart.dispose(); |
||||||
|
if (this.energyCarbonChart) this.energyCarbonChart.dispose(); |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
activePeriod() { |
||||||
|
this.updateAllCharts(); |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 时间段切换 |
||||||
|
handlePeriodChange(index) { |
||||||
|
this.activePeriod = index; |
||||||
|
}, |
||||||
|
// 日期范围变化 |
||||||
|
handleDateChange(value) { |
||||||
|
console.log("自定义日期范围:", value); |
||||||
|
this.updateAllCharts(); |
||||||
|
}, |
||||||
|
// 导出数据 |
||||||
|
exportData() { |
||||||
|
this.$message.success("数据导出成功"); |
||||||
|
}, |
||||||
|
// 初始化碳排放趋势图 |
||||||
|
initCarbonTrendChart() { |
||||||
|
this.carbonTrendChart = echarts.init(this.$refs.carbonTrendChartRef); |
||||||
|
this.updateCarbonTrendChart(); |
||||||
|
}, |
||||||
|
// 更新碳排放趋势图 |
||||||
|
updateCarbonTrendChart() { |
||||||
|
const dataMap = { |
||||||
|
0: { // 近七日 |
||||||
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
||||||
|
carbon: [92.56, 98.28, 102.44, 94.12, 106.08, 112.56, 104.76], |
||||||
|
reduction: [36.94, 39.22, 40.86, 37.48, 42.32, 44.96, 41.76] |
||||||
|
}, |
||||||
|
1: { // 近一月 |
||||||
|
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"], |
||||||
|
carbon: [856, 912, 888, 945, 1012, 956, 892], |
||||||
|
reduction: [341.6, 364.8, 355.2, 378, 404.8, 382.4, 356.8] |
||||||
|
}, |
||||||
|
2: { // 近三月 |
||||||
|
xData: ["1月", "2月", "3月"], |
||||||
|
carbon: [24120, 27360, 25680], |
||||||
|
reduction: [9648, 10944, 10272] |
||||||
|
}, |
||||||
|
3: { // 自定义 |
||||||
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
||||||
|
carbon: [92.56, 98.28, 102.44, 94.12, 106.08, 112.56, 104.76], |
||||||
|
reduction: [36.94, 39.22, 40.86, 37.48, 42.32, 44.96, 41.76] |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const currentData = dataMap[this.activePeriod]; |
||||||
|
|
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "axis", |
||||||
|
axisPointer: { |
||||||
|
type: "cross" |
||||||
|
} |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
data: ["碳排放量", "碳减排量"], |
||||||
|
textStyle: { |
||||||
|
color: "#ffffff" |
||||||
|
} |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: "3%", |
||||||
|
right: "4%", |
||||||
|
bottom: "3%", |
||||||
|
containLabel: true |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
boundaryGap: false, |
||||||
|
data: currentData.xData, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
type: "value", |
||||||
|
name: "tCO₂e", |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", |
||||||
|
type: "dashed" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "碳排放量", |
||||||
|
type: "bar", |
||||||
|
data: currentData.carbon, |
||||||
|
itemStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "#EE6666" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "#E53935" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "碳减排量", |
||||||
|
type: "line", |
||||||
|
smooth: true, |
||||||
|
data: currentData.reduction, |
||||||
|
itemStyle: { |
||||||
|
color: "#91CC75" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#91CC75", |
||||||
|
width: 3 |
||||||
|
}, |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(145, 204, 117, 0.5)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(145, 204, 117, 0)" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.carbonTrendChart.setOption(option); |
||||||
|
}, |
||||||
|
// 初始化碳排放来源分布图 |
||||||
|
initCarbonSourceChart() { |
||||||
|
this.carbonSourceChart = echarts.init(this.$refs.carbonSourceChartRef); |
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "item", |
||||||
|
formatter: "{b}: {c}% ({d}%)" |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
orient: "vertical", |
||||||
|
left: "left", |
||||||
|
textStyle: { |
||||||
|
color: "#ffffff" |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "碳排放来源", |
||||||
|
type: "pie", |
||||||
|
radius: ["30%", "70%"], |
||||||
|
center: ["60%", "50%"], |
||||||
|
data: [ |
||||||
|
{ value: 65, name: "主机", itemStyle: { color: "#5470C6" } }, |
||||||
|
{ value: 20, name: "冷冻泵", itemStyle: { color: "#91CC75" } }, |
||||||
|
{ value: 10, name: "冷却泵", itemStyle: { color: "#FAC858" } }, |
||||||
|
{ value: 3, name: "冷却塔风机", itemStyle: { color: "#EE6666" } }, |
||||||
|
{ value: 2, name: "其他", itemStyle: { color: "#73C0DE" } } |
||||||
|
], |
||||||
|
label: { |
||||||
|
formatter: "{b}\n{d}%" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.carbonSourceChart.setOption(option); |
||||||
|
}, |
||||||
|
// 初始化能耗与碳排放对比图 |
||||||
|
initEnergyCarbonChart() { |
||||||
|
this.energyCarbonChart = echarts.init(this.$refs.energyCarbonChartRef); |
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "axis", |
||||||
|
axisPointer: { |
||||||
|
type: "cross" |
||||||
|
} |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
data: ["用电量", "碳排放量"], |
||||||
|
textStyle: { |
||||||
|
color: "#ffffff" |
||||||
|
} |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: "3%", |
||||||
|
right: "4%", |
||||||
|
bottom: "3%", |
||||||
|
containLabel: true |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
}, |
||||||
|
yAxis: [ |
||||||
|
{ |
||||||
|
type: "value", |
||||||
|
name: "kWh", |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", |
||||||
|
type: "dashed" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "value", |
||||||
|
name: "tCO₂e", |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "用电量", |
||||||
|
type: "bar", |
||||||
|
data: [178000, 189000, 197000, 181000, 204000, 215000, 200000], |
||||||
|
itemStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "#15e1fd" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "#208fff" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "碳排放量", |
||||||
|
type: "line", |
||||||
|
smooth: true, |
||||||
|
yAxisIndex: 1, |
||||||
|
data: [92.56, 98.28, 102.44, 94.12, 106.08, 112.56, 104.76], |
||||||
|
itemStyle: { |
||||||
|
color: "#EE6666" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#EE6666", |
||||||
|
width: 3 |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.energyCarbonChart.setOption(option); |
||||||
|
}, |
||||||
|
// 更新所有图表 |
||||||
|
updateAllCharts() { |
||||||
|
this.updateCarbonTrendChart(); |
||||||
|
}, |
||||||
|
// 响应式调整 |
||||||
|
handleResize() { |
||||||
|
if (this.carbonTrendChart) this.carbonTrendChart.resize(); |
||||||
|
if (this.carbonSourceChart) this.carbonSourceChart.resize(); |
||||||
|
if (this.energyCarbonChart) this.energyCarbonChart.resize(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.carbon-emissions-analysis { |
||||||
|
padding: 0.16rem; |
||||||
|
} |
||||||
|
|
||||||
|
.time-selector { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 0.2rem; |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
border-radius: 0.08rem; |
||||||
|
margin-bottom: 0.16rem; |
||||||
|
flex-wrap: wrap; |
||||||
|
gap: 0.15rem; |
||||||
|
|
||||||
|
.selector-label { |
||||||
|
font-size: 0.15rem; |
||||||
|
color: #ffffff; |
||||||
|
margin-right: 0.15rem; |
||||||
|
} |
||||||
|
|
||||||
|
.time-periods { |
||||||
|
display: flex; |
||||||
|
gap: 0.08rem; |
||||||
|
|
||||||
|
.period-item { |
||||||
|
padding: 0.06rem 0.2rem; |
||||||
|
font-size: 0.13rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
cursor: pointer; |
||||||
|
border-radius: 0.04rem; |
||||||
|
transition: all 0.3s; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
&.active { |
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.date-range { |
||||||
|
margin-left: 0.15rem; |
||||||
|
|
||||||
|
::v-deep .custom-picker { |
||||||
|
.el-input__wrapper { |
||||||
|
background: rgba(255, 255, 255, 0.1); |
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2); |
||||||
|
|
||||||
|
.el-input__inner { |
||||||
|
color: #ffffff; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.carbon-indicators { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: repeat(auto-fit, minmax(2.5rem, 1fr)); |
||||||
|
gap: 0.15rem; |
||||||
|
margin-bottom: 0.16rem; |
||||||
|
|
||||||
|
.indicator-card { |
||||||
|
padding: 0.25rem; |
||||||
|
border-radius: 0.08rem; |
||||||
|
|
||||||
|
&.primary { |
||||||
|
background: linear-gradient(135deg, rgba(238, 102, 102, 0.2) 0%, rgba(229, 57, 53, 0.2) 100%); |
||||||
|
border: 1px solid rgba(238, 102, 102, 0.3); |
||||||
|
} |
||||||
|
|
||||||
|
&.success { |
||||||
|
background: linear-gradient(135deg, rgba(145, 204, 117, 0.2) 0%, rgba(102, 187, 106, 0.2) 100%); |
||||||
|
border: 1px solid rgba(145, 204, 117, 0.3); |
||||||
|
} |
||||||
|
|
||||||
|
&.warning { |
||||||
|
background: linear-gradient(135deg, rgba(250, 200, 88, 0.2) 0%, rgba(255, 179, 0, 0.2) 100%); |
||||||
|
border: 1px solid rgba(250, 200, 88, 0.3); |
||||||
|
} |
||||||
|
|
||||||
|
&.info { |
||||||
|
background: linear-gradient(135deg, rgba(84, 112, 198, 0.2) 0%, rgba(115, 192, 222, 0.2) 100%); |
||||||
|
border: 1px solid rgba(84, 112, 198, 0.3); |
||||||
|
} |
||||||
|
|
||||||
|
.card-header { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
|
||||||
|
.card-icon { |
||||||
|
width: 0.4rem; |
||||||
|
height: 0.4rem; |
||||||
|
border-radius: 50%; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
margin-right: 0.12rem; |
||||||
|
background: rgba(255, 255, 255, 0.1); |
||||||
|
|
||||||
|
svg { |
||||||
|
width: 0.2rem; |
||||||
|
height: 0.2rem; |
||||||
|
fill: #ffffff; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.card-title { |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.8; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.card-value { |
||||||
|
font-size: 0.32rem; |
||||||
|
color: #15e1fd; |
||||||
|
font-weight: bold; |
||||||
|
margin-bottom: 0.1rem; |
||||||
|
|
||||||
|
.unit { |
||||||
|
font-size: 0.16rem; |
||||||
|
opacity: 0.8; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.card-trend { |
||||||
|
font-size: 0.13rem; |
||||||
|
|
||||||
|
&.up { |
||||||
|
color: #EE6666; |
||||||
|
} |
||||||
|
|
||||||
|
&.down { |
||||||
|
color: #91CC75; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.chart-section { |
||||||
|
background: rgba(255, 255, 255, 0.03); |
||||||
|
border-radius: 0.08rem; |
||||||
|
padding: 0.2rem; |
||||||
|
margin-bottom: 0.16rem; |
||||||
|
|
||||||
|
&.half-width { |
||||||
|
display: inline-block; |
||||||
|
width: calc(50% - 0.08rem); |
||||||
|
vertical-align: top; |
||||||
|
|
||||||
|
&:nth-child(odd) { |
||||||
|
margin-right: 0.16rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.chart-header { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
|
||||||
|
.chart-title { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
padding-left: 0.12rem; |
||||||
|
border-left: 0.04rem solid #15e1fd; |
||||||
|
} |
||||||
|
|
||||||
|
.chart-legend { |
||||||
|
display: flex; |
||||||
|
gap: 0.2rem; |
||||||
|
|
||||||
|
.legend-item { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
font-size: 0.13rem; |
||||||
|
color: #ffffff; |
||||||
|
|
||||||
|
.legend-dot { |
||||||
|
width: 0.1rem; |
||||||
|
height: 0.1rem; |
||||||
|
border-radius: 50%; |
||||||
|
margin-right: 0.06rem; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.chart { |
||||||
|
width: 100%; |
||||||
|
height: 3rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.table-section { |
||||||
|
background: rgba(255, 255, 255, 0.03); |
||||||
|
border-radius: 0.08rem; |
||||||
|
padding: 0.2rem; |
||||||
|
margin-bottom: 0.16rem; |
||||||
|
|
||||||
|
.section-header { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
|
||||||
|
.section-title { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
padding-left: 0.12rem; |
||||||
|
border-left: 0.04rem solid #15e1fd; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.table-container { |
||||||
|
overflow-x: auto; |
||||||
|
|
||||||
|
.data-table { |
||||||
|
width: 100%; |
||||||
|
border-collapse: collapse; |
||||||
|
|
||||||
|
thead { |
||||||
|
tr { |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
|
||||||
|
th { |
||||||
|
padding: 0.12rem; |
||||||
|
text-align: left; |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
tbody { |
||||||
|
tr { |
||||||
|
&:hover { |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
} |
||||||
|
|
||||||
|
td { |
||||||
|
padding: 0.12rem; |
||||||
|
font-size: 0.13rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.8; |
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.05); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.contribution-section { |
||||||
|
background: rgba(255, 255, 255, 0.03); |
||||||
|
border-radius: 0.08rem; |
||||||
|
padding: 0.2rem; |
||||||
|
|
||||||
|
.section-header { |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
|
||||||
|
.section-title { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
padding-left: 0.12rem; |
||||||
|
border-left: 0.04rem solid #15e1fd; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.contribution-grid { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: repeat(auto-fit, minmax(3rem, 1fr)); |
||||||
|
gap: 0.15rem; |
||||||
|
|
||||||
|
.contribution-item { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 0.2rem; |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
border-radius: 0.06rem; |
||||||
|
|
||||||
|
.contribution-icon { |
||||||
|
width: 0.5rem; |
||||||
|
height: 0.5rem; |
||||||
|
border-radius: 50%; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
margin-right: 0.15rem; |
||||||
|
|
||||||
|
span { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.contribution-info { |
||||||
|
flex: 1; |
||||||
|
|
||||||
|
.contribution-name { |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.8; |
||||||
|
margin-bottom: 0.05rem; |
||||||
|
} |
||||||
|
|
||||||
|
.contribution-value { |
||||||
|
font-size: 0.2rem; |
||||||
|
color: #15e1fd; |
||||||
|
font-weight: bold; |
||||||
|
margin-bottom: 0.03rem; |
||||||
|
|
||||||
|
.unit { |
||||||
|
font-size: 0.13rem; |
||||||
|
opacity: 0.8; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.contribution-percent { |
||||||
|
font-size: 0.12rem; |
||||||
|
color: #91CC75; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 1485px) { |
||||||
|
.carbon-indicators { |
||||||
|
grid-template-columns: repeat(2, 1fr); |
||||||
|
} |
||||||
|
|
||||||
|
.chart-section { |
||||||
|
&.half-width { |
||||||
|
width: 100%; |
||||||
|
margin-right: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.contribution-grid { |
||||||
|
grid-template-columns: repeat(2, 1fr); |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,887 @@ |
|||||||
|
<template> |
||||||
|
<div class="energy-efficiency-calendar"> |
||||||
|
<!-- 顶部控制栏 --> |
||||||
|
<div class="control-bar"> |
||||||
|
<div class="date-picker-group"> |
||||||
|
<el-date-picker |
||||||
|
v-model="currentDate" |
||||||
|
type="date" |
||||||
|
placeholder="选择日期" |
||||||
|
value-format="yyyy-MM-dd" |
||||||
|
@change="handleDateChange" |
||||||
|
class="date-picker" |
||||||
|
/> |
||||||
|
<div class="view-toggle"> |
||||||
|
<div |
||||||
|
v-for="(view, index) in viewTypes" |
||||||
|
:key="index" |
||||||
|
:class="['view-btn', { active: activeView === index }]" |
||||||
|
@click="handleViewChange(index)" |
||||||
|
> |
||||||
|
{{ view }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="indicator-selector"> |
||||||
|
<el-select v-model="selectedIndicator" @change="handleIndicatorChange" class="custom-select"> |
||||||
|
<el-option |
||||||
|
v-for="indicator in indicators" |
||||||
|
:key="indicator.value" |
||||||
|
:label="indicator.label" |
||||||
|
:value="indicator.value" |
||||||
|
> |
||||||
|
<span class="option-dot" :style="{ background: indicator.color }"></span> |
||||||
|
<span class="option-label">{{ indicator.label }}</span> |
||||||
|
</el-option> |
||||||
|
</el-select> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 月份导航 --> |
||||||
|
<div class="month-navigation"> |
||||||
|
<el-button class="nav-btn" icon="el-icon-arrow-left" @click="prevMonth" size="small"></el-button> |
||||||
|
<div class="current-month">{{ currentYear }}年{{ currentMonth }}月</div> |
||||||
|
<el-button class="nav-btn" icon="el-icon-arrow-right" @click="nextMonth" size="small"></el-button> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 日历视图 --> |
||||||
|
<div class="calendar-container"> |
||||||
|
<div class="calendar-header"> |
||||||
|
<div class="weekday" v-for="day in weekDays" :key="day">{{ day }}</div> |
||||||
|
</div> |
||||||
|
<div class="calendar-body"> |
||||||
|
<div |
||||||
|
v-for="(day, index) in calendarDays" |
||||||
|
:key="index" |
||||||
|
:class="['calendar-day', { 'other-month': day.isOtherMonth, 'selected': isSelected(day), 'today': isToday(day) }]" |
||||||
|
@click="handleDayClick(day)" |
||||||
|
> |
||||||
|
<div class="day-number">{{ day.day }}</div> |
||||||
|
<div class="day-indicator" v-if="day.hasData"> |
||||||
|
<div class="indicator-value" :style="{ color: getIndicatorColor(day) }"> |
||||||
|
{{ getIndicatorValue(day) }} |
||||||
|
</div> |
||||||
|
<div class="indicator-unit">{{ getIndicatorUnit() }}</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 日期图例 --> |
||||||
|
<div class="calendar-legend"> |
||||||
|
<div class="legend-item" v-for="item in legendItems" :key="item.label"> |
||||||
|
<span class="legend-color" :style="{ background: item.color }"></span> |
||||||
|
<span class="legend-label">{{ item.label }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 日期详情面板 --> |
||||||
|
<div class="detail-panel" v-if="selectedDateData"> |
||||||
|
<div class="detail-header"> |
||||||
|
<div class="detail-title">日期详情 - {{ selectedDateData.date }}</div> |
||||||
|
<el-button class="close-btn" icon="el-icon-close" @click="closeDetail" size="small" circle></el-button> |
||||||
|
</div> |
||||||
|
<div class="detail-content"> |
||||||
|
<div class="detail-row" v-for="(item, index) in detailData" :key="index"> |
||||||
|
<div class="detail-label"> |
||||||
|
<span class="label-dot" :style="{ background: item.color }"></span> |
||||||
|
{{ item.label }} |
||||||
|
</div> |
||||||
|
<div class="detail-value" :style="{ color: item.color }"> |
||||||
|
{{ selectedDateData[item.key] }} {{ item.unit }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 月度汇总统计 --> |
||||||
|
<div class="monthly-summary"> |
||||||
|
<div class="summary-header"> |
||||||
|
<div class="summary-title">月度汇总</div> |
||||||
|
<div class="summary-period">{{ currentYear }}年{{ currentMonth }}月</div> |
||||||
|
</div> |
||||||
|
<div class="summary-cards"> |
||||||
|
<div class="summary-card"> |
||||||
|
<div class="summary-label">平均EER</div> |
||||||
|
<div class="summary-value">{{ monthlySummary.avgEer }}</div> |
||||||
|
</div> |
||||||
|
<div class="summary-card"> |
||||||
|
<div class="summary-label">总用电量</div> |
||||||
|
<div class="summary-value">{{ monthlySummary.totalEnergy }} <span class="unit">kWh</span></div> |
||||||
|
</div> |
||||||
|
<div class="summary-card"> |
||||||
|
<div class="summary-label">总供冷量</div> |
||||||
|
<div class="summary-value">{{ monthlySummary.totalCooling }} <span class="unit">RT</span></div> |
||||||
|
</div> |
||||||
|
<div class="summary-card"> |
||||||
|
<div class="summary-label">平均单价</div> |
||||||
|
<div class="summary-value">¥{{ monthlySummary.avgPrice }} <span class="unit">/kWh</span></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 趋势图 --> |
||||||
|
<div class="trend-chart-section"> |
||||||
|
<div class="chart-header"> |
||||||
|
<div class="chart-title">{{ currentMonth }}月能效趋势</div> |
||||||
|
</div> |
||||||
|
<div class="chart" ref="trendChartRef"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import * as echarts from "echarts"; |
||||||
|
|
||||||
|
export default { |
||||||
|
name: "EnergyEfficiencyCalendarViz", |
||||||
|
data() { |
||||||
|
return { |
||||||
|
// 视图类型 |
||||||
|
viewTypes: ["日视图", "月视图"], |
||||||
|
activeView: 1, |
||||||
|
// 当前日期 |
||||||
|
currentDate: new Date().toISOString().split('T')[0], |
||||||
|
currentYear: new Date().getFullYear(), |
||||||
|
currentMonth: new Date().getMonth() + 1, |
||||||
|
selectedDay: null, |
||||||
|
selectedDateData: null, |
||||||
|
// 星期 |
||||||
|
weekDays: ["日", "一", "二", "三", "四", "五", "六"], |
||||||
|
// 指标选择 |
||||||
|
indicators: [ |
||||||
|
{ label: "能效值(EER)", value: "eer", color: "#91CC75", unit: "" }, |
||||||
|
{ label: "用电量", value: "energy", color: "#5470C6", unit: "kWh" }, |
||||||
|
{ label: "供冷量", value: "cooling", color: "#15e1fd", unit: "RT" }, |
||||||
|
{ label: "供能单价", value: "price", color: "#FAC858", unit: "元/kWh" } |
||||||
|
], |
||||||
|
selectedIndicator: "eer", |
||||||
|
// 日历数据 |
||||||
|
calendarDays: [], |
||||||
|
// 图例 |
||||||
|
legendItems: [ |
||||||
|
{ label: "优秀(≥6.5)", color: "#91CC75" }, |
||||||
|
{ label: "良好(6.5-5.5)", color: "#4facfe" }, |
||||||
|
{ label: "一般(5.5-4.5)", color: "#FAC858" }, |
||||||
|
{ label: "急需改善(<4.5)", color: "#EE6666" } |
||||||
|
], |
||||||
|
// 详情数据配置 |
||||||
|
detailData: [ |
||||||
|
{ label: "能效值(EER)", key: "eer", color: "#91CC75", unit: "" }, |
||||||
|
{ label: "用电量", key: "energy", color: "#5470C6", unit: "kWh" }, |
||||||
|
{ label: "供冷量", key: "cooling", color: "#15e1fd", unit: "RT" }, |
||||||
|
{ label: "供能单价", key: "price", color: "#FAC858", unit: "元/kWh" }, |
||||||
|
{ label: "节电量", key: "saving", color: "#EE6666", unit: "kWh" } |
||||||
|
], |
||||||
|
// 月度汇总 |
||||||
|
monthlySummary: { |
||||||
|
avgEer: 6.5, |
||||||
|
totalEnergy: 5620000, |
||||||
|
totalCooling: 198500, |
||||||
|
avgPrice: 1.18 |
||||||
|
}, |
||||||
|
// 模拟日历数据 |
||||||
|
dailyData: {}, |
||||||
|
// 图表实例 |
||||||
|
trendChart: null |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.generateDailyData(); |
||||||
|
this.generateCalendar(); |
||||||
|
this.initTrendChart(); |
||||||
|
}, |
||||||
|
beforeDestroy() { |
||||||
|
if (this.trendChart) this.trendChart.dispose(); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 生成模拟日历数据 |
||||||
|
generateDailyData() { |
||||||
|
const year = this.currentYear; |
||||||
|
const month = this.currentMonth; |
||||||
|
const daysInMonth = new Date(year, month, 0).getDate(); |
||||||
|
|
||||||
|
for (let day = 1; day <= daysInMonth; day++) { |
||||||
|
const date = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`; |
||||||
|
const eer = (4 + Math.random() * 4).toFixed(1); |
||||||
|
const energy = Math.floor(150000 + Math.random() * 100000); |
||||||
|
const cooling = Math.floor(energy / 25 + Math.random() * 10); |
||||||
|
const price = (1.1 + Math.random() * 0.2).toFixed(2); |
||||||
|
const saving = Math.floor(energy * 0.25 + Math.random() * 10000); |
||||||
|
|
||||||
|
this.dailyData[date] = { |
||||||
|
date, |
||||||
|
eer: parseFloat(eer), |
||||||
|
energy, |
||||||
|
cooling, |
||||||
|
price: parseFloat(price), |
||||||
|
saving, |
||||||
|
hasData: true |
||||||
|
}; |
||||||
|
} |
||||||
|
}, |
||||||
|
// 生成日历 |
||||||
|
generateCalendar() { |
||||||
|
const year = this.currentYear; |
||||||
|
const month = this.currentMonth - 1; |
||||||
|
const firstDay = new Date(year, month, 1).getDay(); |
||||||
|
const daysInMonth = new Date(year, month + 1, 0).getDate(); |
||||||
|
const prevMonthDays = new Date(year, month, 0).getDate(); |
||||||
|
|
||||||
|
const days = []; |
||||||
|
|
||||||
|
// 上月日期 |
||||||
|
for (let i = firstDay - 1; i >= 0; i--) { |
||||||
|
days.push({ |
||||||
|
day: prevMonthDays - i, |
||||||
|
isOtherMonth: true, |
||||||
|
hasData: false |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
// 当月日期 |
||||||
|
for (let i = 1; i <= daysInMonth; i++) { |
||||||
|
const date = `${year}-${String(month + 1).padStart(2, '0')}-${String(i).padStart(2, '0')}`; |
||||||
|
days.push({ |
||||||
|
day: i, |
||||||
|
isOtherMonth: false, |
||||||
|
...this.dailyData[date] |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
// 下月日期 |
||||||
|
const remainingDays = 42 - days.length; |
||||||
|
for (let i = 1; i <= remainingDays; i++) { |
||||||
|
days.push({ |
||||||
|
day: i, |
||||||
|
isOtherMonth: true, |
||||||
|
hasData: false |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
this.calendarDays = days; |
||||||
|
}, |
||||||
|
// 日期改变 |
||||||
|
handleDateChange(value) { |
||||||
|
if (value) { |
||||||
|
const date = new Date(value); |
||||||
|
this.currentYear = date.getFullYear(); |
||||||
|
this.currentMonth = date.getMonth() + 1; |
||||||
|
this.selectedDay = date.getDate(); |
||||||
|
this.generateCalendar(); |
||||||
|
} |
||||||
|
}, |
||||||
|
// 视图切换 |
||||||
|
handleViewChange(index) { |
||||||
|
this.activeView = index; |
||||||
|
}, |
||||||
|
// 指标切换 |
||||||
|
handleIndicatorChange(value) { |
||||||
|
this.selectedIndicator = value; |
||||||
|
}, |
||||||
|
// 上月 |
||||||
|
prevMonth() { |
||||||
|
if (this.currentMonth === 1) { |
||||||
|
this.currentYear--; |
||||||
|
this.currentMonth = 12; |
||||||
|
} else { |
||||||
|
this.currentMonth--; |
||||||
|
} |
||||||
|
this.generateCalendar(); |
||||||
|
this.updateTrendChart(); |
||||||
|
}, |
||||||
|
// 下月 |
||||||
|
nextMonth() { |
||||||
|
if (this.currentMonth === 12) { |
||||||
|
this.currentYear++; |
||||||
|
this.currentMonth = 1; |
||||||
|
} else { |
||||||
|
this.currentMonth++; |
||||||
|
} |
||||||
|
this.generateCalendar(); |
||||||
|
this.updateTrendChart(); |
||||||
|
}, |
||||||
|
// 日期点击 |
||||||
|
handleDayClick(day) { |
||||||
|
if (day.isOtherMonth || !day.hasData) return; |
||||||
|
|
||||||
|
this.selectedDay = day.day; |
||||||
|
this.selectedDateData = day; |
||||||
|
}, |
||||||
|
// 判断是否选中 |
||||||
|
isSelected(day) { |
||||||
|
return !day.isOtherMonth && day.day === this.selectedDay; |
||||||
|
}, |
||||||
|
// 判断是否今天 |
||||||
|
isToday(day) { |
||||||
|
if (day.isOtherMonth) return false; |
||||||
|
const today = new Date(); |
||||||
|
return day.day === today.getDate() && |
||||||
|
this.currentMonth === today.getMonth() + 1 && |
||||||
|
this.currentYear === today.getFullYear(); |
||||||
|
}, |
||||||
|
// 获取指标颜色 |
||||||
|
getIndicatorColor(day) { |
||||||
|
if (this.selectedIndicator !== 'eer') { |
||||||
|
const indicator = this.indicators.find(i => i.value === this.selectedIndicator); |
||||||
|
return indicator ? indicator.color : '#ffffff'; |
||||||
|
} |
||||||
|
|
||||||
|
const eer = day.eer; |
||||||
|
if (eer >= 6.5) return '#91CC75'; |
||||||
|
if (eer >= 5.5) return '#4facfe'; |
||||||
|
if (eer >= 4.5) return '#FAC858'; |
||||||
|
return '#EE6666'; |
||||||
|
}, |
||||||
|
// 获取指标值 |
||||||
|
getIndicatorValue(day) { |
||||||
|
const key = this.selectedIndicator; |
||||||
|
return day[key] !== undefined ? day[key] : '-'; |
||||||
|
}, |
||||||
|
// 获取指标单位 |
||||||
|
getIndicatorUnit() { |
||||||
|
const indicator = this.indicators.find(i => i.value === this.selectedIndicator); |
||||||
|
return indicator ? indicator.unit : ''; |
||||||
|
}, |
||||||
|
// 关闭详情 |
||||||
|
closeDetail() { |
||||||
|
this.selectedDateData = null; |
||||||
|
this.selectedDay = null; |
||||||
|
}, |
||||||
|
// 初始化趋势图 |
||||||
|
initTrendChart() { |
||||||
|
this.trendChart = echarts.init(this.$refs.trendChartRef); |
||||||
|
this.updateTrendChart(); |
||||||
|
}, |
||||||
|
// 更新趋势图 |
||||||
|
updateTrendChart() { |
||||||
|
const daysInMonth = new Date(this.currentYear, this.currentMonth, 0).getDate(); |
||||||
|
const xData = []; |
||||||
|
const eerData = []; |
||||||
|
const energyData = []; |
||||||
|
|
||||||
|
for (let day = 1; day <= daysInMonth; day++) { |
||||||
|
const date = `${this.currentYear}-${String(this.currentMonth).padStart(2, '0')}-${String(day).padStart(2, '0')}`; |
||||||
|
const data = this.dailyData[date]; |
||||||
|
xData.push(`${day}日`); |
||||||
|
eerData.push(data ? data.eer : null); |
||||||
|
energyData.push(data ? data.energy : null); |
||||||
|
} |
||||||
|
|
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "axis", |
||||||
|
axisPointer: { |
||||||
|
type: "cross" |
||||||
|
} |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
data: ["能效值(EER)", "用电量"], |
||||||
|
textStyle: { |
||||||
|
color: "#ffffff" |
||||||
|
} |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: "3%", |
||||||
|
right: "4%", |
||||||
|
bottom: "3%", |
||||||
|
containLabel: true |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
data: xData, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
}, |
||||||
|
yAxis: [ |
||||||
|
{ |
||||||
|
type: "value", |
||||||
|
name: "EER", |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", |
||||||
|
type: "dashed" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "value", |
||||||
|
name: "kWh", |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "能效值(EER)", |
||||||
|
type: "line", |
||||||
|
smooth: true, |
||||||
|
data: eerData, |
||||||
|
itemStyle: { |
||||||
|
color: "#91CC75" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#91CC75", |
||||||
|
width: 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "用电量", |
||||||
|
type: "bar", |
||||||
|
yAxisIndex: 1, |
||||||
|
data: energyData, |
||||||
|
itemStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "#5470C6" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "#73C0DE" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.trendChart.setOption(option); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.energy-efficiency-calendar { |
||||||
|
padding: 0.16rem; |
||||||
|
} |
||||||
|
|
||||||
|
.control-bar { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
padding: 0.2rem; |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
border-radius: 0.08rem; |
||||||
|
margin-bottom: 0.16rem; |
||||||
|
flex-wrap: wrap; |
||||||
|
gap: 0.15rem; |
||||||
|
|
||||||
|
.date-picker-group { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
gap: 0.15rem; |
||||||
|
|
||||||
|
::v-deep .date-picker { |
||||||
|
.el-input__wrapper { |
||||||
|
background: rgba(255, 255, 255, 0.1); |
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2); |
||||||
|
|
||||||
|
.el-input__inner { |
||||||
|
color: #ffffff; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.view-toggle { |
||||||
|
display: flex; |
||||||
|
gap: 0.08rem; |
||||||
|
|
||||||
|
.view-btn { |
||||||
|
padding: 0.06rem 0.2rem; |
||||||
|
font-size: 0.13rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
cursor: pointer; |
||||||
|
border-radius: 0.04rem; |
||||||
|
transition: all 0.3s; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
&.active { |
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.indicator-selector { |
||||||
|
::v-deep .custom-select { |
||||||
|
.el-input__wrapper { |
||||||
|
background: rgba(255, 255, 255, 0.1); |
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2); |
||||||
|
|
||||||
|
.el-input__inner { |
||||||
|
color: #ffffff; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
::v-deep .option-dot { |
||||||
|
display: inline-block; |
||||||
|
width: 0.1rem; |
||||||
|
height: 0.1rem; |
||||||
|
border-radius: 50%; |
||||||
|
margin-right: 0.08rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.month-navigation { |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
gap: 0.3rem; |
||||||
|
padding: 0.15rem; |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
border-radius: 0.08rem; |
||||||
|
margin-bottom: 0.16rem; |
||||||
|
|
||||||
|
.current-month { |
||||||
|
font-size: 0.18rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.nav-btn { |
||||||
|
background: rgba(255, 255, 255, 0.1); |
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2); |
||||||
|
color: #ffffff; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
background: rgba(255, 255, 255, 0.2); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.calendar-container { |
||||||
|
background: rgba(255, 255, 255, 0.03); |
||||||
|
border-radius: 0.08rem; |
||||||
|
padding: 0.2rem; |
||||||
|
margin-bottom: 0.16rem; |
||||||
|
|
||||||
|
.calendar-header { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: repeat(7, 1fr); |
||||||
|
gap: 0.1rem; |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
|
||||||
|
.weekday { |
||||||
|
text-align: center; |
||||||
|
font-size: 0.15rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
padding: 0.1rem 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.calendar-body { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: repeat(7, 1fr); |
||||||
|
gap: 0.1rem; |
||||||
|
|
||||||
|
.calendar-day { |
||||||
|
aspect-ratio: 1; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
padding: 0.1rem; |
||||||
|
border-radius: 0.06rem; |
||||||
|
cursor: pointer; |
||||||
|
transition: all 0.3s; |
||||||
|
background: rgba(255, 255, 255, 0.03); |
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05); |
||||||
|
|
||||||
|
&:hover { |
||||||
|
background: rgba(255, 255, 255, 0.08); |
||||||
|
} |
||||||
|
|
||||||
|
&.other-month { |
||||||
|
opacity: 0.3; |
||||||
|
cursor: default; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
background: rgba(255, 255, 255, 0.03); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&.selected { |
||||||
|
background: rgba(21, 225, 253, 0.2); |
||||||
|
border: 2px solid #15e1fd; |
||||||
|
} |
||||||
|
|
||||||
|
&.today { |
||||||
|
background: rgba(145, 204, 117, 0.2); |
||||||
|
border: 1px solid #91CC75; |
||||||
|
} |
||||||
|
|
||||||
|
.day-number { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
margin-bottom: 0.05rem; |
||||||
|
} |
||||||
|
|
||||||
|
.day-indicator { |
||||||
|
text-align: center; |
||||||
|
|
||||||
|
.indicator-value { |
||||||
|
font-size: 0.14rem; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.indicator-unit { |
||||||
|
font-size: 0.1rem; |
||||||
|
opacity: 0.7; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.calendar-legend { |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
gap: 0.3rem; |
||||||
|
padding: 0.2rem; |
||||||
|
background: rgba(255, 255, 255, 0.03); |
||||||
|
border-radius: 0.08rem; |
||||||
|
margin-bottom: 0.16rem; |
||||||
|
flex-wrap: wrap; |
||||||
|
|
||||||
|
.legend-item { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
font-size: 0.13rem; |
||||||
|
color: #ffffff; |
||||||
|
|
||||||
|
.legend-color { |
||||||
|
width: 0.12rem; |
||||||
|
height: 0.12rem; |
||||||
|
border-radius: 50%; |
||||||
|
margin-right: 0.08rem; |
||||||
|
} |
||||||
|
|
||||||
|
.legend-label { |
||||||
|
opacity: 0.8; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.detail-panel { |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
border-radius: 0.08rem; |
||||||
|
padding: 0.2rem; |
||||||
|
margin-bottom: 0.16rem; |
||||||
|
|
||||||
|
.detail-header { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
|
||||||
|
.detail-title { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
padding-left: 0.12rem; |
||||||
|
border-left: 0.04rem solid #15e1fd; |
||||||
|
} |
||||||
|
|
||||||
|
.close-btn { |
||||||
|
background: rgba(255, 255, 255, 0.1); |
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2); |
||||||
|
color: #ffffff; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
background: rgba(255, 255, 255, 0.2); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.detail-content { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: repeat(auto-fit, minmax(2rem, 1fr)); |
||||||
|
gap: 0.15rem; |
||||||
|
|
||||||
|
.detail-row { |
||||||
|
padding: 0.15rem; |
||||||
|
background: rgba(255, 255, 255, 0.03); |
||||||
|
border-radius: 0.06rem; |
||||||
|
|
||||||
|
.detail-label { |
||||||
|
font-size: 0.13rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
margin-bottom: 0.08rem; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
|
||||||
|
.label-dot { |
||||||
|
width: 0.08rem; |
||||||
|
height: 0.08rem; |
||||||
|
border-radius: 50%; |
||||||
|
margin-right: 0.08rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.detail-value { |
||||||
|
font-size: 0.18rem; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.monthly-summary { |
||||||
|
background: rgba(255, 255, 255, 0.03); |
||||||
|
border-radius: 0.08rem; |
||||||
|
padding: 0.2rem; |
||||||
|
margin-bottom: 0.16rem; |
||||||
|
|
||||||
|
.summary-header { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
|
||||||
|
.summary-title { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
padding-left: 0.12rem; |
||||||
|
border-left: 0.04rem solid #15e1fd; |
||||||
|
} |
||||||
|
|
||||||
|
.summary-period { |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.summary-cards { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: repeat(auto-fit, minmax(2rem, 1fr)); |
||||||
|
gap: 0.15rem; |
||||||
|
|
||||||
|
.summary-card { |
||||||
|
padding: 0.2rem; |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
border-radius: 0.06rem; |
||||||
|
text-align: center; |
||||||
|
|
||||||
|
.summary-label { |
||||||
|
font-size: 0.13rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
margin-bottom: 0.1rem; |
||||||
|
} |
||||||
|
|
||||||
|
.summary-value { |
||||||
|
font-size: 0.22rem; |
||||||
|
color: #15e1fd; |
||||||
|
font-weight: bold; |
||||||
|
|
||||||
|
.unit { |
||||||
|
font-size: 0.13rem; |
||||||
|
opacity: 0.8; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.trend-chart-section { |
||||||
|
background: rgba(255, 255, 255, 0.03); |
||||||
|
border-radius: 0.08rem; |
||||||
|
padding: 0.2rem; |
||||||
|
|
||||||
|
.chart-header { |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
|
||||||
|
.chart-title { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
padding-left: 0.12rem; |
||||||
|
border-left: 0.04rem solid #15e1fd; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.chart { |
||||||
|
width: 100%; |
||||||
|
height: 3rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 1485px) { |
||||||
|
.calendar-body { |
||||||
|
.calendar-day { |
||||||
|
.day-number { |
||||||
|
font-size: 0.14rem; |
||||||
|
} |
||||||
|
|
||||||
|
.day-indicator { |
||||||
|
.indicator-value { |
||||||
|
font-size: 0.12rem; |
||||||
|
} |
||||||
|
|
||||||
|
.indicator-unit { |
||||||
|
font-size: 0.09rem; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.detail-content { |
||||||
|
grid-template-columns: repeat(2, 1fr); |
||||||
|
} |
||||||
|
|
||||||
|
.summary-cards { |
||||||
|
grid-template-columns: repeat(2, 1fr); |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,531 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class="historyCharts" ref="chart_ref"></div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import * as echarts from "echarts"; |
||||||
|
export default { |
||||||
|
props: { |
||||||
|
temArray: { |
||||||
|
type: Array, |
||||||
|
default: () => [], |
||||||
|
}, |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
chartInstance: null, |
||||||
|
option: {}, |
||||||
|
chartData1: [], |
||||||
|
chartData2: [], |
||||||
|
chartData3: [], |
||||||
|
chartData4: [], |
||||||
|
chartData5: [], |
||||||
|
bottomData: [], |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
temArray: { |
||||||
|
immediate: true, // 页面加载时立即触发一次监听 |
||||||
|
handler(newVal, oldVal) { |
||||||
|
if (newVal) { |
||||||
|
this.chartData1 = []; // 清空 chartData1 |
||||||
|
this.chartData2 = []; // 清空 chartData2 |
||||||
|
this.bottomData = []; // 清空 bottomData |
||||||
|
console.log("charts传值", newVal); |
||||||
|
let data = newVal; |
||||||
|
if (data.length > 0) { |
||||||
|
// 获取 title 和 titleStr 数组 |
||||||
|
const title = data[0].title; |
||||||
|
const titleStr = data[1].titleStr; |
||||||
|
// 获取 dataList 数组 |
||||||
|
const dataList = data[3].dataList; |
||||||
|
|
||||||
|
// 遍历 dataList 数组 |
||||||
|
dataList.forEach((item) => { |
||||||
|
// 查找 name 在 title 数组中的索引 |
||||||
|
const index = title.indexOf(item.name); |
||||||
|
if (index !== -1) { |
||||||
|
// 若找到匹配项,则将 name 替换为 titleStr 中对应位置的值 |
||||||
|
item.name = titleStr[index]; |
||||||
|
} |
||||||
|
}); |
||||||
|
console.log("处理后的data", data); |
||||||
|
let name1 = ""; |
||||||
|
let name2 = ""; |
||||||
|
let name3 = ""; |
||||||
|
let name4 = ""; |
||||||
|
let name5 = ""; |
||||||
|
|
||||||
|
data.forEach((item) => { |
||||||
|
if (item.timeStr) { |
||||||
|
this.bottomData = item.timeStr; |
||||||
|
} |
||||||
|
|
||||||
|
if (item.dataList) { |
||||||
|
// 用于存储 name 的数组 |
||||||
|
const names = []; |
||||||
|
// 用于存储 chartData 的数组 |
||||||
|
const chartData = []; |
||||||
|
|
||||||
|
// 查找包含“负载”的数据 |
||||||
|
let loadDataIndex = -1; |
||||||
|
for (let i = 0; i < item.dataList.length; i++) { |
||||||
|
if ( |
||||||
|
item.dataList[i].name && |
||||||
|
item.dataList[i].name.includes("负载") |
||||||
|
) { |
||||||
|
loadDataIndex = i; |
||||||
|
this.chartData5 = item.dataList[i].value; |
||||||
|
name5 = item.dataList[i].name; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 剔除包含“负载”的数据 |
||||||
|
if (loadDataIndex !== -1) { |
||||||
|
item.dataList.splice(loadDataIndex, 1); |
||||||
|
} |
||||||
|
|
||||||
|
// 处理剩下的数据 |
||||||
|
item.dataList.slice(0, 4).forEach((val, index) => { |
||||||
|
if (val.name) { |
||||||
|
chartData[index] = val.value; |
||||||
|
names[index] = val.name; |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// 将 chartData 数组的值赋值给 this.chartDataX |
||||||
|
this.chartData1 = chartData[0] || ""; |
||||||
|
this.chartData2 = chartData[1] || ""; |
||||||
|
this.chartData3 = chartData[2] || ""; |
||||||
|
this.chartData4 = chartData[3] || ""; |
||||||
|
|
||||||
|
// 将 names 数组的值赋值给外部作用域的变量 |
||||||
|
name1 = names[0] || ""; |
||||||
|
name2 = names[1] || ""; |
||||||
|
name3 = names[2] || ""; |
||||||
|
name4 = names[3] || ""; |
||||||
|
} |
||||||
|
}); |
||||||
|
// console.log("this.chartData1", this.chartData1); |
||||||
|
// console.log("this.chartData2", this.chartData2); |
||||||
|
// console.log("this.chartData3", this.chartData3); |
||||||
|
// console.log("this.chartData4", this.chartData4); |
||||||
|
// console.log("this.chartData5", this.chartData5); |
||||||
|
this.$nextTick(() => { |
||||||
|
// 计算双y轴最大最小值, |
||||||
|
var Min1 = 0, |
||||||
|
Min2 = 0, |
||||||
|
Max1 = Math.ceil( |
||||||
|
Math.max( |
||||||
|
...this.chartData1, |
||||||
|
...this.chartData2, |
||||||
|
...this.chartData3, |
||||||
|
...this.chartData4 |
||||||
|
) |
||||||
|
), |
||||||
|
Max2 = Math.ceil(Math.max(...this.chartData5)); |
||||||
|
console.log("Min1", Min1); |
||||||
|
console.log("Min2", Min2); |
||||||
|
console.log("Max1", Max1); |
||||||
|
console.log("Max2", Max2); |
||||||
|
const adapterOption = { |
||||||
|
xAxis: { |
||||||
|
data: this.bottomData, |
||||||
|
}, |
||||||
|
yAxis: [ |
||||||
|
//两个y轴 |
||||||
|
{ |
||||||
|
min: Min1, |
||||||
|
max: Max1, |
||||||
|
splitNumber: 10, |
||||||
|
interval: (Max1 - Min1) / 10, |
||||||
|
}, |
||||||
|
{ |
||||||
|
min: Min2, |
||||||
|
max: Max2, |
||||||
|
splitNumber: 10, |
||||||
|
interval: (Max2 - Min2) / 10, |
||||||
|
}, |
||||||
|
], |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
name: name1, |
||||||
|
data: this.chartData1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
name: name2, |
||||||
|
data: this.chartData2, |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
name: name3, |
||||||
|
data: this.chartData3, |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
name: name4, |
||||||
|
data: this.chartData4, |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 1, |
||||||
|
name: name5, |
||||||
|
data: this.chartData5, |
||||||
|
}, |
||||||
|
], |
||||||
|
}; |
||||||
|
this.chartInstance.setOption(adapterOption); |
||||||
|
// 手动的调用图标对象的 resize 才能产生效果 |
||||||
|
this.chartInstance.resize(); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.$nextTick(() => { |
||||||
|
const adapterOption = { |
||||||
|
xAxis: { |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
yAxis: [ |
||||||
|
//两个y轴 |
||||||
|
{ |
||||||
|
min: 0, |
||||||
|
max: 0, |
||||||
|
splitNumber: 10, |
||||||
|
interval: 0, |
||||||
|
}, |
||||||
|
{ |
||||||
|
min: 0, |
||||||
|
max: 0, |
||||||
|
splitNumber: 10, |
||||||
|
interval: 0, |
||||||
|
}, |
||||||
|
], |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
], |
||||||
|
}; |
||||||
|
this.chartInstance.setOption(adapterOption); |
||||||
|
//手动的调用图标对象的resize才能产生效果 |
||||||
|
this.chartInstance.resize(); |
||||||
|
this.screenAdapter(); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.initChart(); |
||||||
|
this.screenAdapter(); |
||||||
|
}, |
||||||
|
destroyed() { |
||||||
|
//取消监听器 |
||||||
|
window.removeEventListener("resize", this.screenAdapter); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 折线图自适应+ 根据按钮切换图例仅限一条且不可点击+ 折线图数据 |
||||||
|
screenAdapter() { |
||||||
|
//自己定义的比较合适的适配大小,2.6 mes_ref是图表盒子 |
||||||
|
const titleFontSize = this.$refs.chart_ref.offsetWidth / 130; |
||||||
|
//因为option可以多次配置的,所以这里的option只需要写 需要配置大小的相关数据 |
||||||
|
const adapterOption = {}; |
||||||
|
//记得重新给配置项给实例对象。只要实例对象.chartInstance不变,option就可以多次配置不同的条件。也可以配置一个dataoption只写需要从后台请求的数据相关 |
||||||
|
this.chartInstance.setOption(adapterOption); |
||||||
|
//手动的调用图标对象的resize才能产生效果 |
||||||
|
this.chartInstance.resize(); |
||||||
|
}, |
||||||
|
//初始化chartInstance对象 |
||||||
|
initChart() { |
||||||
|
var Min1 = 0, |
||||||
|
Min2 = 0, |
||||||
|
Max1 = Math.ceil( |
||||||
|
Math.max( |
||||||
|
...this.chartData1, |
||||||
|
...this.chartData2, |
||||||
|
...this.chartData3, |
||||||
|
...this.chartData4 |
||||||
|
) + 4 |
||||||
|
), |
||||||
|
Max2 = Math.ceil(Math.max(...this.chartData5) + 4); |
||||||
|
const chartRef = this.$refs.chart_ref; |
||||||
|
if (chartRef) { |
||||||
|
// 初始化图表的代码 |
||||||
|
this.chartInstance = echarts.init(this.$refs.chart_ref); |
||||||
|
const titleFontSize = this.$refs.chart_ref.offsetWidth / 130; |
||||||
|
this.option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "axis", |
||||||
|
// 自定义 tooltip 内容 |
||||||
|
formatter: function (params) { |
||||||
|
var res = params[0].name + "<br/>"; |
||||||
|
for (var i = 0, l = params.length; i < l; i++) { |
||||||
|
var seriesName = params[i].seriesName; |
||||||
|
var value = params[i].value; |
||||||
|
// console.log("打印颜色", params[i].color) |
||||||
|
var marker = |
||||||
|
'<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' + |
||||||
|
params[i].color + |
||||||
|
'"></span>'; |
||||||
|
// 根据不同的seriesName 返回不同的单位 |
||||||
|
if (seriesName.includes("负载")) { |
||||||
|
res += |
||||||
|
marker + |
||||||
|
seriesName + |
||||||
|
":" + |
||||||
|
'<span style="color: #000000; font-weight: bold;margin-left:5px">' + |
||||||
|
value + |
||||||
|
" " + |
||||||
|
"%" + |
||||||
|
"</span><br>"; |
||||||
|
} else { |
||||||
|
res += |
||||||
|
marker + |
||||||
|
seriesName + |
||||||
|
":" + |
||||||
|
'<span style="color: #000000; font-weight: bold;margin-left:5px">' + |
||||||
|
value + |
||||||
|
" " + |
||||||
|
"℃" + |
||||||
|
"</span><br>"; |
||||||
|
} |
||||||
|
} |
||||||
|
return res; |
||||||
|
}, |
||||||
|
textStyle: { |
||||||
|
fontSize: titleFontSize * 1.5, |
||||||
|
}, |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
show: true, |
||||||
|
top: 0, |
||||||
|
textStyle: { |
||||||
|
color: "white", |
||||||
|
fontSize: titleFontSize * 1.5, |
||||||
|
}, |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
top: "10%", |
||||||
|
left: "4%", |
||||||
|
right: "6%", |
||||||
|
bottom: "3%", |
||||||
|
containLabel: true, |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
//设置为true代表离零刻度间隔一段距离 |
||||||
|
boundaryGap: true, |
||||||
|
// 修饰刻度标签的颜色即x坐标数据 |
||||||
|
axisLabel: { |
||||||
|
// interval: 0, //强制显示所有x轴数据 |
||||||
|
// rotate: 30, //x轴坐标字体倾斜30度 |
||||||
|
color: "rgba(255, 255, 255, 1)", |
||||||
|
textStyle: { |
||||||
|
fontSize: titleFontSize * 1.5, |
||||||
|
}, |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false, // 不显示坐标轴刻度线 |
||||||
|
}, |
||||||
|
// x坐标轴的颜色 |
||||||
|
axisLine: { |
||||||
|
show: true, |
||||||
|
lineStyle: { |
||||||
|
color: "#365576", |
||||||
|
}, |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#e2e6f0", |
||||||
|
}, |
||||||
|
}, //x轴分割线 |
||||||
|
data: this.bottomData, |
||||||
|
}, |
||||||
|
yAxis: [ |
||||||
|
{ |
||||||
|
min: Min1, |
||||||
|
max: Max1, |
||||||
|
splitNumber: 10, |
||||||
|
interval: (Max1 - Min1) / 10, |
||||||
|
// 设置 name 的样式 |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 1)", |
||||||
|
fontSize: titleFontSize * 2, |
||||||
|
}, |
||||||
|
miniInterval: 5, |
||||||
|
type: "value", |
||||||
|
// 修饰刻度标签的颜色即y坐标数据 |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 1)", |
||||||
|
textStyle: { |
||||||
|
fontSize: titleFontSize * 1.5, |
||||||
|
}, |
||||||
|
}, |
||||||
|
// 显示y坐标轴 |
||||||
|
axisLine: { |
||||||
|
show: true, |
||||||
|
lineStyle: { |
||||||
|
color: "#365576", // 设置 y 轴线的颜色 |
||||||
|
}, |
||||||
|
}, |
||||||
|
//y轴分割线段数 |
||||||
|
// splitNumber: 10, |
||||||
|
// 修改y轴分割线的颜色 |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", // 设置分割线的颜色 |
||||||
|
type: "dashed", // 设置分割线为虚线 |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
min: Min2, |
||||||
|
max: Max2, |
||||||
|
splitNumber: 10, |
||||||
|
interval: (Max2 - Min2) / 10, |
||||||
|
// 设置 name 的样式 |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 1)", |
||||||
|
fontSize: titleFontSize * 1.5, |
||||||
|
}, |
||||||
|
miniInterval: 5, |
||||||
|
type: "value", |
||||||
|
name: "负载", // y 轴的单位描述 |
||||||
|
// 修饰刻度标签的颜色即y坐标数据 |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 1)", |
||||||
|
textStyle: { |
||||||
|
fontSize: titleFontSize * 1.5, |
||||||
|
}, |
||||||
|
}, |
||||||
|
// 显示y坐标轴 |
||||||
|
axisLine: { |
||||||
|
show: true, |
||||||
|
lineStyle: { |
||||||
|
color: "#365576", // 设置 y 轴线的颜色 |
||||||
|
}, |
||||||
|
}, |
||||||
|
//y轴分割线段数 |
||||||
|
// splitNumber: 10, |
||||||
|
// 修改y轴分割线的颜色 |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", // 设置分割线的颜色 |
||||||
|
type: "dashed", // 设置分割线为虚线 |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
type: "line", |
||||||
|
// 拐点大小 |
||||||
|
symbolSize: 8, |
||||||
|
data: this.chartData1, |
||||||
|
yAxisIndex: 0, |
||||||
|
//折线颜色 |
||||||
|
itemStyle: { |
||||||
|
color: "#00CED1", //折线点的颜色 |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#00CED1", //折线点的颜色 |
||||||
|
}, |
||||||
|
smooth: false, |
||||||
|
// 不显示折线点 |
||||||
|
showSymbol: false, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "line", |
||||||
|
// 拐点大小 |
||||||
|
symbolSize: 8, |
||||||
|
data: this.chartData2, |
||||||
|
yAxisIndex: 0, |
||||||
|
//折线颜色 |
||||||
|
itemStyle: { |
||||||
|
color: "#3ba272", //折线的颜色 |
||||||
|
}, |
||||||
|
smooth: false, |
||||||
|
// 不显示折线点 |
||||||
|
showSymbol: false, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "line", |
||||||
|
// 拐点大小 |
||||||
|
symbolSize: 8, |
||||||
|
data: this.chartData3, |
||||||
|
yAxisIndex: 0, |
||||||
|
//折线颜色 |
||||||
|
itemStyle: { |
||||||
|
color: "#1a69f1", //折线的颜色 |
||||||
|
}, |
||||||
|
smooth: false, |
||||||
|
// 不显示折线点 |
||||||
|
showSymbol: false, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "line", |
||||||
|
// 拐点大小 |
||||||
|
symbolSize: 8, |
||||||
|
data: this.chartData4, |
||||||
|
yAxisIndex: 0, |
||||||
|
//折线颜色 |
||||||
|
itemStyle: { |
||||||
|
color: "#ee6666", //折线的颜色 |
||||||
|
}, |
||||||
|
smooth: false, |
||||||
|
// 不显示折线点 |
||||||
|
showSymbol: false, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "line", |
||||||
|
// 拐点大小 |
||||||
|
symbolSize: 8, |
||||||
|
data: this.chartData5, |
||||||
|
yAxisIndex: 1, |
||||||
|
//折线颜色 |
||||||
|
itemStyle: { |
||||||
|
color: "#fac858", //折线的颜色 |
||||||
|
}, |
||||||
|
smooth: false, |
||||||
|
// 不显示折线点 |
||||||
|
showSymbol: false, |
||||||
|
}, |
||||||
|
], |
||||||
|
}; |
||||||
|
//把配置项给实例对象 |
||||||
|
this.chartInstance.setOption(this.option, true); |
||||||
|
} else { |
||||||
|
console.error("未找到有效的 DOM 元素"); |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.historyCharts { |
||||||
|
width: 100%; |
||||||
|
height: 4.4rem; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,120 @@ |
|||||||
|
<template> |
||||||
|
<div class="line-container"> |
||||||
|
<!-- 第一个圆点 --> |
||||||
|
<div class="dot dot-start"></div> |
||||||
|
<!-- 第一条直线 --> |
||||||
|
<div |
||||||
|
class="line line1" |
||||||
|
:style="{ |
||||||
|
transform: `rotate(${angle1}deg)`, |
||||||
|
width: lineWidth1Rem + 'rem' |
||||||
|
}" |
||||||
|
></div> |
||||||
|
<!-- 中间圆点 --> |
||||||
|
<div |
||||||
|
class="dot dot-mid" |
||||||
|
:style="{ |
||||||
|
top: (1 + Math.sin((angle1 * Math.PI) / 180) * lineWidth1Rem - 0.025) + 'rem', |
||||||
|
left: (1 + Math.cos((angle1 * Math.PI) / 180) * lineWidth1Rem - 0.025) + 'rem' |
||||||
|
}" |
||||||
|
></div> |
||||||
|
<!-- 第二条直线 --> |
||||||
|
<div |
||||||
|
class="line line2" |
||||||
|
:style="{ |
||||||
|
top: (1 + Math.sin((angle1 * Math.PI) / 180) * lineWidth1Rem) + 'rem', |
||||||
|
left: (1 + Math.cos((angle1 * Math.PI) / 180) * lineWidth1Rem) + 'rem', |
||||||
|
transform: `rotate(${angle2}deg)`, |
||||||
|
width: lineWidth2Rem + 'rem' |
||||||
|
}" |
||||||
|
></div> |
||||||
|
<!-- 最后一个圆点 --> |
||||||
|
<div |
||||||
|
class="dot dot-end" |
||||||
|
:style="{ |
||||||
|
top: endDotTop + 'rem', |
||||||
|
left: endDotLeft + 'rem' |
||||||
|
}" |
||||||
|
></div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
props: { |
||||||
|
// 第一条直线的角度 |
||||||
|
angle1: { |
||||||
|
type: Number, |
||||||
|
default: 0 |
||||||
|
}, |
||||||
|
// 第二条直线的角度 |
||||||
|
angle2: { |
||||||
|
type: Number, |
||||||
|
default: 0 |
||||||
|
}, |
||||||
|
// 第一条直线的宽度(px) |
||||||
|
lineWidth1: { |
||||||
|
type: Number, |
||||||
|
default: 100 |
||||||
|
}, |
||||||
|
// 第二条直线的宽度(px) |
||||||
|
lineWidth2: { |
||||||
|
type: Number, |
||||||
|
default: 100 |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
lineWidth1Rem() { |
||||||
|
return this.lineWidth1 / 100; |
||||||
|
}, |
||||||
|
lineWidth2Rem() { |
||||||
|
return this.lineWidth2 / 100; |
||||||
|
}, |
||||||
|
endDotTop() { |
||||||
|
// 第一条直线终点的 y 坐标 |
||||||
|
const firstLineEndY = 1 + Math.sin((this.angle1 * Math.PI) / 180) * this.lineWidth1Rem; |
||||||
|
// 第二条直线在第一条直线基础上终点的 y 坐标偏移量 |
||||||
|
const secondLineYOffset = Math.sin((this.angle2 * Math.PI) / 180) * this.lineWidth2Rem; |
||||||
|
return firstLineEndY + secondLineYOffset - 0.025; |
||||||
|
}, |
||||||
|
endDotLeft() { |
||||||
|
// 第一条直线终点的 x 坐标 |
||||||
|
const firstLineEndX = 1 + Math.cos((this.angle1 * Math.PI) / 180) * this.lineWidth1Rem; |
||||||
|
// 第二条直线在第一条直线基础上终点的 x 坐标偏移量 |
||||||
|
const secondLineXOffset = Math.cos((this.angle2 * Math.PI) / 180) * this.lineWidth2Rem; |
||||||
|
return firstLineEndX + secondLineXOffset - 0.025; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
.line-container { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.line { |
||||||
|
position: absolute; |
||||||
|
height: 1px; |
||||||
|
background-color: rgba(0, 255, 255, 0.5); |
||||||
|
transform-origin: left center; |
||||||
|
} |
||||||
|
|
||||||
|
.line1 { |
||||||
|
top: 1rem; |
||||||
|
left: 1rem; |
||||||
|
} |
||||||
|
|
||||||
|
.dot { |
||||||
|
position: absolute; |
||||||
|
width: 0.05rem; |
||||||
|
height: 0.05rem; |
||||||
|
background-color: aqua; |
||||||
|
border-radius: 50%; |
||||||
|
} |
||||||
|
|
||||||
|
.dot-start { |
||||||
|
top: 0.97rem; |
||||||
|
left: 0.97rem; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,67 @@ |
|||||||
|
<template> |
||||||
|
<div class="crossed-lines-container"> |
||||||
|
<!-- 上边线 --> |
||||||
|
<div |
||||||
|
class="line horizontal-line" |
||||||
|
:style="{ width: (horizontalLength / 100) + 'rem', left: `calc(50% - ${horizontalLength / 200}rem)`, top: `calc(50% - ${(verticalLength / 200) - (overlap / 100)}rem)` }" |
||||||
|
></div> |
||||||
|
<!-- 右边线 --> |
||||||
|
<div |
||||||
|
class="line vertical-line" |
||||||
|
:style="{ height: (verticalLength / 100) + 'rem', top: `calc(50% - ${verticalLength / 200}rem)`, left: `calc(50% + ${(horizontalLength / 200) - (overlap / 100)}rem)` }" |
||||||
|
></div> |
||||||
|
<!-- 下边线 --> |
||||||
|
<div |
||||||
|
class="line horizontal-line" |
||||||
|
:style="{ width: (horizontalLength / 100) + 'rem', left: `calc(50% - ${horizontalLength / 200}rem)`, top: `calc(50% + ${(verticalLength / 200) - (overlap / 100)}rem)` }" |
||||||
|
></div> |
||||||
|
<!-- 左边线 --> |
||||||
|
<div |
||||||
|
class="line vertical-line" |
||||||
|
:style="{ height: (verticalLength / 100) + 'rem', top: `calc(50% - ${verticalLength / 200}rem)`, left: `calc(50% - ${(horizontalLength / 200) - (overlap / 100)}rem)` }" |
||||||
|
></div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
props: { |
||||||
|
// 水平方向(上下边)的直线长度 |
||||||
|
horizontalLength: { |
||||||
|
type: Number, |
||||||
|
default: 100 |
||||||
|
}, |
||||||
|
// 垂直方向(左右边)的直线长度 |
||||||
|
verticalLength: { |
||||||
|
type: Number, |
||||||
|
default: 100 |
||||||
|
}, |
||||||
|
// 直线交叉时超出的长度 |
||||||
|
overlap: { |
||||||
|
type: Number, |
||||||
|
default: 10 |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
.crossed-lines-container { |
||||||
|
position: relative; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.line { |
||||||
|
position: absolute; |
||||||
|
background-color: rgb(45, 121, 236,0.7); |
||||||
|
} |
||||||
|
|
||||||
|
.horizontal-line { |
||||||
|
height: 0.01rem; |
||||||
|
} |
||||||
|
|
||||||
|
.vertical-line { |
||||||
|
width: 0.01rem; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,450 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class="sys_charts" ref="sys_charts"></div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import * as echarts from "echarts"; |
||||||
|
export default { |
||||||
|
props: { |
||||||
|
hostData: { |
||||||
|
type: Array, |
||||||
|
default: () => [], |
||||||
|
}, |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
chartInstance: null, |
||||||
|
option: {}, |
||||||
|
loadPercent: "", |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
hostData: { |
||||||
|
immediate: true, // 页面加载时立即触发一次监听 |
||||||
|
handler(newVal, oldVal) { |
||||||
|
if (newVal) { |
||||||
|
console.log("charts传值", newVal); |
||||||
|
let data = newVal; |
||||||
|
if (data.length > 0) { |
||||||
|
data.forEach((item) => { |
||||||
|
if (item.otherName === "负载") { |
||||||
|
this.loadPercent = item.curValue; |
||||||
|
} |
||||||
|
}); |
||||||
|
this.$nextTick(() => { |
||||||
|
// 销毁现有的 ECharts 实例 |
||||||
|
if (this.chartInstance) { |
||||||
|
this.chartInstance.dispose(); |
||||||
|
} |
||||||
|
// 重新初始化图表 |
||||||
|
this.initChart(); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.initChart(); |
||||||
|
this.screenAdapter(); |
||||||
|
window.addEventListener("resize", this.screenAdapter); |
||||||
|
}, |
||||||
|
destroyed() { |
||||||
|
//与mounted中的监听对应,在组件销毁的时候,需要将监听器取消掉 |
||||||
|
window.removeEventListener("resize", this.screenAdapter); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 计算颜色设置的函数 |
||||||
|
getAxisLineColor(useData, maxData) { |
||||||
|
// 计算阈值 |
||||||
|
// 真实值大于最大值的0.75才使用颜色渐变 |
||||||
|
const threshold = maxData * 0.75; |
||||||
|
|
||||||
|
// 判断实际值是否超过阈值 |
||||||
|
if (useData > threshold) { |
||||||
|
return [ |
||||||
|
[ |
||||||
|
useData / maxData, |
||||||
|
new echarts.graphic.LinearGradient(0, 0, 1, 0, [ |
||||||
|
{ offset: 0, color: "rgba(0,127,208,1)" }, |
||||||
|
{ offset: 0.6, color: "rgba(0,127,208,1)" }, |
||||||
|
{ offset: 1, color: "rgba(69, 235, 167,0.5)" }, |
||||||
|
]), |
||||||
|
], |
||||||
|
[1, "rgba(28,128,245,.0)"], |
||||||
|
]; |
||||||
|
} else { |
||||||
|
return [ |
||||||
|
[ |
||||||
|
useData / maxData, |
||||||
|
new echarts.graphic.LinearGradient(0, 0, 1, 0, [ |
||||||
|
{ offset: 0, color: "rgba(0,127,208,1)" }, |
||||||
|
{ offset: 0.5, color: "rgba(0,127,208,1)" }, |
||||||
|
{ offset: 1, color: "rgba(0,127,208,1)" }, |
||||||
|
]), |
||||||
|
], |
||||||
|
[1, "rgba(28,128,245,.0)"], |
||||||
|
]; |
||||||
|
} |
||||||
|
}, |
||||||
|
//初始化chartInstance2对象 折线图 |
||||||
|
initChart() { |
||||||
|
var value = 80; |
||||||
|
// 初始化数据 |
||||||
|
const dataArr = this.loadPercent; //负载数据 |
||||||
|
const dataX = 100; |
||||||
|
const titleFontSize = this.$refs.sys_charts.offsetWidth / 20; |
||||||
|
this.chartInstance = echarts.init(this.$refs.sys_charts); |
||||||
|
this.option = { |
||||||
|
backgroundStyle: { |
||||||
|
borderWidth: 1, |
||||||
|
color: "transparent", |
||||||
|
}, |
||||||
|
title: [ |
||||||
|
{ |
||||||
|
text: `${dataArr} %`, |
||||||
|
bottom: titleFontSize, |
||||||
|
left: "center", |
||||||
|
textStyle: { |
||||||
|
fontSize: titleFontSize * 1.5, //标记 |
||||||
|
color: "#ffff", |
||||||
|
fontWeight: 800, |
||||||
|
}, |
||||||
|
triggerEvent: true, |
||||||
|
}, |
||||||
|
], |
||||||
|
|
||||||
|
legend: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "最外部进度条", |
||||||
|
type: "gauge", |
||||||
|
radius: "99%", |
||||||
|
splitNumber: 10, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: [ |
||||||
|
[ |
||||||
|
dataArr / dataX, |
||||||
|
{ |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 1, |
||||||
|
x2: 0.5, |
||||||
|
y2: 0.5, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(0,0,0,0)", // 0% 处的颜色 |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 0.8, |
||||||
|
color: "#195b9d", // 100% 处的颜色 |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "#0a2256", // 100% 处的颜色 |
||||||
|
}, |
||||||
|
], |
||||||
|
global: false, // 缺省为 false |
||||||
|
}, |
||||||
|
], |
||||||
|
[1, "#083158"], |
||||||
|
], |
||||||
|
width: 5, //标记 |
||||||
|
}, |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
itemStyle: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
detail: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
title: { |
||||||
|
// 标题 |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
data: [ |
||||||
|
{ |
||||||
|
name: "title", |
||||||
|
value: dataArr, |
||||||
|
}, |
||||||
|
], |
||||||
|
pointer: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
animationDuration: 4000, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "刻度尺", |
||||||
|
type: "gauge", |
||||||
|
radius: "88%", |
||||||
|
splitNumber: 10, // 刻度数量 |
||||||
|
min: 0, // 最小刻度 |
||||||
|
max: dataX, // 最大刻度 |
||||||
|
// 分隔线 |
||||||
|
splitLine: { |
||||||
|
show: true, |
||||||
|
length: 12, |
||||||
|
lineStyle: { |
||||||
|
width: 3, |
||||||
|
color: "#12E5FE", |
||||||
|
}, |
||||||
|
}, |
||||||
|
// 刻度线 |
||||||
|
axisTick: { |
||||||
|
show: true, |
||||||
|
splitNumber: 10, |
||||||
|
length: 5, |
||||||
|
lineStyle: { |
||||||
|
color: "#12E5FE", |
||||||
|
width: 2, |
||||||
|
}, |
||||||
|
}, |
||||||
|
// 刻度标签 |
||||||
|
axisLabel: { |
||||||
|
distance: -8, //刻度数字离轴线的距离 |
||||||
|
color: "#CEF3FE", |
||||||
|
fontSize: "6", |
||||||
|
fontWeight: 600, |
||||||
|
}, |
||||||
|
detail: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
width: -10, //刻度离轴线的距离 |
||||||
|
color: [ |
||||||
|
[ |
||||||
|
1, |
||||||
|
{ |
||||||
|
type: "radial", |
||||||
|
x: 0.5, |
||||||
|
y: 0.6, |
||||||
|
r: 0.6, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0.85, |
||||||
|
color: "#031F46", // 0% 处的颜色 |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 0.93, |
||||||
|
color: "#060d25", // 100% 处的颜色 |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "#12D7EF", // 100% 处的颜色 |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "外部指针", |
||||||
|
type: "gauge", |
||||||
|
radius: "90%", |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: [ |
||||||
|
[dataArr / dataX - 0.001, "rgba(0,0,0,0)"], |
||||||
|
[dataArr / dataX + 0.003, "#e43c59"], |
||||||
|
[1, "rgba(0,0,0,0)"], |
||||||
|
], |
||||||
|
width: 33, |
||||||
|
}, |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
itemStyle: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
detail: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
title: { |
||||||
|
// 标题 |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
data: [ |
||||||
|
{ |
||||||
|
name: "title", |
||||||
|
value: dataArr, |
||||||
|
}, |
||||||
|
], |
||||||
|
pointer: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "内层带指针", |
||||||
|
type: "gauge", |
||||||
|
radius: "60%", |
||||||
|
splitNumber: 10, // 刻度数量 |
||||||
|
min: 0, // 最小刻度 |
||||||
|
max: dataX, // 最大刻度 |
||||||
|
// 仪表盘轴线相关配置 |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: [ |
||||||
|
[ |
||||||
|
1, |
||||||
|
{ |
||||||
|
type: "radial", |
||||||
|
x: 0.5, |
||||||
|
y: 0.59, |
||||||
|
r: 0.6, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0.72, |
||||||
|
color: "#032046", |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 0.94, |
||||||
|
color: "#086989", |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 0.98, |
||||||
|
color: "#0FAFCB", |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "#0EA4C1", |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
], |
||||||
|
width: 1000, |
||||||
|
}, |
||||||
|
}, |
||||||
|
// 分隔线 |
||||||
|
splitLine: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
// 刻度线 |
||||||
|
axisTick: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
// 刻度标签 |
||||||
|
axisLabel: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
// 仪表盘指针 |
||||||
|
pointer: { |
||||||
|
show: true, |
||||||
|
length: "95%", |
||||||
|
width: 5, // 指针粗细 |
||||||
|
}, |
||||||
|
// 仪表盘指针样式 |
||||||
|
itemStyle: { |
||||||
|
color: "#01eaf8", |
||||||
|
}, |
||||||
|
data: [ |
||||||
|
{ |
||||||
|
value: dataArr, |
||||||
|
}, |
||||||
|
], |
||||||
|
detail: { |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
}, |
||||||
|
|
||||||
|
// 中间半圆装饰 |
||||||
|
{ |
||||||
|
type: "gauge", |
||||||
|
radius: "110%", // 大小 |
||||||
|
center: ["50%", "127%"], |
||||||
|
axisLine: { |
||||||
|
show: true, |
||||||
|
lineStyle: { |
||||||
|
// 轴线样式 |
||||||
|
width: 4, // 宽度 |
||||||
|
color: [ |
||||||
|
[ |
||||||
|
1, |
||||||
|
{ |
||||||
|
type: "radial", |
||||||
|
x: 0.5, |
||||||
|
y: 0, |
||||||
|
r: 0.6, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "#00f3f9", // 0% 处的颜色 |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "#000", // 100% 处的颜色 |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
], |
||||||
|
}, |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
// 刻度 |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
// 分割线 |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
// 刻度标签 |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
pointer: { |
||||||
|
// 仪表盘指针 |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
detail: { |
||||||
|
// 仪表盘详情 |
||||||
|
show: false, |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}; |
||||||
|
//把配置项给实例对象 |
||||||
|
this.chartInstance.setOption(this.option, true); |
||||||
|
}, |
||||||
|
screenAdapter() { |
||||||
|
const titleFontSize = this.$refs.sys_charts.offsetWidth / 18; |
||||||
|
const adapterOption = {}; |
||||||
|
this.chartInstance.setOption(adapterOption); |
||||||
|
this.chartInstance.resize(); |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.sys_charts { |
||||||
|
width: 2rem; |
||||||
|
height: 2rem; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,416 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class="historyCharts" ref="chart_ref"></div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import * as echarts from "echarts"; |
||||||
|
export default { |
||||||
|
props: { |
||||||
|
temArray: { |
||||||
|
type: Array, |
||||||
|
default: () => [], |
||||||
|
}, |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
chartInstance: null, |
||||||
|
option: {}, |
||||||
|
chartData1: [], |
||||||
|
chartData2: [], |
||||||
|
chartData3: [], |
||||||
|
chartData4: [], |
||||||
|
bottomData: [], |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
temArray: { |
||||||
|
immediate: true, // 页面加载时立即触发一次监听 |
||||||
|
handler(newVal, oldVal) { |
||||||
|
if (newVal) { |
||||||
|
this.chartData1 = []; // 清空 chartData1 |
||||||
|
this.chartData2 = []; // 清空 chartData2 |
||||||
|
this.bottomData = []; // 清空 bottomData |
||||||
|
console.log("charts传值", newVal); |
||||||
|
let data = newVal; |
||||||
|
if (data.length > 0) { |
||||||
|
// 获取 title 和 titleStr 数组 |
||||||
|
const title = data.data[0].title; |
||||||
|
const titleStr = data.data[1].titleStr; |
||||||
|
// 获取 dataList 数组 |
||||||
|
const dataList = data.data[3].dataList; |
||||||
|
|
||||||
|
// 遍历 dataList 数组 |
||||||
|
dataList.forEach((item) => { |
||||||
|
// 查找 name 在 title 数组中的索引 |
||||||
|
const index = title.indexOf(item.name); |
||||||
|
if (index !== -1) { |
||||||
|
// 若找到匹配项,则将 name 替换为 titleStr 中对应位置的值 |
||||||
|
item.name = titleStr[index]; |
||||||
|
} |
||||||
|
}); |
||||||
|
console.log("处理后的data", data); |
||||||
|
data.forEach((item) => { |
||||||
|
if (item.timeStr) { |
||||||
|
this.bottomData = item.timeStr; |
||||||
|
} |
||||||
|
if (item.dataList) { |
||||||
|
let name1 = ""; |
||||||
|
let name2 = ""; |
||||||
|
let name3 = ""; |
||||||
|
let name4 = ""; |
||||||
|
item.dataList.forEach((val, index) => { |
||||||
|
if (val.name) { |
||||||
|
switch (index) { |
||||||
|
case 0: |
||||||
|
this.chartData1 = val.value; |
||||||
|
name1 = val.name; |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
this.chartData2 = val.value; |
||||||
|
name2 = val.name; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
this.chartData3 = val.value; |
||||||
|
name3 = val.name; |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
this.chartData4 = val.value; |
||||||
|
name4 = val.name; |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
this.$nextTick(() => { |
||||||
|
const adapterOption = { |
||||||
|
xAxis: { |
||||||
|
data: this.bottomData, |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
name:name1, |
||||||
|
data: this.chartData1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
name:name2, |
||||||
|
data: this.chartData2, |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
name:name3, |
||||||
|
data: this.chartData3, |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
name:name4, |
||||||
|
data: this.chartData4, |
||||||
|
}, |
||||||
|
], |
||||||
|
}; |
||||||
|
this.chartInstance.setOption(adapterOption); |
||||||
|
//手动的调用图标对象的resize才能产生效果 |
||||||
|
this.chartInstance.resize(); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.$nextTick(() => { |
||||||
|
const adapterOption = { |
||||||
|
xAxis: { |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
{ |
||||||
|
yAxisIndex: 0, |
||||||
|
data: [], |
||||||
|
}, |
||||||
|
], |
||||||
|
}; |
||||||
|
this.chartInstance.setOption(adapterOption); |
||||||
|
//手动的调用图标对象的resize才能产生效果 |
||||||
|
this.chartInstance.resize(); |
||||||
|
this.screenAdapter(); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.initChart(); |
||||||
|
this.screenAdapter(); |
||||||
|
}, |
||||||
|
destroyed() { |
||||||
|
//取消监听器 |
||||||
|
window.removeEventListener("resize", this.screenAdapter); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 折线图自适应+ 根据按钮切换图例仅限一条且不可点击+ 折线图数据 |
||||||
|
screenAdapter() { |
||||||
|
//自己定义的比较合适的适配大小,2.6 mes_ref是图表盒子 |
||||||
|
const titleFontSize = this.$refs.chart_ref.offsetWidth / 130; |
||||||
|
//因为option可以多次配置的,所以这里的option只需要写 需要配置大小的相关数据 |
||||||
|
const adapterOption = {}; |
||||||
|
//记得重新给配置项给实例对象。只要实例对象.chartInstance不变,option就可以多次配置不同的条件。也可以配置一个dataoption只写需要从后台请求的数据相关 |
||||||
|
this.chartInstance.setOption(adapterOption); |
||||||
|
//手动的调用图标对象的resize才能产生效果 |
||||||
|
this.chartInstance.resize(); |
||||||
|
}, |
||||||
|
//初始化chartInstance对象 |
||||||
|
initChart() { |
||||||
|
const chartRef = this.$refs.chart_ref; |
||||||
|
if (chartRef) { |
||||||
|
// 初始化图表的代码 |
||||||
|
this.chartInstance = echarts.init(this.$refs.chart_ref); |
||||||
|
this.option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "axis", |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
show: true, |
||||||
|
top: 0, |
||||||
|
textStyle: { |
||||||
|
color: "white", |
||||||
|
}, |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
top: "10%", |
||||||
|
left: "4%", |
||||||
|
right: "6%", |
||||||
|
bottom: "3%", |
||||||
|
containLabel: true, |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
//设置为true代表离零刻度间隔一段距离 |
||||||
|
boundaryGap: true, |
||||||
|
// 修饰刻度标签的颜色即x坐标数据 |
||||||
|
axisLabel: { |
||||||
|
// interval: 0, //强制显示所有x轴数据 |
||||||
|
// rotate: 30, //x轴坐标字体倾斜30度 |
||||||
|
color: "rgba(255, 255, 255, 1)", |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false, // 不显示坐标轴刻度线 |
||||||
|
}, |
||||||
|
// x坐标轴的颜色 |
||||||
|
axisLine: { |
||||||
|
show: true, |
||||||
|
lineStyle: { |
||||||
|
color: "#365576", |
||||||
|
}, |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#e2e6f0", |
||||||
|
}, |
||||||
|
}, //x轴分割线 |
||||||
|
data: this.bottomData, |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
min: 0, |
||||||
|
// max:20, |
||||||
|
// // // min:'dataMin', |
||||||
|
// // // max:'dataMax', |
||||||
|
// name: "kwh", // 第一个 y 轴的单位描述 |
||||||
|
// 设置 name 的样式 |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 1)", |
||||||
|
fontSize: 12, |
||||||
|
}, |
||||||
|
miniInterval: 5, |
||||||
|
type: "value", |
||||||
|
// 修饰刻度标签的颜色即y坐标数据 |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 1)", |
||||||
|
}, |
||||||
|
// 显示y坐标轴 |
||||||
|
axisLine: { |
||||||
|
show: true, |
||||||
|
lineStyle: { |
||||||
|
color: "#365576", // 设置 y 轴线的颜色 |
||||||
|
}, |
||||||
|
}, |
||||||
|
//y轴分割线段数 |
||||||
|
// splitNumber: 10, |
||||||
|
// 修改y轴分割线的颜色 |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", // 设置分割线的颜色 |
||||||
|
type: "dashed", // 设置分割线为虚线 |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
type: "line", |
||||||
|
// 拐点大小 |
||||||
|
symbolSize: 8, |
||||||
|
data: this.chartData1, |
||||||
|
//折线颜色 |
||||||
|
itemStyle: { |
||||||
|
color: "#1a69f1", //折线点的颜色 |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#1a69f1", //折线点的颜色 |
||||||
|
}, |
||||||
|
smooth: false, |
||||||
|
// 不显示折线点 |
||||||
|
showSymbol: false, |
||||||
|
// 区域填充样式,添加渐变背景 |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(26, 105, 241, 0.5)", // 渐变起始颜色 |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(26, 105, 241, 0)", // 渐变结束颜色 |
||||||
|
}, |
||||||
|
], |
||||||
|
global: false, // 缺省为 false |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "line", |
||||||
|
// 拐点大小 |
||||||
|
symbolSize: 8, |
||||||
|
data: this.chartData2, |
||||||
|
//折线颜色 |
||||||
|
itemStyle: { |
||||||
|
color: "#00CED1", //折线的颜色 |
||||||
|
}, |
||||||
|
smooth: false, |
||||||
|
// 不显示折线点 |
||||||
|
showSymbol: false, |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(0, 206, 209, 0.5)", // 渐变起始颜色 |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(0, 206, 209, 0)", // 渐变结束颜色 |
||||||
|
}, |
||||||
|
], |
||||||
|
global: false, // 缺省为 false |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "line", |
||||||
|
// 拐点大小 |
||||||
|
symbolSize: 8, |
||||||
|
data: this.chartData3, |
||||||
|
//折线颜色 |
||||||
|
itemStyle: { |
||||||
|
color: "#00CED1", //折线的颜色 |
||||||
|
}, |
||||||
|
smooth: false, |
||||||
|
// 不显示折线点 |
||||||
|
showSymbol: false, |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(0, 206, 209, 0.5)", // 渐变起始颜色 |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(0, 206, 209, 0)", // 渐变结束颜色 |
||||||
|
}, |
||||||
|
], |
||||||
|
global: false, // 缺省为 false |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "line", |
||||||
|
// 拐点大小 |
||||||
|
symbolSize: 8, |
||||||
|
data: this.chartData4, |
||||||
|
//折线颜色 |
||||||
|
itemStyle: { |
||||||
|
color: "#00CED1", //折线的颜色 |
||||||
|
}, |
||||||
|
smooth: false, |
||||||
|
// 不显示折线点 |
||||||
|
showSymbol: false, |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(0, 206, 209, 0.5)", // 渐变起始颜色 |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(0, 206, 209, 0)", // 渐变结束颜色 |
||||||
|
}, |
||||||
|
], |
||||||
|
global: false, // 缺省为 false |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}; |
||||||
|
//把配置项给实例对象 |
||||||
|
this.chartInstance.setOption(this.option, true); |
||||||
|
} else { |
||||||
|
console.error("未找到有效的 DOM 元素"); |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.historyCharts { |
||||||
|
width: 100%; |
||||||
|
height:3rem; |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
@ -0,0 +1,15 @@ |
|||||||
|
<template> |
||||||
|
<div class="title-img"> |
||||||
|
<img src="../../../../assets/images/big.png" class="img1" alt="" /> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<style lang="scss" scoped> |
||||||
|
.title-img { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.img1 { |
||||||
|
width: 0.8rem; |
||||||
|
height: 0.5rem; |
||||||
|
z-index: 10; |
||||||
|
} |
||||||
|
</style> |
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,20 @@ |
|||||||
|
<template> |
||||||
|
<div></div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
created() { |
||||||
|
this.toPage(); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
toPage() { |
||||||
|
console.log("需要跳转的") |
||||||
|
// 跳转到高校导航大屏展示 |
||||||
|
this.$router.push("/monitorCenter") |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style></style> |
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,736 @@ |
|||||||
|
<template> |
||||||
|
<div class="monitor" v-loading="loading"> |
||||||
|
<div class="monitor-top"> |
||||||
|
<img |
||||||
|
class="title-left" |
||||||
|
src="../../../assets/images/title-left.png" |
||||||
|
alt="" |
||||||
|
/> |
||||||
|
<img |
||||||
|
class="title-center" |
||||||
|
src="../../../assets/images/title-center.png" |
||||||
|
@click="goSys" |
||||||
|
alt="" |
||||||
|
/> |
||||||
|
<img |
||||||
|
class="title-right" |
||||||
|
src="../../../assets/images/title-right.png" |
||||||
|
alt="" |
||||||
|
/> |
||||||
|
<div class="sys-title" @click="goSys">铭汉高效冷源站管理系统</div> |
||||||
|
<!-- logo --> |
||||||
|
<img src="../../../assets/images/logo-3.png" class="sys-logo" alt="" /> |
||||||
|
<div class="nowTime">{{ formattedDate }}</div> |
||||||
|
<div class="monitor-time">已监测时长:{{ dayData }}天</div> |
||||||
|
<img |
||||||
|
class="icon_warning" |
||||||
|
src="../../../assets/images/warning.png" |
||||||
|
title="报警记录" |
||||||
|
@click="goWarning" |
||||||
|
v-if="isShowWarning" |
||||||
|
alt="" |
||||||
|
/> |
||||||
|
<img |
||||||
|
class="icon_home" |
||||||
|
src="../../../assets/images/icon_home.png" |
||||||
|
title="首页" |
||||||
|
@click="goSys" |
||||||
|
alt="" |
||||||
|
/> |
||||||
|
<img |
||||||
|
class="back-icon" |
||||||
|
src="../../../assets/images/back-icon.png" |
||||||
|
title="返回" |
||||||
|
@click="goBack" |
||||||
|
alt="" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div class="host-detail"> |
||||||
|
<div class="detail-top"> |
||||||
|
<div class="detail-top-left"> |
||||||
|
<div class="host-li"> |
||||||
|
<img |
||||||
|
class="host-img" |
||||||
|
src="../../../assets/images/host-img4.png" |
||||||
|
alt="" |
||||||
|
/> |
||||||
|
<div class="host-name">1号螺旋机</div> |
||||||
|
<div class="detail-data hostparams"> |
||||||
|
<div class="detail-data-top"> |
||||||
|
<title-img></title-img> |
||||||
|
<div class="details-title">冷机性能</div> |
||||||
|
<title-img></title-img> |
||||||
|
</div> |
||||||
|
<div class="detail-data-bottom"> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>实时EER:</span> |
||||||
|
<span class="dotData">10.365</span> |
||||||
|
<span class="dotUnit">kw/kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>实时功率:</span> |
||||||
|
<span class="dotData">126</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>实时冷量:</span> |
||||||
|
<span class="dotData">1306</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li year-data"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>全年EER:</span> |
||||||
|
<span class="dotData">0.000</span> |
||||||
|
<span class="dotUnit">kw/kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>全年用电:</span> |
||||||
|
<span class="dotData">64098</span> |
||||||
|
<span class="dotUnit">kw/H</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>全年供电:</span> |
||||||
|
<span class="dotData">101365</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="host-li"> |
||||||
|
<img |
||||||
|
class="host-img" |
||||||
|
src="../../../assets/images/host-img4.png" |
||||||
|
alt="" |
||||||
|
/> |
||||||
|
<div class="host-name">2号螺旋机</div> |
||||||
|
<div class="detail-data hostparams"> |
||||||
|
<div class="detail-data-top"> |
||||||
|
<title-img></title-img> |
||||||
|
<div class="details-title">冷机性能</div> |
||||||
|
<title-img></title-img> |
||||||
|
</div> |
||||||
|
<div class="detail-data-bottom"> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>实时EER:</span> |
||||||
|
<span class="dotData">10.365</span> |
||||||
|
<span class="dotUnit">kw/kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>实时功率:</span> |
||||||
|
<span class="dotData">126</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>实时冷量:</span> |
||||||
|
<span class="dotData">1306</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li year-data"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>全年EER:</span> |
||||||
|
<span class="dotData">0.000</span> |
||||||
|
<span class="dotUnit">kw/kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>全年用电:</span> |
||||||
|
<span class="dotData">64098</span> |
||||||
|
<span class="dotUnit">kw/H</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>全年供电:</span> |
||||||
|
<span class="dotData">101365</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="host-li"> |
||||||
|
<img |
||||||
|
class="host-img" |
||||||
|
src="../../../assets/images/host-img3.png" |
||||||
|
alt="" |
||||||
|
/> |
||||||
|
<div class="host-name">3号磁悬浮机</div> |
||||||
|
<div class="detail-data hostparams"> |
||||||
|
<div class="detail-data-top"> |
||||||
|
<title-img></title-img> |
||||||
|
<div class="details-title">冷机性能</div> |
||||||
|
<title-img></title-img> |
||||||
|
</div> |
||||||
|
<div class="detail-data-bottom"> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>实时EER:</span> |
||||||
|
<span class="dotData">10.365</span> |
||||||
|
<span class="dotUnit">kw/kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>实时功率:</span> |
||||||
|
<span class="dotData">126</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>实时冷量:</span> |
||||||
|
<span class="dotData">1306</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li year-data"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>全年EER:</span> |
||||||
|
<span class="dotData">0.000</span> |
||||||
|
<span class="dotUnit">kw/kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>全年用电:</span> |
||||||
|
<span class="dotData">64098</span> |
||||||
|
<span class="dotUnit">kw/H</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>全年供电:</span> |
||||||
|
<span class="dotData">101365</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-top-right"> |
||||||
|
<div class="detail-data hostparams"> |
||||||
|
<div class="detail-data-top"> |
||||||
|
<title-img></title-img> |
||||||
|
<div class="details-title">系统性能</div> |
||||||
|
<title-img></title-img> |
||||||
|
</div> |
||||||
|
<div class="detail-data-bottom"> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>今日EER:</span> |
||||||
|
<span class="dotData">6.531</span> |
||||||
|
<span class="dotUnit">kw/kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>今日用电:</span> |
||||||
|
<span class="dotData">367</span> |
||||||
|
<span class="dotUnit">kw/H</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>今日供冷:</span> |
||||||
|
<span class="dotData">2397</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li year-data"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>当月EER:</span> |
||||||
|
<span class="dotData">6.131</span> |
||||||
|
<span class="dotUnit">kw/kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>今月用电:</span> |
||||||
|
<span class="dotData">27840</span> |
||||||
|
<span class="dotUnit">kw/H</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>当月供冷:</span> |
||||||
|
<span class="dotData">172069</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li year-data"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>当年EER:</span> |
||||||
|
<span class="dotData">6.531</span> |
||||||
|
<span class="dotUnit">kw/kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>当年用电:</span> |
||||||
|
<span class="dotData">105771</span> |
||||||
|
<span class="dotUnit">kw/H</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span>当年供冷:</span> |
||||||
|
<span class="dotData">744519</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li year-data"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span class="dotTitle">累计EER:</span> |
||||||
|
<span class="dotData">5.531</span> |
||||||
|
<span class="dotUnit">kw/kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span class="dotTitle">累计用电:</span> |
||||||
|
<span class="dotData">1096628</span> |
||||||
|
<span class="dotUnit">kw/H</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-data-li"> |
||||||
|
<div class="rightDot"> |
||||||
|
<div class="leftDot"> |
||||||
|
<span class="dotTitle">累计供冷:</span> |
||||||
|
<span class="dotData">6107983</span> |
||||||
|
<span class="dotUnit">kw</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="detail-bottom"> |
||||||
|
<performance-chart :temArray="temArray"></performance-chart> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { |
||||||
|
hostDetailsData, |
||||||
|
hostTemData, |
||||||
|
runTime, |
||||||
|
} from "@/api/centerairC/sysMonitor"; |
||||||
|
import { alarmRecordList } from "@/api/alarm/alarmRecord"; |
||||||
|
import titleImg from "./components/titleImg.vue"; |
||||||
|
import { format } from "@/utils/datetime"; |
||||||
|
import PerformanceChart from "./components/performanceChart.vue"; |
||||||
|
export default { |
||||||
|
name: "sysControl", |
||||||
|
components: { titleImg, PerformanceChart }, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
loading: false, |
||||||
|
|
||||||
|
currentDate: new Date(), |
||||||
|
nowTimer: null, |
||||||
|
deviceName: "", //主机名称 |
||||||
|
hostData: [], //冷机性能 |
||||||
|
rightHostData: [], //右 |
||||||
|
automaticObj: {}, //手自动状态 |
||||||
|
localObj: {}, //本地远程状态 |
||||||
|
badObj: {}, //故障状态 |
||||||
|
timeObj: {}, //累计运行时间 |
||||||
|
compressorData: [], //压缩机参数 |
||||||
|
temArray: [], //冷冻冷却水温度 |
||||||
|
isMagnetic: false, |
||||||
|
isShowWarning: false, //是否有报警 |
||||||
|
dayData: "", //监测天数 |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
formattedDate() { |
||||||
|
const year = this.currentDate.getFullYear(); |
||||||
|
const month = String(this.currentDate.getMonth() + 1).padStart(2, "0"); |
||||||
|
const day = String(this.currentDate.getDate()).padStart(2, "0"); |
||||||
|
const hours = String(this.currentDate.getHours()).padStart(2, "0"); |
||||||
|
const minutes = String(this.currentDate.getMinutes()).padStart(2, "0"); |
||||||
|
const seconds = String(this.currentDate.getSeconds()).padStart(2, "0"); |
||||||
|
const weekDays = [ |
||||||
|
"星期日", |
||||||
|
"星期一", |
||||||
|
"星期二", |
||||||
|
"星期三", |
||||||
|
"星期四", |
||||||
|
"星期五", |
||||||
|
"星期六", |
||||||
|
]; |
||||||
|
const weekDay = weekDays[this.currentDate.getDay()]; |
||||||
|
return `${year}年${month}月${day}日 ${hours}:${minutes}:${seconds} ${weekDay}`; |
||||||
|
}, |
||||||
|
}, |
||||||
|
created() {}, |
||||||
|
mounted() { |
||||||
|
this.getHostDetailsData(); |
||||||
|
this.getDayData(); |
||||||
|
// 在组件挂载后尝试进入全屏 |
||||||
|
setTimeout(() => { |
||||||
|
this.requestFullscreen(); |
||||||
|
}, 100); // 延迟 100 毫秒执行全屏操作 |
||||||
|
}, |
||||||
|
beforeDestroy() { |
||||||
|
// 组件销毁前清除定时器 |
||||||
|
if (this.nowTimer) { |
||||||
|
clearInterval(this.nowTimer); |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 全屏操作 |
||||||
|
requestFullscreen() { |
||||||
|
const element = document.documentElement; |
||||||
|
console.log("全屏了吗"); |
||||||
|
if (element.requestFullscreen) { |
||||||
|
element.requestFullscreen(); |
||||||
|
} else if (element.mozRequestFullScreen) { |
||||||
|
// Firefox |
||||||
|
element.mozRequestFullScreen(); |
||||||
|
} else if (element.webkitRequestFullscreen) { |
||||||
|
// Chrome, Safari and Opera |
||||||
|
element.webkitRequestFullscreen(); |
||||||
|
} else if (element.msRequestFullscreen) { |
||||||
|
// IE/Edge |
||||||
|
element.msRequestFullscreen(); |
||||||
|
} |
||||||
|
}, |
||||||
|
// 退出全屏 |
||||||
|
exitFullscreen() { |
||||||
|
if (document.exitFullscreen) { |
||||||
|
document.exitFullscreen(); |
||||||
|
} else if (document.mozCancelFullScreen) { |
||||||
|
// Firefox |
||||||
|
document.mozCancelFullScreen(); |
||||||
|
} else if (document.webkitExitFullscreen) { |
||||||
|
// Chrome, Safari and Opera |
||||||
|
document.webkitExitFullscreen(); |
||||||
|
} else if (document.msExitFullscreen) { |
||||||
|
// IE/Edge |
||||||
|
document.msExitFullscreen(); |
||||||
|
} |
||||||
|
}, |
||||||
|
// 进入系统首页 |
||||||
|
goSys() { |
||||||
|
// this.exitFullscreen(); |
||||||
|
this.$router.push("/"); |
||||||
|
}, |
||||||
|
// 返回上一页 |
||||||
|
goBack() { |
||||||
|
this.$router.back(); |
||||||
|
}, |
||||||
|
getHostDetailsData() { |
||||||
|
// 请求数据 |
||||||
|
// this.getHostParams(deviceLedgerId); |
||||||
|
}, |
||||||
|
// 监测天数 |
||||||
|
getDayData() { |
||||||
|
runTime().then((res) => { |
||||||
|
if (res.code == 200) { |
||||||
|
this.dayData = res.data.runTime; |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
// 报警列表 |
||||||
|
getAlarnStatus() { |
||||||
|
let data = { |
||||||
|
pageNum: 1, |
||||||
|
pageSize: 10, |
||||||
|
status: "0", |
||||||
|
}; |
||||||
|
let timeArr = [getDay(0), getDay(0)]; |
||||||
|
alarmRecordList(this.addDateRange(data, timeArr)).then((res) => { |
||||||
|
if (res.code == 200 && res.rows.length > 0) { |
||||||
|
this.isShowWarning = true; |
||||||
|
} else { |
||||||
|
this.isShowWarning = false; |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
goWarning() { |
||||||
|
// this.exitFullscreen(); |
||||||
|
this.$router.push("/alarm/alarmRecord"); |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.monitor { |
||||||
|
width: 100%; |
||||||
|
min-height: 100vh; |
||||||
|
height: auto; |
||||||
|
background-color: black; |
||||||
|
color: #fff; |
||||||
|
.monitor-top { |
||||||
|
width: 100%; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: space-between; |
||||||
|
flex-wrap: nowrap; |
||||||
|
padding: 0.1rem 0.2rem; |
||||||
|
position: relative; |
||||||
|
.title-left { |
||||||
|
width: 3.41rem; |
||||||
|
height: 0.8rem; |
||||||
|
} |
||||||
|
.title-center { |
||||||
|
width: 9.46rem; |
||||||
|
height: 0.8rem; |
||||||
|
} |
||||||
|
.title-right { |
||||||
|
width: 5.04rem; |
||||||
|
height: 0.78rem; |
||||||
|
} |
||||||
|
.sys-title { |
||||||
|
position: absolute; |
||||||
|
top: 40%; |
||||||
|
left: 50%; |
||||||
|
transform: translate(-50%, -50%); |
||||||
|
font-size: 0.28rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
z-index: 100; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.nowTime { |
||||||
|
position: absolute; |
||||||
|
top: 0.37rem; |
||||||
|
right: 0.6rem; |
||||||
|
font-size: 0.18rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
z-index: 100; |
||||||
|
} |
||||||
|
.sys-logo { |
||||||
|
width: 1.8rem; |
||||||
|
height: 0.5rem; |
||||||
|
position: absolute; |
||||||
|
top: 0.26rem; |
||||||
|
left: 0.8rem; |
||||||
|
z-index: 10; |
||||||
|
} |
||||||
|
.monitor-time { |
||||||
|
position: absolute; |
||||||
|
top: 0.44rem; |
||||||
|
left: 4.2rem; |
||||||
|
z-index: 10; |
||||||
|
font-size: 0.18rem; |
||||||
|
color: #ffffff; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
.icon_warning { |
||||||
|
position: absolute; |
||||||
|
top: 0.39rem; |
||||||
|
right: 4.4rem; |
||||||
|
z-index: 10; |
||||||
|
width: 0.35rem; |
||||||
|
height: 0.32rem; |
||||||
|
margin: 0 0.25rem 0 0.27rem; |
||||||
|
cursor: pointer; |
||||||
|
/* 添加闪烁动画 */ |
||||||
|
animation: blink 1s infinite; |
||||||
|
} |
||||||
|
@keyframes blink { |
||||||
|
100% { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
50% { |
||||||
|
opacity: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
.icon_home { |
||||||
|
position: absolute; |
||||||
|
top: 0.39rem; |
||||||
|
right: 4rem; |
||||||
|
z-index: 10; |
||||||
|
width: 0.35rem; |
||||||
|
height: 0.32rem; |
||||||
|
margin: 0 0.2rem 0 0.27rem; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.back-icon { |
||||||
|
position: absolute; |
||||||
|
top: 0.39rem; |
||||||
|
right: 3.7rem; |
||||||
|
z-index: 10; |
||||||
|
width: 0.35rem; |
||||||
|
height: 0.32rem; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
.host-detail { |
||||||
|
padding: 0.2rem; |
||||||
|
width: 100%; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
.detail-top { |
||||||
|
width: 100%; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
.detail-top-left { |
||||||
|
width: 14rem; |
||||||
|
// background-color: aquamarine; |
||||||
|
position: relative; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: flex-start; |
||||||
|
.host-li { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
margin-left: 0.3rem; |
||||||
|
position: relative; |
||||||
|
.host-img { |
||||||
|
width: 3.5rem; |
||||||
|
height: 2.6rem; |
||||||
|
margin-bottom: 0.1rem; |
||||||
|
} |
||||||
|
.host-name { |
||||||
|
position: absolute; |
||||||
|
top: 0.8rem; |
||||||
|
left: 1.6rem; |
||||||
|
color: #3520f8; |
||||||
|
font-size: 0.18rem; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.detail-top-right { |
||||||
|
width: calc(100% - 14rem); |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.detail-data { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
width: 4.5rem; |
||||||
|
position: relative; |
||||||
|
.detail-data-top { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
color: #c0dffc; |
||||||
|
font-weight: bold; |
||||||
|
font-size: 0.18rem; |
||||||
|
width: 100%; |
||||||
|
text-align: center; |
||||||
|
z-index: 10; |
||||||
|
.details-title { |
||||||
|
margin: 0 0.15rem; |
||||||
|
} |
||||||
|
} |
||||||
|
.detail-data-bottom { |
||||||
|
width: 100%; |
||||||
|
padding: 0rem 0.3rem; |
||||||
|
z-index: 0; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
flex-wrap: wrap; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
.line1 { |
||||||
|
position: absolute; |
||||||
|
top: 0.53rem; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.detail-bottom { |
||||||
|
// margin: 0.3rem 0.5rem 0 0.5rem; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
justify-content: space-between; |
||||||
|
height: 3rem; |
||||||
|
// background-color: #217df5; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,765 @@ |
|||||||
|
<template> |
||||||
|
<div class="app-container"> |
||||||
|
<!-- 关键指标统计 --> |
||||||
|
<div class="special-div"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">关键指标统计</div> |
||||||
|
<div class="time-tabs"> |
||||||
|
<div |
||||||
|
v-for="(tab, index) in deviceTimeTabs" |
||||||
|
:key="index" |
||||||
|
:class="['time-tab', { active: activeDeviceTab === index }]" |
||||||
|
@click="handleDeviceTabChange(index)" |
||||||
|
> |
||||||
|
{{ tab }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="device-indicators"> |
||||||
|
<div class="indicator-card" v-for="device in deviceIndicators" :key="device.name"> |
||||||
|
<div class="indicator-header" :style="{ background: device.bg }"> |
||||||
|
<div class="indicator-icon"> |
||||||
|
<img :src="device.icon" :alt="device.name" /> |
||||||
|
</div> |
||||||
|
<div class="indicator-name">{{ device.name }}</div> |
||||||
|
</div> |
||||||
|
<div class="indicator-content"> |
||||||
|
<div class="indicator-value">{{ device.total }}</div> |
||||||
|
<div class="indicator-label">总设备数</div> |
||||||
|
</div> |
||||||
|
<div class="indicator-footer"> |
||||||
|
<div class="footer-item"> |
||||||
|
<span class="footer-label">在线:</span> |
||||||
|
<span class="footer-value online">{{ device.online }}</span> |
||||||
|
</div> |
||||||
|
<div class="footer-item"> |
||||||
|
<span class="footer-label">离线:</span> |
||||||
|
<span class="footer-value offline">{{ device.offline }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 设备在线数量趋势 --> |
||||||
|
<div class="special-div"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">全系统设备在线数量趋势</div> |
||||||
|
<div class="time-tabs"> |
||||||
|
<div |
||||||
|
v-for="(tab, index) in trendTimeTabs" |
||||||
|
:key="index" |
||||||
|
:class="['time-tab', { active: activeTrendTab === index }]" |
||||||
|
@click="handleTrendTabChange(index)" |
||||||
|
> |
||||||
|
{{ tab }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="trend-chart" ref="deviceTrendChartRef"></div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 网关在线数量趋势 --> |
||||||
|
<div class="special-div"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">网关在线数量趋势</div> |
||||||
|
<div class="time-tabs"> |
||||||
|
<div |
||||||
|
v-for="(tab, index) in gatewayTimeTabs" |
||||||
|
:key="index" |
||||||
|
:class="['time-tab', { active: activeGatewayTab === index }]" |
||||||
|
@click="handleGatewayTabChange(index)" |
||||||
|
> |
||||||
|
{{ tab }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="trend-chart" ref="gatewayTrendChartRef"></div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 设备状态概览 --> |
||||||
|
<div class="special-div"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">设备状态概览</div> |
||||||
|
</div> |
||||||
|
<div class="status-overview"> |
||||||
|
<div class="status-card"> |
||||||
|
<div class="status-icon online"></div> |
||||||
|
<div class="status-info"> |
||||||
|
<div class="status-value">{{ overview.online }}</div> |
||||||
|
<div class="status-label">在线设备</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="status-card"> |
||||||
|
<div class="status-icon offline"></div> |
||||||
|
<div class="status-info"> |
||||||
|
<div class="status-value">{{ overview.offline }}</div> |
||||||
|
<div class="status-label">离线设备</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="status-card"> |
||||||
|
<div class="status-icon warning"></div> |
||||||
|
<div class="status-info"> |
||||||
|
<div class="status-value">{{ overview.warning }}</div> |
||||||
|
<div class="status-label">告警设备</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="status-card"> |
||||||
|
<div class="status-icon fault"></div> |
||||||
|
<div class="status-info"> |
||||||
|
<div class="status-value">{{ overview.fault }}</div> |
||||||
|
<div class="status-label">故障设备</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="status-pie-chart" ref="statusPieRef"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import * as echarts from "echarts"; |
||||||
|
|
||||||
|
export default { |
||||||
|
name: "SystemDevice", |
||||||
|
data() { |
||||||
|
return { |
||||||
|
// 设备统计时间选项 |
||||||
|
deviceTimeTabs: ["近七日", "当月", "当年"], |
||||||
|
activeDeviceTab: 0, |
||||||
|
// 趋势图时间选项 |
||||||
|
trendTimeTabs: ["近七日", "当月", "当年"], |
||||||
|
activeTrendTab: 0, |
||||||
|
gatewayTimeTabs: ["近七日", "当月", "当年"], |
||||||
|
activeGatewayTab: 0, |
||||||
|
// 设备关键指标数据 |
||||||
|
deviceIndicators: [ |
||||||
|
{ |
||||||
|
name: "照明系统", |
||||||
|
total: 1250, |
||||||
|
online: 1180, |
||||||
|
offline: 70, |
||||||
|
icon: "", |
||||||
|
bg: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "空调系统", |
||||||
|
total: 86, |
||||||
|
online: 78, |
||||||
|
offline: 8, |
||||||
|
icon: "", |
||||||
|
bg: "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "水泵系统", |
||||||
|
total: 156, |
||||||
|
online: 148, |
||||||
|
offline: 8, |
||||||
|
icon: "", |
||||||
|
bg: "linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "电梯系统", |
||||||
|
total: 24, |
||||||
|
online: 22, |
||||||
|
offline: 2, |
||||||
|
icon: "", |
||||||
|
bg: "linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "风机系统", |
||||||
|
total: 328, |
||||||
|
online: 305, |
||||||
|
offline: 23, |
||||||
|
icon: "", |
||||||
|
bg: "linear-gradient(135deg, #fa709a 0%, #fee140 100%)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "监控系统", |
||||||
|
total: 189, |
||||||
|
online: 175, |
||||||
|
offline: 14, |
||||||
|
icon: "", |
||||||
|
bg: "linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)" |
||||||
|
} |
||||||
|
], |
||||||
|
// 设备状态概览 |
||||||
|
overview: { |
||||||
|
online: 2008, |
||||||
|
offline: 125, |
||||||
|
warning: 32, |
||||||
|
fault: 15 |
||||||
|
}, |
||||||
|
// 图表实例 |
||||||
|
deviceTrendChart: null, |
||||||
|
gatewayTrendChart: null, |
||||||
|
statusPieChart: null |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.initDeviceTrendChart(); |
||||||
|
this.initGatewayTrendChart(); |
||||||
|
this.initStatusPieChart(); |
||||||
|
window.addEventListener("resize", this.handleResize); |
||||||
|
}, |
||||||
|
beforeDestroy() { |
||||||
|
window.removeEventListener("resize", this.handleResize); |
||||||
|
if (this.deviceTrendChart) this.deviceTrendChart.dispose(); |
||||||
|
if (this.gatewayTrendChart) this.gatewayTrendChart.dispose(); |
||||||
|
if (this.statusPieChart) this.statusPieChart.dispose(); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 设备统计时间切换 |
||||||
|
handleDeviceTabChange(index) { |
||||||
|
this.activeDeviceTab = index; |
||||||
|
// 这里可以添加根据时间切换更新数据的逻辑 |
||||||
|
}, |
||||||
|
// 设备趋势时间切换 |
||||||
|
handleTrendTabChange(index) { |
||||||
|
this.activeTrendTab = index; |
||||||
|
this.updateDeviceTrendChart(); |
||||||
|
}, |
||||||
|
// 网关趋势时间切换 |
||||||
|
handleGatewayTabChange(index) { |
||||||
|
this.activeGatewayTab = index; |
||||||
|
this.updateGatewayTrendChart(); |
||||||
|
}, |
||||||
|
// 初始化设备在线趋势图 |
||||||
|
initDeviceTrendChart() { |
||||||
|
this.deviceTrendChart = echarts.init(this.$refs.deviceTrendChartRef); |
||||||
|
this.updateDeviceTrendChart(); |
||||||
|
}, |
||||||
|
// 更新设备在线趋势图 |
||||||
|
updateDeviceTrendChart() { |
||||||
|
const dataMap = { |
||||||
|
0: { // 近七日 |
||||||
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
||||||
|
onlineData: [1985, 1990, 1988, 1995, 2000, 1992, 2008], |
||||||
|
offlineData: [148, 143, 145, 138, 133, 141, 125] |
||||||
|
}, |
||||||
|
1: { // 当月 |
||||||
|
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"], |
||||||
|
onlineData: [1950, 1965, 1980, 1975, 1990, 1998, 2008], |
||||||
|
offlineData: [183, 168, 153, 158, 143, 135, 125] |
||||||
|
}, |
||||||
|
2: { // 当年 |
||||||
|
xData: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"], |
||||||
|
onlineData: [1800, 1820, 1850, 1880, 1920, 1950, 1980, 1990, 2000, 2005, 2008, 2010], |
||||||
|
offlineData: [333, 313, 283, 253, 213, 183, 153, 143, 133, 128, 125, 123] |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const currentData = dataMap[this.activeTrendTab]; |
||||||
|
|
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "axis" |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
data: ["在线", "离线"], |
||||||
|
textStyle: { |
||||||
|
color: "#ffffff" |
||||||
|
} |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: "3%", |
||||||
|
right: "4%", |
||||||
|
bottom: "3%", |
||||||
|
containLabel: true |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
boundaryGap: false, |
||||||
|
data: currentData.xData, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
type: "value", |
||||||
|
name: "台", |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", |
||||||
|
type: "dashed" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "在线", |
||||||
|
type: "line", |
||||||
|
smooth: true, |
||||||
|
data: currentData.onlineData, |
||||||
|
itemStyle: { |
||||||
|
color: "#91CC75" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#91CC75" |
||||||
|
}, |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(145, 204, 117, 0.5)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(145, 204, 117, 0)" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "离线", |
||||||
|
type: "line", |
||||||
|
smooth: true, |
||||||
|
data: currentData.offlineData, |
||||||
|
itemStyle: { |
||||||
|
color: "#EE6666" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#EE6666" |
||||||
|
}, |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(238, 102, 102, 0.5)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(238, 102, 102, 0)" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.deviceTrendChart.setOption(option); |
||||||
|
}, |
||||||
|
// 初始化网关在线趋势图 |
||||||
|
initGatewayTrendChart() { |
||||||
|
this.gatewayTrendChart = echarts.init(this.$refs.gatewayTrendChartRef); |
||||||
|
this.updateGatewayTrendChart(); |
||||||
|
}, |
||||||
|
// 更新网关在线趋势图 |
||||||
|
updateGatewayTrendChart() { |
||||||
|
const dataMap = { |
||||||
|
0: { // 近七日 |
||||||
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
||||||
|
onlineData: [45, 46, 45, 47, 48, 47, 48], |
||||||
|
offlineData: [3, 2, 3, 1, 0, 1, 0] |
||||||
|
}, |
||||||
|
1: { // 当月 |
||||||
|
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"], |
||||||
|
onlineData: [42, 44, 45, 46, 46, 47, 48], |
||||||
|
offlineData: [6, 4, 3, 2, 2, 1, 0] |
||||||
|
}, |
||||||
|
2: { // 当年 |
||||||
|
xData: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"], |
||||||
|
onlineData: [40, 41, 42, 43, 44, 45, 46, 47, 47, 48, 48, 48], |
||||||
|
offlineData: [8, 7, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0] |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const currentData = dataMap[this.activeGatewayTab]; |
||||||
|
|
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "axis" |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
data: ["在线", "离线"], |
||||||
|
textStyle: { |
||||||
|
color: "#ffffff" |
||||||
|
} |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: "3%", |
||||||
|
right: "4%", |
||||||
|
bottom: "3%", |
||||||
|
containLabel: true |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
boundaryGap: false, |
||||||
|
data: currentData.xData, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
type: "value", |
||||||
|
name: "台", |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", |
||||||
|
type: "dashed" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "在线", |
||||||
|
type: "line", |
||||||
|
smooth: true, |
||||||
|
data: currentData.onlineData, |
||||||
|
itemStyle: { |
||||||
|
color: "#5470C6" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#5470C6" |
||||||
|
}, |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(84, 112, 198, 0.5)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(84, 112, 198, 0)" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "离线", |
||||||
|
type: "line", |
||||||
|
smooth: true, |
||||||
|
data: currentData.offlineData, |
||||||
|
itemStyle: { |
||||||
|
color: "#FAC858" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#FAC858" |
||||||
|
}, |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(250, 200, 88, 0.5)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(250, 200, 88, 0)" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.gatewayTrendChart.setOption(option); |
||||||
|
}, |
||||||
|
// 初始化状态饼图 |
||||||
|
initStatusPieChart() { |
||||||
|
this.statusPieChart = echarts.init(this.$refs.statusPieRef); |
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "item" |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
orient: "vertical", |
||||||
|
left: "left", |
||||||
|
textStyle: { |
||||||
|
color: "#ffffff" |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "设备状态", |
||||||
|
type: "pie", |
||||||
|
radius: "60%", |
||||||
|
center: ["60%", "50%"], |
||||||
|
data: [ |
||||||
|
{ value: 2008, name: "在线", itemStyle: { color: "#91CC75" } }, |
||||||
|
{ value: 125, name: "离线", itemStyle: { color: "#EE6666" } }, |
||||||
|
{ value: 32, name: "告警", itemStyle: { color: "#FAC858" } }, |
||||||
|
{ value: 15, name: "故障", itemStyle: { color: "#5470C6" } } |
||||||
|
], |
||||||
|
emphasis: { |
||||||
|
itemStyle: { |
||||||
|
shadowBlur: 10, |
||||||
|
shadowOffsetX: 0, |
||||||
|
shadowColor: "rgba(0, 0, 0, 0.5)" |
||||||
|
} |
||||||
|
}, |
||||||
|
label: { |
||||||
|
formatter: "{b}\n{d}%" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.statusPieChart.setOption(option); |
||||||
|
}, |
||||||
|
// 响应式调整 |
||||||
|
handleResize() { |
||||||
|
if (this.deviceTrendChart) this.deviceTrendChart.resize(); |
||||||
|
if (this.gatewayTrendChart) this.gatewayTrendChart.resize(); |
||||||
|
if (this.statusPieChart) this.statusPieChart.resize(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.time-tabs { |
||||||
|
display: flex; |
||||||
|
gap: 0.1rem; |
||||||
|
|
||||||
|
.time-tab { |
||||||
|
padding: 0.06rem 0.2rem; |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
cursor: pointer; |
||||||
|
border-radius: 0.04rem; |
||||||
|
transition: all 0.3s; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
&.active { |
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.device-indicators { |
||||||
|
display: flex; |
||||||
|
flex-wrap: wrap; |
||||||
|
padding: 0.3rem 0.2rem; |
||||||
|
gap: 0.2rem; |
||||||
|
|
||||||
|
.indicator-card { |
||||||
|
flex: 1; |
||||||
|
min-width: 2.5rem; |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
border-radius: 0.08rem; |
||||||
|
overflow: hidden; |
||||||
|
|
||||||
|
.indicator-header { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 0.15rem; |
||||||
|
color: #ffffff; |
||||||
|
|
||||||
|
.indicator-icon { |
||||||
|
width: 0.4rem; |
||||||
|
height: 0.4rem; |
||||||
|
border-radius: 50%; |
||||||
|
background: rgba(255, 255, 255, 0.2); |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
margin-right: 0.1rem; |
||||||
|
|
||||||
|
img { |
||||||
|
width: 0.24rem; |
||||||
|
height: 0.24rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.indicator-name { |
||||||
|
font-size: 0.16rem; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.indicator-content { |
||||||
|
padding: 0.2rem; |
||||||
|
text-align: center; |
||||||
|
|
||||||
|
.indicator-value { |
||||||
|
font-size: 0.36rem; |
||||||
|
color: #15e1fd; |
||||||
|
font-weight: bold; |
||||||
|
margin-bottom: 0.05rem; |
||||||
|
} |
||||||
|
|
||||||
|
.indicator-label { |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.6; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.indicator-footer { |
||||||
|
display: flex; |
||||||
|
justify-content: space-around; |
||||||
|
padding: 0.15rem 0.2rem; |
||||||
|
background: rgba(0, 0, 0, 0.1); |
||||||
|
|
||||||
|
.footer-item { |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
|
||||||
|
.footer-label { |
||||||
|
opacity: 0.7; |
||||||
|
} |
||||||
|
|
||||||
|
.footer-value { |
||||||
|
font-weight: bold; |
||||||
|
|
||||||
|
&.online { |
||||||
|
color: #91CC75; |
||||||
|
} |
||||||
|
|
||||||
|
&.offline { |
||||||
|
color: #EE6666; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.trend-chart { |
||||||
|
width: 100%; |
||||||
|
height: 3rem; |
||||||
|
padding: 0.2rem; |
||||||
|
} |
||||||
|
|
||||||
|
.status-overview { |
||||||
|
display: flex; |
||||||
|
justify-content: space-around; |
||||||
|
padding: 0.3rem 0.2rem; |
||||||
|
gap: 0.2rem; |
||||||
|
|
||||||
|
.status-card { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 0.2rem; |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
border-radius: 0.08rem; |
||||||
|
|
||||||
|
.status-icon { |
||||||
|
width: 0.08rem; |
||||||
|
height: 0.4rem; |
||||||
|
border-radius: 0.04rem; |
||||||
|
margin-right: 0.15rem; |
||||||
|
|
||||||
|
&.online { |
||||||
|
background: #91CC75; |
||||||
|
} |
||||||
|
|
||||||
|
&.offline { |
||||||
|
background: #EE6666; |
||||||
|
} |
||||||
|
|
||||||
|
&.warning { |
||||||
|
background: #FAC858; |
||||||
|
} |
||||||
|
|
||||||
|
&.fault { |
||||||
|
background: #5470C6; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.status-info { |
||||||
|
flex: 1; |
||||||
|
|
||||||
|
.status-value { |
||||||
|
font-size: 0.28rem; |
||||||
|
color: #15e1fd; |
||||||
|
font-weight: bold; |
||||||
|
margin-bottom: 0.05rem; |
||||||
|
} |
||||||
|
|
||||||
|
.status-label { |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.status-pie-chart { |
||||||
|
width: 100%; |
||||||
|
height: 3rem; |
||||||
|
padding: 0.2rem; |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 1485px) { |
||||||
|
.device-indicators { |
||||||
|
.indicator-card { |
||||||
|
min-width: 2rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.status-overview { |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,608 @@ |
|||||||
|
<template> |
||||||
|
<div class="app-container"> |
||||||
|
<!-- 项目整体用能/碳排放趋势 --> |
||||||
|
<div class="special-div"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">项目整体趋势</div> |
||||||
|
<div class="time-tabs"> |
||||||
|
<div |
||||||
|
v-for="(tab, index) in trendTimeTabs" |
||||||
|
:key="index" |
||||||
|
:class="['time-tab', { active: activeTrendTab === index }]" |
||||||
|
@click="handleTrendTabChange(index)" |
||||||
|
> |
||||||
|
{{ tab }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="trend-charts"> |
||||||
|
<div class="chart-container"> |
||||||
|
<div class="chart-title">全系统用电量趋势</div> |
||||||
|
<div class="chart" ref="electricTrendChartRef"></div> |
||||||
|
</div> |
||||||
|
<div class="chart-container"> |
||||||
|
<div class="chart-title">碳排放指标趋势</div> |
||||||
|
<div class="chart" ref="carbonTrendChartRef"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 分系统用电分布 --> |
||||||
|
<div class="special-div"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">分系统用电分布</div> |
||||||
|
</div> |
||||||
|
<div class="bar-chart" ref="barChartRef"></div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 周期用量统计 --> |
||||||
|
<div class="special-div"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">近七日用量统计</div> |
||||||
|
</div> |
||||||
|
<div class="period-stats"> |
||||||
|
<div class="stat-card"> |
||||||
|
<div class="stat-label">近七日用电量</div> |
||||||
|
<div class="stat-value">{{ periodData.electricity }} <span class="unit">万kWh</span></div> |
||||||
|
<div class="stat-change" :class="{ positive: periodData.electricityChange >= 0 }"> |
||||||
|
<span v-if="periodData.electricityChange >= 0">↑</span> |
||||||
|
<span v-else>↓</span> |
||||||
|
环比 {{ Math.abs(periodData.electricityChange) }}% |
||||||
|
<span class="compare-label">| 同比 {{ Math.abs(periodData.electricityYoy) }}%</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="stat-card"> |
||||||
|
<div class="stat-label">近七日用水量</div> |
||||||
|
<div class="stat-value">{{ periodData.water }} <span class="unit">t</span></div> |
||||||
|
<div class="stat-change" :class="{ positive: periodData.waterChange >= 0 }"> |
||||||
|
<span v-if="periodData.waterChange >= 0">↑</span> |
||||||
|
<span v-else>↓</span> |
||||||
|
环比 {{ Math.abs(periodData.waterChange) }}% |
||||||
|
<span class="compare-label">| 同比 {{ Math.abs(periodData.waterYoy) }}%</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 周期水电用量可视化 --> |
||||||
|
<div class="special-div"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">周期水电用量分布</div> |
||||||
|
</div> |
||||||
|
<div class="ring-charts"> |
||||||
|
<div class="ring-chart-container"> |
||||||
|
<div class="ring-chart-title">用电量分布</div> |
||||||
|
<div class="ring-chart" ref="electricRingRef"></div> |
||||||
|
</div> |
||||||
|
<div class="ring-chart-container"> |
||||||
|
<div class="ring-chart-title">用水量分布</div> |
||||||
|
<div class="ring-chart" ref="waterRingRef"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import * as echarts from "echarts"; |
||||||
|
|
||||||
|
export default { |
||||||
|
name: "SystemEnergy", |
||||||
|
data() { |
||||||
|
return { |
||||||
|
// 趋势图时间选项 |
||||||
|
trendTimeTabs: ["近七日", "当月", "当年", "自定义"], |
||||||
|
activeTrendTab: 0, |
||||||
|
// 周期统计数据 |
||||||
|
periodData: { |
||||||
|
electricity: 12.58, |
||||||
|
electricityChange: 3.2, |
||||||
|
electricityYoy: -1.5, |
||||||
|
water: 456.8, |
||||||
|
waterChange: -2.1, |
||||||
|
waterYoy: 5.3 |
||||||
|
}, |
||||||
|
// 图表实例 |
||||||
|
electricTrendChart: null, |
||||||
|
carbonTrendChart: null, |
||||||
|
barChart: null, |
||||||
|
electricRingChart: null, |
||||||
|
waterRingChart: null |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.initElectricTrendChart(); |
||||||
|
this.initCarbonTrendChart(); |
||||||
|
this.initBarChart(); |
||||||
|
this.initElectricRingChart(); |
||||||
|
this.initWaterRingChart(); |
||||||
|
window.addEventListener("resize", this.handleResize); |
||||||
|
}, |
||||||
|
beforeDestroy() { |
||||||
|
window.removeEventListener("resize", this.handleResize); |
||||||
|
if (this.electricTrendChart) this.electricTrendChart.dispose(); |
||||||
|
if (this.carbonTrendChart) this.carbonTrendChart.dispose(); |
||||||
|
if (this.barChart) this.barChart.dispose(); |
||||||
|
if (this.electricRingChart) this.electricRingChart.dispose(); |
||||||
|
if (this.waterRingChart) this.waterRingChart.dispose(); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 趋势图时间切换 |
||||||
|
handleTrendTabChange(index) { |
||||||
|
this.activeTrendTab = index; |
||||||
|
// 这里可以添加根据时间切换更新图表数据的逻辑 |
||||||
|
}, |
||||||
|
// 初始化用电量趋势图 |
||||||
|
initElectricTrendChart() { |
||||||
|
this.electricTrendChart = echarts.init(this.$refs.electricTrendChartRef); |
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "axis", |
||||||
|
axisPointer: { |
||||||
|
type: "line" |
||||||
|
} |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: "3%", |
||||||
|
right: "4%", |
||||||
|
bottom: "3%", |
||||||
|
containLabel: true |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
boundaryGap: false, |
||||||
|
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
type: "value", |
||||||
|
name: "万kWh", |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", |
||||||
|
type: "dashed" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "用电量", |
||||||
|
type: "line", |
||||||
|
smooth: true, |
||||||
|
data: [1.8, 2.1, 1.9, 2.3, 2.5, 1.5, 1.4], |
||||||
|
itemStyle: { |
||||||
|
color: "#15e1fd" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#15e1fd" |
||||||
|
}, |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(21, 225, 253, 0.5)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(21, 225, 253, 0)" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.electricTrendChart.setOption(option); |
||||||
|
}, |
||||||
|
// 初始化碳排放趋势图 |
||||||
|
initCarbonTrendChart() { |
||||||
|
this.carbonTrendChart = echarts.init(this.$refs.carbonTrendChartRef); |
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "axis" |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: "3%", |
||||||
|
right: "4%", |
||||||
|
bottom: "3%", |
||||||
|
containLabel: true |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
boundaryGap: false, |
||||||
|
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
type: "value", |
||||||
|
name: "tCO₂e", |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", |
||||||
|
type: "dashed" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "碳排放", |
||||||
|
type: "line", |
||||||
|
smooth: true, |
||||||
|
data: [0.9, 1.1, 0.95, 1.15, 1.25, 0.75, 0.7], |
||||||
|
itemStyle: { |
||||||
|
color: "#91CC75" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
color: "#91CC75" |
||||||
|
}, |
||||||
|
areaStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "rgba(145, 204, 117, 0.5)" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "rgba(145, 204, 117, 0)" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.carbonTrendChart.setOption(option); |
||||||
|
}, |
||||||
|
// 初始化柱状图 |
||||||
|
initBarChart() { |
||||||
|
this.barChart = echarts.init(this.$refs.barChartRef); |
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "axis", |
||||||
|
axisPointer: { |
||||||
|
type: "shadow" |
||||||
|
} |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: "3%", |
||||||
|
right: "4%", |
||||||
|
bottom: "3%", |
||||||
|
containLabel: true |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
data: ["照明系统", "空调系统", "水泵系统", "电梯系统", "风机系统", "监控系统"], |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)", |
||||||
|
interval: 0, |
||||||
|
rotate: 20 |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
type: "value", |
||||||
|
name: "kWh", |
||||||
|
nameTextStyle: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
color: "rgba(255, 255, 255, 0.8)" |
||||||
|
}, |
||||||
|
axisLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#365576" |
||||||
|
} |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
lineStyle: { |
||||||
|
color: "#1a3d62", |
||||||
|
type: "dashed" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "用电量", |
||||||
|
type: "bar", |
||||||
|
barWidth: "40%", |
||||||
|
data: [12500, 8900, 5600, 2300, 4200, 1800], |
||||||
|
itemStyle: { |
||||||
|
color: { |
||||||
|
type: "linear", |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
x2: 0, |
||||||
|
y2: 1, |
||||||
|
colorStops: [ |
||||||
|
{ |
||||||
|
offset: 0, |
||||||
|
color: "#15e1fd" |
||||||
|
}, |
||||||
|
{ |
||||||
|
offset: 1, |
||||||
|
color: "#208fff" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.barChart.setOption(option); |
||||||
|
}, |
||||||
|
// 初始化用电量环形图 |
||||||
|
initElectricRingChart() { |
||||||
|
this.electricRingChart = echarts.init(this.$refs.electricRingRef); |
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "item" |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
orient: "vertical", |
||||||
|
left: "left", |
||||||
|
textStyle: { |
||||||
|
color: "#ffffff" |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "用电量分布", |
||||||
|
type: "pie", |
||||||
|
radius: ["30%", "60%"], |
||||||
|
center: ["60%", "50%"], |
||||||
|
data: [ |
||||||
|
{ value: 35, name: "照明系统" }, |
||||||
|
{ value: 25, name: "空调系统" }, |
||||||
|
{ value: 18, name: "水泵系统" }, |
||||||
|
{ value: 12, name: "电梯系统" }, |
||||||
|
{ value: 10, name: "其他系统" } |
||||||
|
], |
||||||
|
label: { |
||||||
|
formatter: "{b}\n{d}%" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.electricRingChart.setOption(option); |
||||||
|
}, |
||||||
|
// 初始化用水量环形图 |
||||||
|
initWaterRingChart() { |
||||||
|
this.waterRingChart = echarts.init(this.$refs.waterRingRef); |
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "item" |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
orient: "vertical", |
||||||
|
left: "left", |
||||||
|
textStyle: { |
||||||
|
color: "#ffffff" |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "用水量分布", |
||||||
|
type: "pie", |
||||||
|
radius: ["30%", "60%"], |
||||||
|
center: ["60%", "50%"], |
||||||
|
data: [ |
||||||
|
{ value: 40, name: "生活用水" }, |
||||||
|
{ value: 25, name: "冷却补水" }, |
||||||
|
{ value: 20, name: "绿化用水" }, |
||||||
|
{ value: 15, name: "其他用水" } |
||||||
|
], |
||||||
|
label: { |
||||||
|
formatter: "{b}\n{d}%" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.waterRingChart.setOption(option); |
||||||
|
}, |
||||||
|
// 响应式调整 |
||||||
|
handleResize() { |
||||||
|
if (this.electricTrendChart) this.electricTrendChart.resize(); |
||||||
|
if (this.carbonTrendChart) this.carbonTrendChart.resize(); |
||||||
|
if (this.barChart) this.barChart.resize(); |
||||||
|
if (this.electricRingChart) this.electricRingChart.resize(); |
||||||
|
if (this.waterRingChart) this.waterRingChart.resize(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.time-tabs { |
||||||
|
display: flex; |
||||||
|
gap: 0.1rem; |
||||||
|
|
||||||
|
.time-tab { |
||||||
|
padding: 0.06rem 0.2rem; |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
cursor: pointer; |
||||||
|
border-radius: 0.04rem; |
||||||
|
transition: all 0.3s; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
&.active { |
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.trend-charts { |
||||||
|
display: flex; |
||||||
|
gap: 0.16rem; |
||||||
|
padding: 0.2rem; |
||||||
|
|
||||||
|
.chart-container { |
||||||
|
flex: 1; |
||||||
|
|
||||||
|
.chart-title { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
text-align: center; |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
} |
||||||
|
|
||||||
|
.chart { |
||||||
|
width: 100%; |
||||||
|
height: 2.5rem; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.bar-chart { |
||||||
|
width: 100%; |
||||||
|
height: 3rem; |
||||||
|
padding: 0.2rem; |
||||||
|
} |
||||||
|
|
||||||
|
.period-stats { |
||||||
|
display: flex; |
||||||
|
justify-content: space-around; |
||||||
|
padding: 0.3rem 0.2rem; |
||||||
|
gap: 0.2rem; |
||||||
|
|
||||||
|
.stat-card { |
||||||
|
flex: 1; |
||||||
|
padding: 0.25rem; |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
border-radius: 0.08rem; |
||||||
|
text-align: center; |
||||||
|
|
||||||
|
.stat-label { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.8; |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
} |
||||||
|
|
||||||
|
.stat-value { |
||||||
|
font-size: 0.28rem; |
||||||
|
color: #15e1fd; |
||||||
|
font-weight: bold; |
||||||
|
margin-bottom: 0.1rem; |
||||||
|
|
||||||
|
.unit { |
||||||
|
font-size: 0.16rem; |
||||||
|
opacity: 0.8; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.stat-change { |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #91CC75; |
||||||
|
|
||||||
|
&.positive { |
||||||
|
color: #ee5e5e; |
||||||
|
} |
||||||
|
|
||||||
|
.compare-label { |
||||||
|
margin-left: 0.15rem; |
||||||
|
opacity: 0.8; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.ring-charts { |
||||||
|
display: flex; |
||||||
|
gap: 0.2rem; |
||||||
|
padding: 0.2rem; |
||||||
|
|
||||||
|
.ring-chart-container { |
||||||
|
flex: 1; |
||||||
|
text-align: center; |
||||||
|
|
||||||
|
.ring-chart-title { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
margin-bottom: 0.15rem; |
||||||
|
} |
||||||
|
|
||||||
|
.ring-chart { |
||||||
|
width: 100%; |
||||||
|
height: 2.5rem; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 1485px) { |
||||||
|
.trend-charts, |
||||||
|
.ring-charts { |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
|
||||||
|
.period-stats { |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,503 @@ |
|||||||
|
<template> |
||||||
|
<div class="app-container"> |
||||||
|
<!-- 综合类指标 --> |
||||||
|
<div class="special-div"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">综合指标</div> |
||||||
|
</div> |
||||||
|
<div class="comprehensive-indicators"> |
||||||
|
<div class="indicator-item"> |
||||||
|
<div class="indicator-label">综合节能率</div> |
||||||
|
<div class="indicator-value">{{ comprehensiveData.energySavingRate }}%</div> |
||||||
|
</div> |
||||||
|
<div class="indicator-item"> |
||||||
|
<div class="indicator-label">节电金额</div> |
||||||
|
<div class="indicator-value">¥{{ comprehensiveData.electricSavingAmount }}</div> |
||||||
|
</div> |
||||||
|
<div class="indicator-item"> |
||||||
|
<div class="indicator-label">减碳量</div> |
||||||
|
<div class="indicator-value">{{ comprehensiveData.carbonReduction }}t</div> |
||||||
|
</div> |
||||||
|
<div class="indicator-item"> |
||||||
|
<div class="indicator-label">累计用电</div> |
||||||
|
<div class="indicator-value">{{ comprehensiveData.totalElectricity }}kWh</div> |
||||||
|
</div> |
||||||
|
<div class="indicator-item"> |
||||||
|
<div class="indicator-label">节电量</div> |
||||||
|
<div class="indicator-value">{{ comprehensiveData.electricSaving }}kWh</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 设备规模指标 --> |
||||||
|
<div class="special-div"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">设备规模</div> |
||||||
|
<div class="time-tabs"> |
||||||
|
<div |
||||||
|
v-for="(tab, index) in timeTabs" |
||||||
|
:key="index" |
||||||
|
:class="['time-tab', { active: activeTab === index }]" |
||||||
|
@click="handleTabChange(index)" |
||||||
|
> |
||||||
|
{{ tab }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="device-scale"> |
||||||
|
<div class="device-item" v-for="device in deviceList" :key="device.name"> |
||||||
|
<div class="device-icon" :style="{ background: device.bg }"> |
||||||
|
<img :src="device.icon" :alt="device.name" /> |
||||||
|
</div> |
||||||
|
<div class="device-info"> |
||||||
|
<div class="device-name">{{ device.name }}</div> |
||||||
|
<div class="device-count">{{ device.count }}台</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 项目节能统计和用能类型 --> |
||||||
|
<div class="energy-stats-row"> |
||||||
|
<!-- 项目节能统计 --> |
||||||
|
<div class="special-div energy-stats"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">项目节能统计</div> |
||||||
|
</div> |
||||||
|
<div class="energy-data"> |
||||||
|
<div class="energy-item"> |
||||||
|
<div class="energy-label">日节电量</div> |
||||||
|
<div class="energy-value">{{ energySaving.daySaving }}kWh</div> |
||||||
|
</div> |
||||||
|
<div class="energy-item"> |
||||||
|
<div class="energy-label">累计节电量</div> |
||||||
|
<div class="energy-value">{{ energySaving.totalSaving }}kWh</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="ring-chart" ref="ringChartRef"></div> |
||||||
|
<div class="chart-legend"> |
||||||
|
<div |
||||||
|
class="legend-item" |
||||||
|
v-for="(item, index) in energyLegend" |
||||||
|
:key="index" |
||||||
|
> |
||||||
|
<span |
||||||
|
class="legend-color" |
||||||
|
:style="{ background: item.color }" |
||||||
|
></span> |
||||||
|
<span class="legend-text">{{ item.name }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="compare-tabs"> |
||||||
|
<div |
||||||
|
:class="['compare-tab', { active: compareType === 'yoy' }]" |
||||||
|
@click="compareType = 'yoy'" |
||||||
|
> |
||||||
|
同比 |
||||||
|
</div> |
||||||
|
<div |
||||||
|
:class="['compare-tab', { active: compareType === 'mom' }]" |
||||||
|
@click="compareType = 'mom'" |
||||||
|
> |
||||||
|
环比 |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 项目用能类型 --> |
||||||
|
<div class="special-div energy-type"> |
||||||
|
<div class="special-top"> |
||||||
|
<div class="special-title">项目用能类型</div> |
||||||
|
</div> |
||||||
|
<div class="pie-chart" ref="pieChartRef"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import * as echarts from "echarts"; |
||||||
|
|
||||||
|
export default { |
||||||
|
name: "SystemHome", |
||||||
|
data() { |
||||||
|
return { |
||||||
|
// 综合类指标数据 |
||||||
|
comprehensiveData: { |
||||||
|
energySavingRate: 15.8, |
||||||
|
electricSavingAmount: 125.6, |
||||||
|
carbonReduction: 89.3, |
||||||
|
totalElectricity: 45680, |
||||||
|
electricSaving: 7890 |
||||||
|
}, |
||||||
|
// 时间切换选项 |
||||||
|
timeTabs: ["近七日", "当月", "当年", "自定义"], |
||||||
|
activeTab: 0, |
||||||
|
// 设备列表 |
||||||
|
deviceList: [ |
||||||
|
{ name: "照明系统", count: 1250, icon: "", bg: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)" }, |
||||||
|
{ name: "空调系统", count: 86, icon: "", bg: "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)" }, |
||||||
|
{ name: "水泵系统", count: 156, icon: "", bg: "linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)" }, |
||||||
|
{ name: "电梯系统", count: 24, icon: "", bg: "linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)" }, |
||||||
|
{ name: "风机系统", count: 328, icon: "", bg: "linear-gradient(135deg, #fa709a 0%, #fee140 100%)" }, |
||||||
|
{ name: "监控系统", count: 189, icon: "", bg: "linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)" } |
||||||
|
], |
||||||
|
// 节能统计数据 |
||||||
|
energySaving: { |
||||||
|
daySaving: 328, |
||||||
|
totalSaving: 7890 |
||||||
|
}, |
||||||
|
// 节能占比图例 |
||||||
|
energyLegend: [ |
||||||
|
{ name: "照明系统", color: "#5470C6" }, |
||||||
|
{ name: "空调系统", color: "#91CC75" }, |
||||||
|
{ name: "水泵系统", color: "#FAC858" }, |
||||||
|
{ name: "其他系统", color: "#EE6666" } |
||||||
|
], |
||||||
|
// 同比环比 |
||||||
|
compareType: "yoy", |
||||||
|
// 图表实例 |
||||||
|
ringChart: null, |
||||||
|
pieChart: null |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.initRingChart(); |
||||||
|
this.initPieChart(); |
||||||
|
window.addEventListener("resize", this.handleResize); |
||||||
|
}, |
||||||
|
beforeDestroy() { |
||||||
|
window.removeEventListener("resize", this.handleResize); |
||||||
|
if (this.ringChart) this.ringChart.dispose(); |
||||||
|
if (this.pieChart) this.pieChart.dispose(); |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
compareType() { |
||||||
|
this.updateRingChart(); |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 时间切换 |
||||||
|
handleTabChange(index) { |
||||||
|
this.activeTab = index; |
||||||
|
// 这里可以添加根据时间切换获取数据的逻辑 |
||||||
|
}, |
||||||
|
// 初始化环形图 |
||||||
|
initRingChart() { |
||||||
|
this.ringChart = echarts.init(this.$refs.ringChartRef); |
||||||
|
this.updateRingChart(); |
||||||
|
}, |
||||||
|
// 更新环形图 |
||||||
|
updateRingChart() { |
||||||
|
const data = this.compareType === "yoy" |
||||||
|
? [ |
||||||
|
{ value: 35, name: "照明系统" }, |
||||||
|
{ value: 28, name: "空调系统" }, |
||||||
|
{ value: 22, name: "水泵系统" }, |
||||||
|
{ value: 15, name: "其他系统" } |
||||||
|
] |
||||||
|
: [ |
||||||
|
{ value: 32, name: "照明系统" }, |
||||||
|
{ value: 30, name: "空调系统" }, |
||||||
|
{ value: 25, name: "水泵系统" }, |
||||||
|
{ value: 13, name: "其他系统" } |
||||||
|
]; |
||||||
|
|
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "item", |
||||||
|
formatter: "{b}: {c}% ({d}%)" |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "节能占比", |
||||||
|
type: "pie", |
||||||
|
radius: ["40%", "70%"], |
||||||
|
center: ["50%", "45%"], |
||||||
|
avoidLabelOverlap: false, |
||||||
|
label: { |
||||||
|
show: true, |
||||||
|
formatter: "{b}\n{d}%" |
||||||
|
}, |
||||||
|
emphasis: { |
||||||
|
label: { |
||||||
|
show: true, |
||||||
|
fontSize: 14, |
||||||
|
fontWeight: "bold" |
||||||
|
} |
||||||
|
}, |
||||||
|
data: data |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.ringChart.setOption(option); |
||||||
|
}, |
||||||
|
// 初始化饼图 |
||||||
|
initPieChart() { |
||||||
|
this.pieChart = echarts.init(this.$refs.pieChartRef); |
||||||
|
const option = { |
||||||
|
tooltip: { |
||||||
|
trigger: "item", |
||||||
|
formatter: "{b}: {c}% ({d}%)" |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
orient: "vertical", |
||||||
|
left: "left", |
||||||
|
textStyle: { |
||||||
|
color: "#ffffff" |
||||||
|
} |
||||||
|
}, |
||||||
|
series: [ |
||||||
|
{ |
||||||
|
name: "用能类型", |
||||||
|
type: "pie", |
||||||
|
radius: "60%", |
||||||
|
center: ["60%", "50%"], |
||||||
|
data: [ |
||||||
|
{ value: 28, name: "生活用水" }, |
||||||
|
{ value: 35, name: "空调用电" }, |
||||||
|
{ value: 18, name: "照明用电" }, |
||||||
|
{ value: 12, name: "动力用电" }, |
||||||
|
{ value: 7, name: "其他" } |
||||||
|
], |
||||||
|
emphasis: { |
||||||
|
itemStyle: { |
||||||
|
shadowBlur: 10, |
||||||
|
shadowOffsetX: 0, |
||||||
|
shadowColor: "rgba(0, 0, 0, 0.5)" |
||||||
|
} |
||||||
|
}, |
||||||
|
label: { |
||||||
|
formatter: "{b}\n{d}%" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}; |
||||||
|
this.pieChart.setOption(option); |
||||||
|
}, |
||||||
|
// 响应式调整 |
||||||
|
handleResize() { |
||||||
|
if (this.ringChart) this.ringChart.resize(); |
||||||
|
if (this.pieChart) this.pieChart.resize(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.comprehensive-indicators { |
||||||
|
display: flex; |
||||||
|
justify-content: space-around; |
||||||
|
padding: 0.3rem 0.2rem; |
||||||
|
flex-wrap: wrap; |
||||||
|
gap: 0.2rem; |
||||||
|
|
||||||
|
.indicator-item { |
||||||
|
text-align: center; |
||||||
|
flex: 1; |
||||||
|
min-width: 1.8rem; |
||||||
|
|
||||||
|
.indicator-label { |
||||||
|
font-size: 0.16rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.8; |
||||||
|
margin-bottom: 0.1rem; |
||||||
|
} |
||||||
|
|
||||||
|
.indicator-value { |
||||||
|
font-size: 0.24rem; |
||||||
|
color: #15e1fd; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.time-tabs { |
||||||
|
display: flex; |
||||||
|
gap: 0.1rem; |
||||||
|
|
||||||
|
.time-tab { |
||||||
|
padding: 0.06rem 0.2rem; |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
cursor: pointer; |
||||||
|
border-radius: 0.04rem; |
||||||
|
transition: all 0.3s; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
&.active { |
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.device-scale { |
||||||
|
display: flex; |
||||||
|
flex-wrap: wrap; |
||||||
|
padding: 0.3rem 0.2rem; |
||||||
|
gap: 0.2rem; |
||||||
|
|
||||||
|
.device-item { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 0.15rem 0.25rem; |
||||||
|
background: rgba(255, 255, 255, 0.05); |
||||||
|
border-radius: 0.08rem; |
||||||
|
flex: 1; |
||||||
|
min-width: 2rem; |
||||||
|
|
||||||
|
.device-icon { |
||||||
|
width: 0.5rem; |
||||||
|
height: 0.5rem; |
||||||
|
border-radius: 0.08rem; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
margin-right: 0.15rem; |
||||||
|
|
||||||
|
img { |
||||||
|
width: 0.3rem; |
||||||
|
height: 0.3rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.device-info { |
||||||
|
flex: 1; |
||||||
|
|
||||||
|
.device-name { |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.8; |
||||||
|
margin-bottom: 0.05rem; |
||||||
|
} |
||||||
|
|
||||||
|
.device-count { |
||||||
|
font-size: 0.2rem; |
||||||
|
color: #15e1fd; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.energy-stats-row { |
||||||
|
display: flex; |
||||||
|
gap: 0.16rem; |
||||||
|
margin-top: 0.16rem; |
||||||
|
|
||||||
|
.special-div { |
||||||
|
flex: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.energy-stats { |
||||||
|
.energy-data { |
||||||
|
display: flex; |
||||||
|
justify-content: space-around; |
||||||
|
padding: 0.2rem; |
||||||
|
|
||||||
|
.energy-item { |
||||||
|
text-align: center; |
||||||
|
|
||||||
|
.energy-label { |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
margin-bottom: 0.08rem; |
||||||
|
} |
||||||
|
|
||||||
|
.energy-value { |
||||||
|
font-size: 0.22rem; |
||||||
|
color: #15e1fd; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.ring-chart { |
||||||
|
width: 100%; |
||||||
|
height: 2.5rem; |
||||||
|
} |
||||||
|
|
||||||
|
.chart-legend { |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
gap: 0.3rem; |
||||||
|
padding: 0.1rem 0; |
||||||
|
|
||||||
|
.legend-item { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
|
||||||
|
.legend-color { |
||||||
|
width: 0.12rem; |
||||||
|
height: 0.12rem; |
||||||
|
border-radius: 50%; |
||||||
|
margin-right: 0.08rem; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.compare-tabs { |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
gap: 0.2rem; |
||||||
|
margin-top: 0.1rem; |
||||||
|
|
||||||
|
.compare-tab { |
||||||
|
padding: 0.05rem 0.2rem; |
||||||
|
font-size: 0.14rem; |
||||||
|
color: #ffffff; |
||||||
|
opacity: 0.7; |
||||||
|
cursor: pointer; |
||||||
|
border-radius: 0.04rem; |
||||||
|
transition: all 0.3s; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
&.active { |
||||||
|
background: linear-gradient(135deg, #5470C6 0%, #91CC75 100%); |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.energy-type { |
||||||
|
.pie-chart { |
||||||
|
width: 100%; |
||||||
|
height: 3.2rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 1485px) { |
||||||
|
.comprehensive-indicators { |
||||||
|
.indicator-item { |
||||||
|
min-width: 1.5rem; |
||||||
|
flex: none; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.device-scale { |
||||||
|
.device-item { |
||||||
|
min-width: 1.8rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.energy-stats-row { |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
Loading…
Reference in new issue