220 lines
4.2 KiB
Vue
220 lines
4.2 KiB
Vue
<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> |