CviLux_fe/src/views/energyManagement/components/EnergyChart/ElecConsumption.vue

154 lines
3.5 KiB
Vue

<script setup>
import { ref, onMounted, watch, inject } from "vue";
import * as echarts from "echarts";
import { getRealTimeDist } from "@/apis/energy";
import { useI18n } from "vue-i18n";
const { search_data } = inject("energy_data");
const { t } = useI18n();
const chartDiv = ref(null);
let myChart = null; // 添加 myChart 变量
const chartOption = {
tooltip: {
trigger: "item",
formatter: (p) => {
return `${p.name}: ${p.value}kWh (${p.data.percentage}%)`;
},
},
series: [
{
type: "sankey",
layout: "none",
nodeWidth: 10,
nodeGap: 10,
right: 180,
data: [],
links: [],
emphasis: {
focus: "adjacency",
},
label: {
position: "right",
fontSize: 14,
color: "#fff",
formatter: (p) => {
return `${p.name} (${p.data.percentage}%)`;
},
},
itemStyle: {
borderWidth: 0,
},
lineStyle: {
color: "gradient",
opacity: 0.7,
curveness: 0.5,
},
},
],
};
const loadData = async (value) => {
const res = await getRealTimeDist(value);
if (res.isSuccess && res.data && res.data.length !== 0) {
const rawData = res.data;
if (rawData) {
const totalValue = rawData.reduce((acc, item) => acc + item.value, 0);
const sortedData = [...rawData].sort((a, b) => b.value - a.value);
// 構造 data 節點
const data = [
{ name: "Total", value: totalValue, percentage: 100 },
...sortedData.map((item) => ({
name: item.key,
value: item.value,
percentage: item.percentage,
})),
];
// 構造 links 連結
const links = sortedData.map((item, index) => ({
source: "Total",
target: item.key,
value: item.value,
percentage: item.percentage,
}));
const colors = [
"#45f4ef",
"#17CEE3",
"#E4EA00",
"#62E39A",
"#E9971F",
"#E52EFF",
];
// 更新 chartOption
chartOption.series[0].data = data.map((item, index) => ({
...item,
itemStyle: {
color: colors[index % colors.length], // 節點顏色
},
}));
chartOption.series[0].links = links;
// 初始化圖表
if (myChart) {
myChart.dispose(); // 銷毀之前的實例
}
myChart = echarts.init(chartDiv.value);
myChart.setOption(chartOption);
}
} else {
// 清空圖表
if (myChart) {
myChart.dispose(); // 銷毀之前的實例
myChart = null;
}
}
};
watch(
search_data,
(newValue, oldValue) => {
if (
newValue.building_guid &&
JSON.stringify(newValue) !== JSON.stringify(oldValue)
) {
loadData(newValue);
}
},
{
immediate: true,
deep: true,
}
);
onMounted(() => {
// 初始化圖表
myChart = echarts.init(chartDiv.value);
myChart.setOption(chartOption);
});
</script>
<template>
<div class="p-3">
<h2 class="text text-lg text-white mb-5 relative">
{{ $t("energy.elec_consumption") }}
</h2>
<div class="chart-container">
<div ref="chartDiv" class="w-full min-h-[200px] h-full"></div>
</div>
</div>
</template>
<style lang="scss" scoped>
.text::after {
@apply absolute -bottom-2.5 left-0 block w-3/5 h-[1px] bg-slate-600;
content: "";
}
ul li:last-child:after {
@apply absolute top-0 bottom-0 left-full block w-full h-[1px] bg-slate-600 m-auto z-10;
content: "";
}
</style>