update 同比分析初始化

master
yinq 6 days ago
parent 7969e6d089
commit 071268b04e

@ -0,0 +1,792 @@
<template>
<div class="energy-dashboard">
<!-- 条件筛选区 -->
<el-card class="filter-section" style="margin-bottom: 20px;">
<div slot="header">
<span>电能耗同比环比分析</span>
</div>
<el-form :model="filterForm" :inline="true" size="small">
<el-form-item label="区域">
<el-select v-model="filterForm.area" placeholder="请选择区域" style="width: 120px;">
<el-option label="全部区域" value=""></el-option>
<el-option label="一车间" value="area1"></el-option>
<el-option label="二车间" value="area2"></el-option>
<el-option label="三车间" value="area3"></el-option>
<el-option label="四车间" value="area4"></el-option>
</el-select>
</el-form-item>
<el-form-item label="部门">
<el-select v-model="filterForm.department" placeholder="请选择部门" style="width: 120px;">
<el-option label="全部部门" value=""></el-option>
<el-option label="生产部" value="prod"></el-option>
<el-option label="设备部" value="equip"></el-option>
<el-option label="能源部" value="energy"></el-option>
</el-select>
</el-form-item>
<el-form-item label="回路">
<el-select v-model="filterForm.circuit" placeholder="请选择回路" style="width: 120px;">
<el-option label="全部回路" value=""></el-option>
<el-option label="主回路" value="main"></el-option>
<el-option label="照明回路" value="light"></el-option>
<el-option label="动力回路" value="power"></el-option>
</el-select>
</el-form-item>
<el-form-item label="管网">
<el-select v-model="filterForm.pipeline" placeholder="请选择管网" style="width: 120px;">
<el-option label="全部管网" value=""></el-option>
<el-option label="高压管网" value="high"></el-option>
<el-option label="中压管网" value="medium"></el-option>
<el-option label="低压管网" value="low"></el-option>
</el-select>
</el-form-item>
<el-form-item label="能源类型">
<el-select v-model="filterForm.energyType" placeholder="请选择能源类型" style="width: 120px;">
<el-option label="电力" value="electricity"></el-option>
<el-option label="水" value="water"></el-option>
<el-option label="蒸汽" value="steam"></el-option>
<el-option label="压缩空气" value="air"></el-option>
<el-option label="氮气" value="nitrogen"></el-option>
</el-select>
</el-form-item>
<el-form-item label="时间维度">
<el-select v-model="filterForm.timeDimension" placeholder="请选择时间维度" style="width: 120px;">
<el-option label="时" value="hour"></el-option>
<el-option label="日" value="day"></el-option>
<el-option label="月" value="month"></el-option>
<el-option label="年" value="year"></el-option>
</el-select>
</el-form-item>
<el-form-item label="时间范围">
<el-date-picker
v-model="filterForm.timeRange"
type="datetimerange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 300px;">
</el-date-picker>
</el-form-item>
<el-form-item label="对比类型">
<el-select v-model="filterForm.compareType" placeholder="请选择对比类型" style="width: 120px;">
<el-option label="同比" value="yoy"></el-option>
<el-option label="环比" value="mom"></el-option>
<el-option label="自定义对比" value="custom"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch"></el-button>
<el-button @click="handleReset"></el-button>
<el-button @click="handleExport"></el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 数据可视化展示区 -->
<el-row :gutter="20" class="visualization-section">
<!-- 趋势对比图 -->
<el-col :span="12">
<el-card>
<div slot="header">
<span>趋势对比图</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="saveChart('trendChart')">
保存图片
</el-button>
</div>
<div ref="trendChart" style="height: 300px; width: 100%"></div>
</el-card>
</el-col>
<!-- 能耗总量对比 -->
<el-col :span="12">
<el-card>
<div slot="header">
<span>能耗总量对比</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="saveChart('totalChart')">
保存图片
</el-button>
</div>
<div ref="totalChart" style="height: 300px; width: 100%"></div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20" class="visualization-section" style="margin-top: 20px;">
<!-- 能耗占比对比 -->
<el-col :span="12">
<el-card>
<div slot="header">
<span>能耗占比对比</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="saveChart('proportionChart')">
保存图片
</el-button>
</div>
<div ref="proportionChart" style="height: 300px; width: 100%"></div>
</el-card>
</el-col>
<!-- 变化率趋势 -->
<el-col :span="12">
<el-card>
<div slot="header">
<span>变化率趋势</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="saveChart('rateChart')">
保存图片
</el-button>
</div>
<div ref="rateChart" style="height: 300px; width: 100%"></div>
</el-card>
</el-col>
</el-row>
<!-- 数据分析区 -->
<el-row :gutter="20" class="analysis-section" style="margin-top: 20px;">
<el-col :span="24">
<el-card>
<div slot="header">
<span>关键指标分析</span>
</div>
<el-row :gutter="20">
<el-col :span="6" v-for="(metric, index) in keyMetrics" :key="index">
<div class="metric-card">
<div class="metric-title">{{ metric.title }}</div>
<div class="metric-value" :class="metric.trend">
{{ metric.value }}
<i :class="metric.trend === 'up' ? 'el-icon-caret-top' : 'el-icon-caret-bottom'"></i>
</div>
<div class="metric-desc">{{ metric.description }}</div>
</div>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<!-- 数据表格区 -->
<el-row :gutter="20" class="table-section" style="margin-top: 20px;">
<el-col :span="24">
<el-card>
<div slot="header">
<span>详细数据列表</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="exportTable">
导出Excel
</el-button>
</div>
<el-table :data="tableData" border size="small" style="width: 100%">
<el-table-column prop="time" label="时间点" width="180"></el-table-column>
<el-table-column prop="currentValue" label="本期值" width="120"></el-table-column>
<el-table-column prop="compareValue" label="对比期值" width="120"></el-table-column>
<el-table-column prop="changeAmount" label="变化量" width="120">
<template slot-scope="scope">
<span :class="scope.row.changeAmount >= 0 ? 'text-danger' : 'text-success'">
{{ scope.row.changeAmount >= 0 ? '+' : '' }}{{ scope.row.changeAmount }}
</span>
</template>
</el-table-column>
<el-table-column prop="changeRate" label="变化率" width="120">
<template slot-scope="scope">
<span :class="scope.row.changeRate >= 0 ? 'text-danger' : 'text-success'">
{{ scope.row.changeRate >= 0 ? '+' : '' }}{{ scope.row.changeRate }}%
</span>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="100">
<template slot-scope="scope">
<el-tag :type="scope.row.status === 'normal' ? 'success' : 'danger'" size="mini">
{{ scope.row.status === 'normal' ? '正常' : '异常' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注"></el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pagination.currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
style="margin-top: 20px; text-align: right;">
</el-pagination>
</el-card>
</el-col>
</el-row>
<!-- 原有的总览模块 -->
<el-row :gutter="20" class="dashboard-overview" style="margin-top: 24px;">
<el-col :span="8">
<el-card>
<div slot="header">五种能源整体占比</div>
<div ref="overviewPie" style="height:260px;width:100%"></div>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<div slot="header">累计消耗柱状对比</div>
<div ref="overviewBar" style="height:260px;width:100%"></div>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<div slot="header">峰值需量仪表</div>
<div ref="overviewGauge" style="height:260px;width:100%"></div>
</el-card>
</el-col>
</el-row>
<!-- 原有的能源对比与效率分析 -->
<el-row :gutter="20" class="dashboard-compare" style="margin-top: 24px;">
<el-col :span="8">
<el-card>
<div slot="header">五种能源消耗堆叠柱状图</div>
<div ref="compareStackBar" style="height:220px;width:100%"></div>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<div slot="header">单位产出消耗强度雷达图</div>
<div ref="compareRadar" style="height:220px;width:100%"></div>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<div slot="header">气体类比压缩空气 vs 氮气</div>
<div ref="compareGas" style="height:220px;width:100%"></div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import * as echarts from 'echarts'
export default {
name: "FactoryEnergyDashboard",
data() {
return {
//
filterForm: {
area: '',
department: '',
circuit: '',
pipeline: '',
energyType: 'electricity',
timeDimension: 'day',
timeRange: [],
compareType: 'yoy'
},
//
keyMetrics: [
{ title: '同比增长率', value: '+12.5%', trend: 'up', description: '相比去年同期增长' },
{ title: '环比增长率', value: '-3.2%', trend: 'down', description: '相比上期下降' },
{ title: '平均能耗', value: '856.7 kWh', trend: 'up', description: '本期平均能耗' },
{ title: '峰值能耗', value: '1245.3 kWh', trend: 'up', description: '本期峰值能耗' }
],
//
pagination: {
currentPage: 1,
pageSize: 20,
total: 0
},
//
tableData: [],
//
charts: {},
//
overviewPieData: [
{ value: 800, name: '电' },
{ value: 500, name: '水' },
{ value: 300, name: '蒸汽' },
{ value: 200, name: '压缩空气' },
{ value: 100, name: '氮气' }
],
overviewBarData: [120, 800, 3200],
overviewBarLabels: ['本日', '本周', '本月'],
overviewGaugeData: [
{ value: 320, name: '电力峰值(kW)' },
{ value: 120, name: '蒸汽流量峰值(t/h)' }
],
//
compareStackBarLabels: ['本日','本周','本月'],
compareStackBarData: {
water: [12, 80, 320],
electricity: [22, 182, 391],
steam: [15, 132, 201],
air: [9, 77, 101],
nitrogen: [6, 72, 91]
},
compareRadarIndicators: [
{ name: '水', max: 100 },
{ name: '电', max: 100 },
{ name: '蒸汽', max: 100 },
{ name: '压缩空气', max: 100 },
{ name: '氮气', max: 100 }
],
compareRadarData: [60, 80, 70, 50, 40],
compareGasLabels: ['压力稳定性','泄漏率','单位产出成本'],
compareGasData: {
air: [90, 8, 0.5],
nitrogen: [85, 5, 0.7]
}
};
},
mounted() {
this.initFilterForm();
this.initAnalysisCharts();
this.initOverviewCharts();
this.initCompareCharts();
this.loadTableData();
},
methods: {
//
initFilterForm() {
const now = new Date();
const startDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
this.filterForm.timeRange = [
startDate.toISOString().slice(0, 19).replace('T', ' '),
now.toISOString().slice(0, 19).replace('T', ' ')
];
},
//
handleSearch() {
this.loadTableData();
this.updateCharts();
},
//
handleReset() {
this.filterForm = {
area: '',
department: '',
circuit: '',
pipeline: '',
energyType: 'electricity',
timeDimension: 'day',
timeRange: this.filterForm.timeRange,
compareType: 'yoy'
};
},
//
handleExport() {
this.$message.success('导出功能开发中...');
},
//
saveChart(chartName) {
if (this.charts[chartName]) {
const url = this.charts[chartName].getDataURL();
const link = document.createElement('a');
link.download = `${chartName}_${new Date().getTime()}.png`;
link.href = url;
link.click();
}
},
//
exportTable() {
this.$message.success('表格导出功能开发中...');
},
//
handleSizeChange(val) {
this.pagination.pageSize = val;
this.loadTableData();
},
handleCurrentChange(val) {
this.pagination.currentPage = val;
this.loadTableData();
},
//
loadTableData() {
//
const mockData = [];
for (let i = 0; i < 50; i++) {
const currentValue = Math.random() * 1000 + 500;
const compareValue = Math.random() * 1000 + 500;
const changeAmount = currentValue - compareValue;
const changeRate = ((changeAmount / compareValue) * 100).toFixed(2);
mockData.push({
time: `2024-06-${String(i + 1).padStart(2, '0')} ${String(Math.floor(Math.random() * 24)).padStart(2, '0')}:00:00`,
currentValue: currentValue.toFixed(2),
compareValue: compareValue.toFixed(2),
changeAmount: changeAmount.toFixed(2),
changeRate: changeRate,
status: Math.random() > 0.8 ? 'abnormal' : 'normal',
remark: Math.random() > 0.8 ? '能耗异常波动' : ''
});
}
this.tableData = mockData.slice(
(this.pagination.currentPage - 1) * this.pagination.pageSize,
this.pagination.currentPage * this.pagination.pageSize
);
this.pagination.total = mockData.length;
},
//
initAnalysisCharts() {
this.$nextTick(() => {
this.initTrendChart();
this.initTotalChart();
this.initProportionChart();
this.initRateChart();
});
},
//
initTrendChart() {
const chart = echarts.init(this.$refs.trendChart);
this.charts.trendChart = chart;
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['本期能耗', '对比期能耗', '变化率']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00']
},
yAxis: [
{
type: 'value',
name: '能耗(kWh)',
position: 'left'
},
{
type: 'value',
name: '变化率(%)',
position: 'right',
axisLabel: {
formatter: '{value}%'
}
}
],
series: [
{
name: '本期能耗',
type: 'bar',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '对比期能耗',
type: 'bar',
data: [110, 125, 95, 128, 85, 220, 200]
},
{
name: '变化率',
type: 'line',
yAxisIndex: 1,
data: [9.1, 5.6, 6.3, 4.7, 5.9, 4.5, 5.0]
}
]
};
chart.setOption(option);
},
//
initTotalChart() {
const chart = echarts.init(this.$refs.totalChart);
this.charts.totalChart = chart;
const option = {
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left'
},
series: [
{
name: '能耗对比',
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: '本期能耗' },
{ value: 735, name: '对比期能耗' }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
chart.setOption(option);
},
//
initProportionChart() {
const chart = echarts.init(this.$refs.proportionChart);
this.charts.proportionChart = chart;
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['本期占比', '对比期占比']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['照明', '动力', '空调', '其他']
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
series: [
{
name: '本期占比',
type: 'bar',
data: [25, 35, 30, 10]
},
{
name: '对比期占比',
type: 'bar',
data: [20, 40, 25, 15]
}
]
};
chart.setOption(option);
},
//
initRateChart() {
const chart = echarts.init(this.$refs.rateChart);
this.charts.rateChart = chart;
const option = {
tooltip: {
trigger: 'axis'
},
legend: {
data: ['同比增长率', '环比增长率']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
series: [
{
name: '同比增长率',
type: 'line',
stack: 'Total',
data: [12, 13, 10, 13, 9, 23, 21]
},
{
name: '环比增长率',
type: 'line',
stack: 'Total',
data: [2, 3, 1, 3, -1, 13, 11]
}
]
};
chart.setOption(option);
},
//
updateCharts() {
//
this.$message.success('图表数据已更新');
},
getLabel(type) {
const map = {
water: "水",
electricity: "电",
steam: "蒸汽",
air: "压缩空气",
nitrogen: "氮气"
};
return map[type] || type;
},
// 1.
initOverviewCharts() {
//
const pie = echarts.init(this.$refs.overviewPie);
pie.setOption({
tooltip: { trigger: 'item' },
legend: { bottom: 10, left: 'center' },
color: ['#5470C6', '#91CC75', '#FAC858', '#EE6666', '#73C0DE'],
series: [{
name: '能源占比',
type: 'pie',
radius: ['60%', '80%'],
label: { show: true, formatter: '{b}: {d}%' },
data: this.overviewPieData
}]
});
//
const bar = echarts.init(this.$refs.overviewBar);
bar.setOption({
xAxis: { type: 'category', data: this.overviewBarLabels },
yAxis: { type: 'value' },
series: [{
data: this.overviewBarData,
type: 'bar',
label: { show: true, position: 'top' },
itemStyle: {
color: function(params) {
const colors = ['#5470C6', '#91CC75', '#FAC858'];
return colors[params.dataIndex];
}
}
}]
});
//
const gauge = echarts.init(this.$refs.overviewGauge);
gauge.setOption({
series: [
{
type: 'gauge',
min: 0,
max: 500,
detail: { formatter: '{value}' },
data: [this.overviewGaugeData[0]],
title: { offsetCenter: [0, '-30%'] },
axisLine: { lineStyle: { width: 10 } },
pointer: { width: 5 }
},
{
type: 'gauge',
min: 0,
max: 200,
center: ['75%', '60%'],
radius: '40%',
detail: { formatter: '{value}' },
data: [this.overviewGaugeData[1]],
title: { offsetCenter: [0, '-30%'] },
axisLine: { lineStyle: { width: 6 } },
pointer: { width: 3 }
}
]
});
},
// 3.
initCompareCharts() {
//
const stackBar = echarts.init(this.$refs.compareStackBar);
stackBar.setOption({
tooltip: { trigger: 'axis' },
legend: { data: ['水', '电', '蒸汽', '压缩空气', '氮气'] },
xAxis: { type: 'category', data: this.compareStackBarLabels },
yAxis: { type: 'value' },
series: [
{ name: '水', type: 'bar', stack: 'total', data: this.compareStackBarData.water },
{ name: '电', type: 'bar', stack: 'total', data: this.compareStackBarData.electricity },
{ name: '蒸汽', type: 'bar', stack: 'total', data: this.compareStackBarData.steam },
{ name: '压缩空气', type: 'bar', stack: 'total', data: this.compareStackBarData.air },
{ name: '氮气', type: 'bar', stack: 'total', data: this.compareStackBarData.nitrogen }
]
});
//
const radar = echarts.init(this.$refs.compareRadar);
radar.setOption({
radar: { indicator: this.compareRadarIndicators },
series: [{
type: 'radar',
data: [{ value: this.compareRadarData, name: '单位产出能耗' }]
}]
});
//
const gas = echarts.init(this.$refs.compareGas);
gas.setOption({
tooltip: { trigger: 'axis' },
legend: { data: ['压缩空气', '氮气'] },
xAxis: { type: 'category', data: this.compareGasLabels },
yAxis: { type: 'value' },
series: [
{ name: '压缩空气', type: 'bar', data: this.compareGasData.air },
{ name: '氮气', type: 'bar', data: this.compareGasData.nitrogen }
]
});
}
}
}
</script>
<style scoped>
.energy-dashboard {
padding: 20px;
}
.filter-section {
background: #f5f7fa;
}
.visualization-section .el-card {
min-height: 350px;
}
.analysis-section .el-card {
min-height: 200px;
}
.table-section .el-card {
min-height: 400px;
}
.metric-card {
background: #f5f7fa;
border-radius: 8px;
padding: 15px;
text-align: center;
margin-bottom: 10px;
}
.metric-title {
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
.metric-value {
font-size: 24px;
font-weight: bold;
margin: 8px 0;
display: flex;
align-items: center;
justify-content: center;
}
.metric-value.up {
color: #67C23A;
}
.metric-value.down {
color: #F56C6C;
}
.metric-desc {
font-size: 12px;
color: #999;
}
.text-danger {
color: #F56C6C;
}
.text-success {
color: #67C23A;
}
.dashboard-overview .el-card {
min-height: 300px;
}
</style>

@ -0,0 +1,792 @@
<template>
<div class="energy-dashboard">
<!-- 条件筛选区 -->
<el-card class="filter-section" style="margin-bottom: 20px;">
<div slot="header">
<span>电能耗同比环比分析</span>
</div>
<el-form :model="filterForm" :inline="true" size="small">
<el-form-item label="区域">
<el-select v-model="filterForm.area" placeholder="请选择区域" style="width: 120px;">
<el-option label="全部区域" value=""></el-option>
<el-option label="一车间" value="area1"></el-option>
<el-option label="二车间" value="area2"></el-option>
<el-option label="三车间" value="area3"></el-option>
<el-option label="四车间" value="area4"></el-option>
</el-select>
</el-form-item>
<el-form-item label="部门">
<el-select v-model="filterForm.department" placeholder="请选择部门" style="width: 120px;">
<el-option label="全部部门" value=""></el-option>
<el-option label="生产部" value="prod"></el-option>
<el-option label="设备部" value="equip"></el-option>
<el-option label="能源部" value="energy"></el-option>
</el-select>
</el-form-item>
<el-form-item label="回路">
<el-select v-model="filterForm.circuit" placeholder="请选择回路" style="width: 120px;">
<el-option label="全部回路" value=""></el-option>
<el-option label="主回路" value="main"></el-option>
<el-option label="照明回路" value="light"></el-option>
<el-option label="动力回路" value="power"></el-option>
</el-select>
</el-form-item>
<el-form-item label="管网">
<el-select v-model="filterForm.pipeline" placeholder="请选择管网" style="width: 120px;">
<el-option label="全部管网" value=""></el-option>
<el-option label="高压管网" value="high"></el-option>
<el-option label="中压管网" value="medium"></el-option>
<el-option label="低压管网" value="low"></el-option>
</el-select>
</el-form-item>
<el-form-item label="能源类型">
<el-select v-model="filterForm.energyType" placeholder="请选择能源类型" style="width: 120px;">
<el-option label="电力" value="electricity"></el-option>
<el-option label="水" value="water"></el-option>
<el-option label="蒸汽" value="steam"></el-option>
<el-option label="压缩空气" value="air"></el-option>
<el-option label="氮气" value="nitrogen"></el-option>
</el-select>
</el-form-item>
<el-form-item label="时间维度">
<el-select v-model="filterForm.timeDimension" placeholder="请选择时间维度" style="width: 120px;">
<el-option label="时" value="hour"></el-option>
<el-option label="日" value="day"></el-option>
<el-option label="月" value="month"></el-option>
<el-option label="年" value="year"></el-option>
</el-select>
</el-form-item>
<el-form-item label="时间范围">
<el-date-picker
v-model="filterForm.timeRange"
type="datetimerange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 300px;">
</el-date-picker>
</el-form-item>
<el-form-item label="对比类型">
<el-select v-model="filterForm.compareType" placeholder="请选择对比类型" style="width: 120px;">
<el-option label="同比" value="yoy"></el-option>
<el-option label="环比" value="mom"></el-option>
<el-option label="自定义对比" value="custom"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch"></el-button>
<el-button @click="handleReset"></el-button>
<el-button @click="handleExport"></el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 数据可视化展示区 -->
<el-row :gutter="20" class="visualization-section">
<!-- 趋势对比图 -->
<el-col :span="12">
<el-card>
<div slot="header">
<span>趋势对比图</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="saveChart('trendChart')">
保存图片
</el-button>
</div>
<div ref="trendChart" style="height: 300px; width: 100%"></div>
</el-card>
</el-col>
<!-- 能耗总量对比 -->
<el-col :span="12">
<el-card>
<div slot="header">
<span>能耗总量对比</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="saveChart('totalChart')">
保存图片
</el-button>
</div>
<div ref="totalChart" style="height: 300px; width: 100%"></div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20" class="visualization-section" style="margin-top: 20px;">
<!-- 能耗占比对比 -->
<el-col :span="12">
<el-card>
<div slot="header">
<span>能耗占比对比</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="saveChart('proportionChart')">
保存图片
</el-button>
</div>
<div ref="proportionChart" style="height: 300px; width: 100%"></div>
</el-card>
</el-col>
<!-- 变化率趋势 -->
<el-col :span="12">
<el-card>
<div slot="header">
<span>变化率趋势</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="saveChart('rateChart')">
保存图片
</el-button>
</div>
<div ref="rateChart" style="height: 300px; width: 100%"></div>
</el-card>
</el-col>
</el-row>
<!-- 数据分析区 -->
<el-row :gutter="20" class="analysis-section" style="margin-top: 20px;">
<el-col :span="24">
<el-card>
<div slot="header">
<span>关键指标分析</span>
</div>
<el-row :gutter="20">
<el-col :span="6" v-for="(metric, index) in keyMetrics" :key="index">
<div class="metric-card">
<div class="metric-title">{{ metric.title }}</div>
<div class="metric-value" :class="metric.trend">
{{ metric.value }}
<i :class="metric.trend === 'up' ? 'el-icon-caret-top' : 'el-icon-caret-bottom'"></i>
</div>
<div class="metric-desc">{{ metric.description }}</div>
</div>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<!-- 数据表格区 -->
<el-row :gutter="20" class="table-section" style="margin-top: 20px;">
<el-col :span="24">
<el-card>
<div slot="header">
<span>详细数据列表</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="exportTable">
导出Excel
</el-button>
</div>
<el-table :data="tableData" border size="small" style="width: 100%">
<el-table-column prop="time" label="时间点" width="180"></el-table-column>
<el-table-column prop="currentValue" label="本期值" width="120"></el-table-column>
<el-table-column prop="compareValue" label="对比期值" width="120"></el-table-column>
<el-table-column prop="changeAmount" label="变化量" width="120">
<template slot-scope="scope">
<span :class="scope.row.changeAmount >= 0 ? 'text-danger' : 'text-success'">
{{ scope.row.changeAmount >= 0 ? '+' : '' }}{{ scope.row.changeAmount }}
</span>
</template>
</el-table-column>
<el-table-column prop="changeRate" label="变化率" width="120">
<template slot-scope="scope">
<span :class="scope.row.changeRate >= 0 ? 'text-danger' : 'text-success'">
{{ scope.row.changeRate >= 0 ? '+' : '' }}{{ scope.row.changeRate }}%
</span>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="100">
<template slot-scope="scope">
<el-tag :type="scope.row.status === 'normal' ? 'success' : 'danger'" size="mini">
{{ scope.row.status === 'normal' ? '正常' : '异常' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注"></el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pagination.currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
style="margin-top: 20px; text-align: right;">
</el-pagination>
</el-card>
</el-col>
</el-row>
<!-- 原有的总览模块 -->
<el-row :gutter="20" class="dashboard-overview" style="margin-top: 24px;">
<el-col :span="8">
<el-card>
<div slot="header">五种能源整体占比</div>
<div ref="overviewPie" style="height:260px;width:100%"></div>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<div slot="header">累计消耗柱状对比</div>
<div ref="overviewBar" style="height:260px;width:100%"></div>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<div slot="header">峰值需量仪表</div>
<div ref="overviewGauge" style="height:260px;width:100%"></div>
</el-card>
</el-col>
</el-row>
<!-- 原有的能源对比与效率分析 -->
<el-row :gutter="20" class="dashboard-compare" style="margin-top: 24px;">
<el-col :span="8">
<el-card>
<div slot="header">五种能源消耗堆叠柱状图</div>
<div ref="compareStackBar" style="height:220px;width:100%"></div>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<div slot="header">单位产出消耗强度雷达图</div>
<div ref="compareRadar" style="height:220px;width:100%"></div>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<div slot="header">气体类比压缩空气 vs 氮气</div>
<div ref="compareGas" style="height:220px;width:100%"></div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import * as echarts from 'echarts'
export default {
name: "YoyAnalysisReport",
data() {
return {
//
filterForm: {
area: '',
department: '',
circuit: '',
pipeline: '',
energyType: 'electricity',
timeDimension: 'day',
timeRange: [],
compareType: 'yoy'
},
//
keyMetrics: [
{ title: '同比增长率', value: '+12.5%', trend: 'up', description: '相比去年同期增长' },
{ title: '环比增长率', value: '-3.2%', trend: 'down', description: '相比上期下降' },
{ title: '平均能耗', value: '856.7 kWh', trend: 'up', description: '本期平均能耗' },
{ title: '峰值能耗', value: '1245.3 kWh', trend: 'up', description: '本期峰值能耗' }
],
//
pagination: {
currentPage: 1,
pageSize: 20,
total: 0
},
//
tableData: [],
//
charts: {},
//
overviewPieData: [
{ value: 800, name: '电' },
{ value: 500, name: '水' },
{ value: 300, name: '蒸汽' },
{ value: 200, name: '压缩空气' },
{ value: 100, name: '氮气' }
],
overviewBarData: [120, 800, 3200],
overviewBarLabels: ['本日', '本周', '本月'],
overviewGaugeData: [
{ value: 320, name: '电力峰值(kW)' },
{ value: 120, name: '蒸汽流量峰值(t/h)' }
],
//
compareStackBarLabels: ['本日','本周','本月'],
compareStackBarData: {
water: [12, 80, 320],
electricity: [22, 182, 391],
steam: [15, 132, 201],
air: [9, 77, 101],
nitrogen: [6, 72, 91]
},
compareRadarIndicators: [
{ name: '水', max: 100 },
{ name: '电', max: 100 },
{ name: '蒸汽', max: 100 },
{ name: '压缩空气', max: 100 },
{ name: '氮气', max: 100 }
],
compareRadarData: [60, 80, 70, 50, 40],
compareGasLabels: ['压力稳定性','泄漏率','单位产出成本'],
compareGasData: {
air: [90, 8, 0.5],
nitrogen: [85, 5, 0.7]
}
};
},
mounted() {
this.initFilterForm();
this.initAnalysisCharts();
this.initOverviewCharts();
this.initCompareCharts();
this.loadTableData();
},
methods: {
//
initFilterForm() {
const now = new Date();
const startDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
this.filterForm.timeRange = [
startDate.toISOString().slice(0, 19).replace('T', ' '),
now.toISOString().slice(0, 19).replace('T', ' ')
];
},
//
handleSearch() {
this.loadTableData();
this.updateCharts();
},
//
handleReset() {
this.filterForm = {
area: '',
department: '',
circuit: '',
pipeline: '',
energyType: 'electricity',
timeDimension: 'day',
timeRange: this.filterForm.timeRange,
compareType: 'yoy'
};
},
//
handleExport() {
this.$message.success('导出功能开发中...');
},
//
saveChart(chartName) {
if (this.charts[chartName]) {
const url = this.charts[chartName].getDataURL();
const link = document.createElement('a');
link.download = `${chartName}_${new Date().getTime()}.png`;
link.href = url;
link.click();
}
},
//
exportTable() {
this.$message.success('表格导出功能开发中...');
},
//
handleSizeChange(val) {
this.pagination.pageSize = val;
this.loadTableData();
},
handleCurrentChange(val) {
this.pagination.currentPage = val;
this.loadTableData();
},
//
loadTableData() {
//
const mockData = [];
for (let i = 0; i < 50; i++) {
const currentValue = Math.random() * 1000 + 500;
const compareValue = Math.random() * 1000 + 500;
const changeAmount = currentValue - compareValue;
const changeRate = ((changeAmount / compareValue) * 100).toFixed(2);
mockData.push({
time: `2024-06-${String(i + 1).padStart(2, '0')} ${String(Math.floor(Math.random() * 24)).padStart(2, '0')}:00:00`,
currentValue: currentValue.toFixed(2),
compareValue: compareValue.toFixed(2),
changeAmount: changeAmount.toFixed(2),
changeRate: changeRate,
status: Math.random() > 0.8 ? 'abnormal' : 'normal',
remark: Math.random() > 0.8 ? '能耗异常波动' : ''
});
}
this.tableData = mockData.slice(
(this.pagination.currentPage - 1) * this.pagination.pageSize,
this.pagination.currentPage * this.pagination.pageSize
);
this.pagination.total = mockData.length;
},
//
initAnalysisCharts() {
this.$nextTick(() => {
this.initTrendChart();
this.initTotalChart();
this.initProportionChart();
this.initRateChart();
});
},
//
initTrendChart() {
const chart = echarts.init(this.$refs.trendChart);
this.charts.trendChart = chart;
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['本期能耗', '对比期能耗', '变化率']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00']
},
yAxis: [
{
type: 'value',
name: '能耗(kWh)',
position: 'left'
},
{
type: 'value',
name: '变化率(%)',
position: 'right',
axisLabel: {
formatter: '{value}%'
}
}
],
series: [
{
name: '本期能耗',
type: 'bar',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '对比期能耗',
type: 'bar',
data: [110, 125, 95, 128, 85, 220, 200]
},
{
name: '变化率',
type: 'line',
yAxisIndex: 1,
data: [9.1, 5.6, 6.3, 4.7, 5.9, 4.5, 5.0]
}
]
};
chart.setOption(option);
},
//
initTotalChart() {
const chart = echarts.init(this.$refs.totalChart);
this.charts.totalChart = chart;
const option = {
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left'
},
series: [
{
name: '能耗对比',
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: '本期能耗' },
{ value: 735, name: '对比期能耗' }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
chart.setOption(option);
},
//
initProportionChart() {
const chart = echarts.init(this.$refs.proportionChart);
this.charts.proportionChart = chart;
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['本期占比', '对比期占比']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['照明', '动力', '空调', '其他']
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
series: [
{
name: '本期占比',
type: 'bar',
data: [25, 35, 30, 10]
},
{
name: '对比期占比',
type: 'bar',
data: [20, 40, 25, 15]
}
]
};
chart.setOption(option);
},
//
initRateChart() {
const chart = echarts.init(this.$refs.rateChart);
this.charts.rateChart = chart;
const option = {
tooltip: {
trigger: 'axis'
},
legend: {
data: ['同比增长率', '环比增长率']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
series: [
{
name: '同比增长率',
type: 'line',
stack: 'Total',
data: [12, 13, 10, 13, 9, 23, 21]
},
{
name: '环比增长率',
type: 'line',
stack: 'Total',
data: [2, 3, 1, 3, -1, 13, 11]
}
]
};
chart.setOption(option);
},
//
updateCharts() {
//
this.$message.success('图表数据已更新');
},
getLabel(type) {
const map = {
water: "水",
electricity: "电",
steam: "蒸汽",
air: "压缩空气",
nitrogen: "氮气"
};
return map[type] || type;
},
// 1.
initOverviewCharts() {
//
const pie = echarts.init(this.$refs.overviewPie);
pie.setOption({
tooltip: { trigger: 'item' },
legend: { bottom: 10, left: 'center' },
color: ['#5470C6', '#91CC75', '#FAC858', '#EE6666', '#73C0DE'],
series: [{
name: '能源占比',
type: 'pie',
radius: ['60%', '80%'],
label: { show: true, formatter: '{b}: {d}%' },
data: this.overviewPieData
}]
});
//
const bar = echarts.init(this.$refs.overviewBar);
bar.setOption({
xAxis: { type: 'category', data: this.overviewBarLabels },
yAxis: { type: 'value' },
series: [{
data: this.overviewBarData,
type: 'bar',
label: { show: true, position: 'top' },
itemStyle: {
color: function(params) {
const colors = ['#5470C6', '#91CC75', '#FAC858'];
return colors[params.dataIndex];
}
}
}]
});
//
const gauge = echarts.init(this.$refs.overviewGauge);
gauge.setOption({
series: [
{
type: 'gauge',
min: 0,
max: 500,
detail: { formatter: '{value}' },
data: [this.overviewGaugeData[0]],
title: { offsetCenter: [0, '-30%'] },
axisLine: { lineStyle: { width: 10 } },
pointer: { width: 5 }
},
{
type: 'gauge',
min: 0,
max: 200,
center: ['75%', '60%'],
radius: '40%',
detail: { formatter: '{value}' },
data: [this.overviewGaugeData[1]],
title: { offsetCenter: [0, '-30%'] },
axisLine: { lineStyle: { width: 6 } },
pointer: { width: 3 }
}
]
});
},
// 3.
initCompareCharts() {
//
const stackBar = echarts.init(this.$refs.compareStackBar);
stackBar.setOption({
tooltip: { trigger: 'axis' },
legend: { data: ['水', '电', '蒸汽', '压缩空气', '氮气'] },
xAxis: { type: 'category', data: this.compareStackBarLabels },
yAxis: { type: 'value' },
series: [
{ name: '水', type: 'bar', stack: 'total', data: this.compareStackBarData.water },
{ name: '电', type: 'bar', stack: 'total', data: this.compareStackBarData.electricity },
{ name: '蒸汽', type: 'bar', stack: 'total', data: this.compareStackBarData.steam },
{ name: '压缩空气', type: 'bar', stack: 'total', data: this.compareStackBarData.air },
{ name: '氮气', type: 'bar', stack: 'total', data: this.compareStackBarData.nitrogen }
]
});
//
const radar = echarts.init(this.$refs.compareRadar);
radar.setOption({
radar: { indicator: this.compareRadarIndicators },
series: [{
type: 'radar',
data: [{ value: this.compareRadarData, name: '单位产出能耗' }]
}]
});
//
const gas = echarts.init(this.$refs.compareGas);
gas.setOption({
tooltip: { trigger: 'axis' },
legend: { data: ['压缩空气', '氮气'] },
xAxis: { type: 'category', data: this.compareGasLabels },
yAxis: { type: 'value' },
series: [
{ name: '压缩空气', type: 'bar', data: this.compareGasData.air },
{ name: '氮气', type: 'bar', data: this.compareGasData.nitrogen }
]
});
}
}
}
</script>
<style scoped>
.energy-dashboard {
padding: 20px;
}
.filter-section {
background: #f5f7fa;
}
.visualization-section .el-card {
min-height: 350px;
}
.analysis-section .el-card {
min-height: 200px;
}
.table-section .el-card {
min-height: 400px;
}
.metric-card {
background: #f5f7fa;
border-radius: 8px;
padding: 15px;
text-align: center;
margin-bottom: 10px;
}
.metric-title {
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
.metric-value {
font-size: 24px;
font-weight: bold;
margin: 8px 0;
display: flex;
align-items: center;
justify-content: center;
}
.metric-value.up {
color: #67C23A;
}
.metric-value.down {
color: #F56C6C;
}
.metric-desc {
font-size: 12px;
color: #999;
}
.text-danger {
color: #F56C6C;
}
.text-success {
color: #67C23A;
}
.dashboard-overview .el-card {
min-height: 300px;
}
</style>
Loading…
Cancel
Save