Files
maintenance_system/src/views/pvSystem/operatingCurve/components/box2/powerBar.vue

220 lines
4.2 KiB
Vue
Raw Normal View History

2025-09-17 16:54:39 +08:00
<template>
<div class="chart-container">
<div class="chart-header">
<h2>发电量预测对比</h2>
<p>实际发电量与预测值偏差在u±5%以内处于合理范围预测模型准确度较高</p>
</div>
<div class="chart-content" ref="chartRef"></div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import * as echarts from 'echarts';
// 接收从父组件传入的数据
const props = defineProps({
powerBarData: {
type: Object,
default: () => ({
xAxis: ['上周', '本周'],
actualData: [],
forecastData: []
})
}
});
const chartRef = ref<HTMLDivElement>();
let chartInstance: echarts.ECharts | null = null;
// 初始化图表
const initChart = async () => {
await nextTick();
if (!chartRef.value) return;
// 销毁已存在的图表实例
if (chartInstance) {
chartInstance.dispose();
}
// 创建新的图表实例
chartInstance = echarts.init(chartRef.value);
// 使用传入的数据,如果不存在则使用默认数据
const data = props.powerBarData;
// 图表配置
const option = {
tooltip: {
backgroundColor: 'rgba(13, 64, 71, 0.50)',
borderColor: 'rgba(143, 225, 252, 0.60)',
textStyle: {
color: '#fff'
},
padding: 10,
borderRadius: 4,
},
legend: {
data: ['实际发电量', '预测发电量'],
itemWidth: 14,
itemHeight: 10,
itemGap: 4,
textStyle: {
fontSize: 12,
color: '#666'
}
},
xAxis: {
type: 'category',
data: data.xAxis,
axisPointer: {
type: 'shadow'
},
axisLabel: {
textStyle: {
color: '#3E4954',
fontSize: 12
}
},
axisLine: {
lineStyle: {
color: '#ccc'
}
},
},
yAxis: {
type: 'value',
min: 0,
max: 10000,
interval: 5000,
axisLine: {
show: false
},
axisTick: {
show: false
},
splitLine: {
lineStyle: {
color: '#f0f0f0',
type: 'dashed'
}
}
},
series: [
{
name: '实际发电量',
type: 'bar',
data: data.actualData,
itemStyle: {
color: '#1a77dd',
borderRadius: [8, 8, 0, 0] // 设置圆角,上左、上右、下右、下左
},
barWidth: 60
},
{
name: '预测发电量',
type: 'bar',
data: data.forecastData,
itemStyle: {
color: '#7c3aed',
borderRadius: [8, 8, 0, 0] // 设置圆角,上左、上右、下右、下左
},
emphasis: {
itemStyle: {
color: '#6d28d9' // 悬停时的颜色
}
},
barWidth: 60
}
]
};
// 设置图表配置
chartInstance.setOption(option);
};
// 窗口大小改变时重新调整图表
const handleResize = () => {
if (chartInstance) {
chartInstance.resize();
}
};
// 生命周期钩子
onMounted(() => {
initChart();
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
}
});
</script>
<style scoped>
.chart-container {
width: 100%;
height: 100%;
padding: 0 16px;
box-sizing: border-box;
background-color: #fff;
border-radius: 8px;
}
.chart-header {
margin-bottom: 16px;
}
.chart-header h2 {
font-size: 16px;
font-weight: 600;
color: #333;
margin: 0;
}
.chart-header p {
font-size: 12px;
color: #666;
margin: 0;
}
.chart-content {
width: 100%;
height: calc(100% - 80px);
min-height: 200px;
}
@media (max-width: 768px) {
.chart-container {
padding: 12px;
}
.chart-content {
height: calc(100% - 70px);
min-height: 280px;
}
}
@media (max-width: 480px) {
.chart-container {
padding: 10px;
}
.chart-header h2 {
font-size: 16px;
}
.chart-header p {
font-size: 11px;
}
.chart-content {
height: calc(100% - 65px);
min-height: 250px;
}
}
</style>