調整近30天能耗趨勢、環比能耗(假資料)
This commit is contained in:
parent
8d23b695c6
commit
1812ce2495
BIN
public/CviLux_globalmap.jpg
Normal file
BIN
public/CviLux_globalmap.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
@ -80,10 +80,16 @@ onUnmounted(() => {
|
||||
未來,瀚荃會持續精進提供更快、更好以及高附加價值的產品與服務來滿足您的需求。
|
||||
</p>
|
||||
</div>
|
||||
<!--狀態、進度-->
|
||||
<!--在線狀態-->
|
||||
<SysProgress />
|
||||
</div>
|
||||
<div class="w-full xl:w-2/4 mt-2"></div>
|
||||
<div class="w-full xl:w-2/4 max-h-[calc(100vh-90px)] mt-2 border border-cyan-400 shadow-md shadow-cyan-500/40">
|
||||
<img
|
||||
src="/CviLux_globalmap.jpg"
|
||||
alt=""
|
||||
class="w-full h-full invert object-cover "
|
||||
/>
|
||||
</div>
|
||||
<div class="w-full xl:w-1/4 mt-2">
|
||||
<ElecRank :energyCostData="energyCostData" />
|
||||
<ElecTrends
|
||||
@ -98,6 +104,6 @@ onUnmounted(() => {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.area-img-box {
|
||||
@apply border border-light-info bg-gray-900/80 backdrop-blur-lg relative overflow-hidden shadow-md shadow-blue-300 mb-3;
|
||||
@apply border border-light-info bg-gray-900/80 backdrop-blur-lg relative overflow-hidden shadow-md shadow-blue-300 mb-4;
|
||||
}
|
||||
</style>
|
||||
|
@ -5,90 +5,100 @@ import BarChart from "@/components/chart/BarChart.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { locale, t } = useI18n();
|
||||
const props = defineProps({
|
||||
energyCostData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
|
||||
// 假資料
|
||||
const fakeEnergyData = ref({
|
||||
buildings: [
|
||||
{
|
||||
name: "A棟",
|
||||
today: 100,
|
||||
yesterday: 90,
|
||||
week: 500,
|
||||
lastWeek: 450,
|
||||
month: 2000,
|
||||
lastMonth: 1800,
|
||||
year: 24000,
|
||||
lastYear: 22000,
|
||||
},
|
||||
{
|
||||
name: "B棟",
|
||||
today: 120,
|
||||
yesterday: 110,
|
||||
week: 600,
|
||||
lastWeek: 550,
|
||||
month: 2400,
|
||||
lastMonth: 2200,
|
||||
year: 28000,
|
||||
lastYear: 26000,
|
||||
},
|
||||
{
|
||||
name: "C棟",
|
||||
today: 80,
|
||||
yesterday: 70,
|
||||
week: 400,
|
||||
lastWeek: 350,
|
||||
month: 1600,
|
||||
lastMonth: 1400,
|
||||
year: 19000,
|
||||
lastYear: 17000,
|
||||
},
|
||||
{
|
||||
name: "D棟",
|
||||
today: 110,
|
||||
yesterday: 100,
|
||||
week: 550,
|
||||
lastWeek: 500,
|
||||
month: 2200,
|
||||
lastMonth: 2000,
|
||||
year: 26000,
|
||||
lastYear: 24000,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const chartData = ref([]); // 初始化為空陣列
|
||||
|
||||
const labels = computed(() => [
|
||||
t("dashboard.today"),
|
||||
t("dashboard.yesterday"),
|
||||
t("dashboard.this_week"),
|
||||
t("dashboard.last_week"),
|
||||
t("dashboard.this_month"),
|
||||
t("dashboard.last_month"),
|
||||
t("dashboard.this_year"),
|
||||
t("dashboard.last_year"),
|
||||
const chartData = ref([]);
|
||||
const currentType = ref({
|
||||
name: "today",
|
||||
});
|
||||
const energyTypeList = ref([
|
||||
{
|
||||
title: t("dashboard.daily_relative_change"),
|
||||
key: "today",
|
||||
},
|
||||
{
|
||||
title: t("dashboard.weekly_relative_change"),
|
||||
key: "week",
|
||||
},
|
||||
{
|
||||
title: t("dashboard.monthly_relative_change"),
|
||||
key: "month",
|
||||
},
|
||||
{
|
||||
title: t("dashboard.yearly_relative_change"),
|
||||
key: "year",
|
||||
},
|
||||
]);
|
||||
|
||||
const labels = computed(() => {
|
||||
switch (currentType.value.name) {
|
||||
case "today":
|
||||
return [t("dashboard.today"), t("dashboard.yesterday")];
|
||||
case "week":
|
||||
return [t("dashboard.this_week"), t("dashboard.last_week")];
|
||||
case "month":
|
||||
return [t("dashboard.this_month"), t("dashboard.last_month")];
|
||||
case "year":
|
||||
return [t("dashboard.this_year"), t("dashboard.last_year")];
|
||||
default:
|
||||
return [t("dashboard.today"), t("dashboard.yesterday")];
|
||||
}
|
||||
});
|
||||
const barWidth = 30; // Set barWidth
|
||||
|
||||
const barChartOptions = ref({
|
||||
const barChartOptions = computed(() => ({
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: chartData.value.map((item) => item.category),
|
||||
axisLine: { lineStyle: { color: "#fff" } },
|
||||
},
|
||||
yAxis: { type: "value", show: false },
|
||||
series: [], // 初始化為空陣列
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: { type: "shadow" },
|
||||
formatter: function (params) {
|
||||
let tooltipText = `<div>${params[0].axisValueLabel}</div>`;
|
||||
const filteredParams = params.filter((item) => item.seriesType === "bar");
|
||||
filteredParams.forEach((item) => {
|
||||
tooltipText += `<div>${item.marker} ${
|
||||
item.value ? item.value : "-"
|
||||
}</div>`;
|
||||
});
|
||||
|
||||
return tooltipText;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
function updateChartData(newEnergyCostData) {
|
||||
if (newEnergyCostData && newEnergyCostData.compare) {
|
||||
// 從 props.energyCostData.compare 中提取資料
|
||||
const compareData = newEnergyCostData.compare;
|
||||
|
||||
// 轉換資料格式
|
||||
chartData.value = [
|
||||
{
|
||||
category: t("dashboard.daily_relative_change"),
|
||||
this: compareData.day.current,
|
||||
last: compareData.day.last,
|
||||
change: compareData.day.percentage,
|
||||
},
|
||||
{
|
||||
category: t("dashboard.weekly_relative_change"),
|
||||
this: compareData.week.current,
|
||||
last: compareData.week.last,
|
||||
change: compareData.week.percentage,
|
||||
},
|
||||
{
|
||||
category: t("dashboard.monthly_relative_change"),
|
||||
this: compareData.month.current,
|
||||
last: compareData.month.last,
|
||||
change: compareData.month.percentage,
|
||||
},
|
||||
{
|
||||
category: t("dashboard.yearly_relative_change"),
|
||||
this: compareData.year.current,
|
||||
last: compareData.year.last,
|
||||
change: compareData.year.percentage,
|
||||
},
|
||||
];
|
||||
|
||||
// 更新 barChartOptions
|
||||
barChartOptions.value = {
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: chartData.value.map((item) => item.category),
|
||||
data: chartData.value.map((item) => item.name),
|
||||
axisLine: { lineStyle: { color: "#fff" } },
|
||||
},
|
||||
yAxis: { type: "value", show: false },
|
||||
@ -101,8 +111,8 @@ function updateChartData(newEnergyCostData) {
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "當前週期",
|
||||
data: chartData.value.map((item) => item.this),
|
||||
name: "當前",
|
||||
data: chartData.value.map((item) => item.current),
|
||||
type: "bar",
|
||||
barWidth: barWidth,
|
||||
barGap: "-10%",
|
||||
@ -119,7 +129,7 @@ function updateChartData(newEnergyCostData) {
|
||||
z: 3,
|
||||
},
|
||||
{
|
||||
name: "對比週期",
|
||||
name: "對比",
|
||||
data: chartData.value.map((item) => item.last),
|
||||
type: "bar",
|
||||
barWidth: barWidth,
|
||||
@ -139,7 +149,7 @@ function updateChartData(newEnergyCostData) {
|
||||
z: 6,
|
||||
type: "pictorialBar",
|
||||
symbolPosition: "end",
|
||||
data: chartData.value.map((item) => item.this),
|
||||
data: chartData.value.map((item) => item.current),
|
||||
symbol: "diamond",
|
||||
symbolOffset: ["-45%", "-50%"],
|
||||
symbolSize: [barWidth, barWidth * 0.5],
|
||||
@ -153,7 +163,7 @@ function updateChartData(newEnergyCostData) {
|
||||
z: 6,
|
||||
type: "pictorialBar",
|
||||
symbolPosition: "start",
|
||||
data: chartData.value.map((item) => item.this),
|
||||
data: chartData.value.map((item) => item.current),
|
||||
symbol: "diamond",
|
||||
symbolOffset: ["-45%", "50%"],
|
||||
symbolSize: [barWidth, barWidth * 0.5],
|
||||
@ -196,9 +206,7 @@ function updateChartData(newEnergyCostData) {
|
||||
axisPointer: { type: "shadow" },
|
||||
formatter: function (params) {
|
||||
let tooltipText = `<div>${params[0].axisValueLabel}</div>`;
|
||||
const filteredParams = params.filter(
|
||||
(item) => item.seriesType === "bar"
|
||||
);
|
||||
const filteredParams = params.filter((item) => item.seriesType === "bar");
|
||||
filteredParams.forEach((item) => {
|
||||
tooltipText += `<div>${item.marker} ${
|
||||
item.value ? item.value : "-"
|
||||
@ -208,20 +216,56 @@ function updateChartData(newEnergyCostData) {
|
||||
return tooltipText;
|
||||
},
|
||||
},
|
||||
};
|
||||
}));
|
||||
|
||||
function updateChartData() {
|
||||
// 從 fakeEnergyData 提取資料
|
||||
chartData.value = fakeEnergyData.value.buildings.map((building) => {
|
||||
let currentKey = currentType.value.name;
|
||||
let lastKey;
|
||||
|
||||
switch (currentType.value.name) {
|
||||
case "today":
|
||||
lastKey = "yesterday";
|
||||
break;
|
||||
case "week":
|
||||
lastKey = "lastWeek";
|
||||
break;
|
||||
case "month":
|
||||
lastKey = "lastMonth";
|
||||
break;
|
||||
case "year":
|
||||
lastKey = "lastYear";
|
||||
break;
|
||||
default:
|
||||
lastKey = "yesterday";
|
||||
}
|
||||
|
||||
return {
|
||||
name: building.name,
|
||||
current: building[currentKey],
|
||||
last: building[lastKey],
|
||||
difference: building[currentKey] - building[lastKey],
|
||||
};
|
||||
});
|
||||
}
|
||||
// 使用 watch 監聽 energyCostData 的變化
|
||||
|
||||
// 使用 watch 監聽 fakeEnergyData 的變化
|
||||
watch(
|
||||
() => props.energyCostData,
|
||||
(newEnergyCostData) => {
|
||||
updateChartData(newEnergyCostData);
|
||||
() => [fakeEnergyData.value, currentType.value],
|
||||
() => {
|
||||
updateChartData();
|
||||
},
|
||||
{ immediate: true } // 立即執行一次,確保初始資料載入
|
||||
{ deep: true, immediate: true } // 立即執行一次,確保初始資料載入
|
||||
);
|
||||
|
||||
// 监听 currentType 的变化
|
||||
watch(currentType, () => {
|
||||
updateChartData();
|
||||
});
|
||||
|
||||
watch(locale, () => {
|
||||
updateChartData(props.energyCostData);
|
||||
updateChartData();
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -229,9 +273,20 @@ watch(locale, () => {
|
||||
<div class="flex flex-wrap">
|
||||
<div class="w-full chart-data relative px-3 mb-3">
|
||||
<div class="flex flex-wrap items-center justify-between">
|
||||
<h2 class="font-light">
|
||||
<h2 class="font-light pt-1 px-1">
|
||||
{{ $t("dashboard.relative_energy_consumption") }}
|
||||
</h2>
|
||||
<Select
|
||||
:value="currentType"
|
||||
class="!w-24"
|
||||
selectClass="border-info focus-within:border-info btn-xs text-xs"
|
||||
name="name"
|
||||
Attribute="title"
|
||||
:options="energyTypeList"
|
||||
:isTopLabelExist="false"
|
||||
:isBottomLabelExist="false"
|
||||
>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="h-[100px]">
|
||||
<BarChart
|
||||
@ -249,19 +304,19 @@ watch(locale, () => {
|
||||
class="w-1/4 text-center mx-1"
|
||||
>
|
||||
<div
|
||||
class="text-sm bg-cyan-900 p-1 border border-cyan-100 border-opacity-20"
|
||||
class="text-xs bg-cyan-900 p-1 border border-cyan-100 border-opacity-20"
|
||||
>
|
||||
{{ labels[index * 2] }}
|
||||
{{ labels[0] }}
|
||||
</div>
|
||||
<div
|
||||
class="text-sm bg-cyan-900 p-1 border border-cyan-100 border-opacity-20"
|
||||
>
|
||||
{{ data.this ?? "-" }}
|
||||
{{ data.current ?? "-" }}
|
||||
</div>
|
||||
<div
|
||||
class="text-sm bg-cyan-900 p-1 border border-cyan-100 border-opacity-20"
|
||||
class="text-xs bg-cyan-900 p-1 border border-cyan-100 border-opacity-20"
|
||||
>
|
||||
{{ labels[index * 2 + 1] }}
|
||||
{{ labels[1] }}
|
||||
</div>
|
||||
<div
|
||||
class="text-sm bg-cyan-900 p-1 border border-cyan-100 border-opacity-20"
|
||||
@ -273,13 +328,13 @@ watch(locale, () => {
|
||||
>
|
||||
<span
|
||||
:class="{
|
||||
'text-red-500': data.change > 0,
|
||||
'text-green-500': data.change < 0,
|
||||
'text-red-500': data.difference > 0,
|
||||
'text-green-500': data.difference < 0,
|
||||
}"
|
||||
>
|
||||
{{
|
||||
data.change
|
||||
? (data.change > 0 ? "+" : "") + data.change + "%"
|
||||
data.difference
|
||||
? (data.difference > 0 ? "+" : "") + data.difference
|
||||
: "-"
|
||||
}}
|
||||
</span>
|
||||
|
@ -37,7 +37,7 @@ const getCurrentEnergyData = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="state-box-col relative h-full max-h-[200px] mb-3">
|
||||
<div class="state-box-col relative h-full max-h-[190px] mb-3">
|
||||
<div class="state-box h-full">
|
||||
<!-- 標題和切換按鈕 -->
|
||||
<div class="flex justify-between items-center mb-2">
|
||||
@ -58,7 +58,7 @@ const getCurrentEnergyData = () => {
|
||||
</div>
|
||||
|
||||
<!-- 能耗排名列表 -->
|
||||
<div class="max-h-[150px] overflow-y-auto">
|
||||
<div class="max-h-[140px] overflow-y-auto">
|
||||
<table class="table table-sm text-center">
|
||||
<tbody>
|
||||
<tr
|
||||
|
@ -21,15 +21,17 @@ const props = defineProps({
|
||||
getEnergyCostData: {
|
||||
type: Function,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const chartData = ref([]);
|
||||
const buildingList = ref([]);
|
||||
const floorList = ref([]);
|
||||
const deptList = ref([]);
|
||||
const weekComparisonOption = ref({});
|
||||
|
||||
const currentType = ref({
|
||||
name: "all",
|
||||
});
|
||||
// 生成柱狀圖的 option
|
||||
const generateCylinderChartOption = (data) => {
|
||||
const barWidth = 15;
|
||||
@ -98,7 +100,7 @@ const generateCylinderChartOption = (data) => {
|
||||
left: "0%",
|
||||
right: "0%",
|
||||
bottom: "3%",
|
||||
top: "10%",
|
||||
top: "17%",
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
@ -139,17 +141,18 @@ watch(
|
||||
);
|
||||
|
||||
watch(
|
||||
() => storeBuild.floorList,
|
||||
() => storeBuild.buildings,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
console.log('newValue',newValue);
|
||||
|
||||
floorList.value = [
|
||||
buildingList.value = [
|
||||
{
|
||||
title: "All",
|
||||
key: "all",
|
||||
},
|
||||
...storeBuild.floorList,
|
||||
...newValue.map((building) => ({
|
||||
title: building.full_name,
|
||||
key: building.building_guid,
|
||||
})),
|
||||
];
|
||||
}
|
||||
},
|
||||
@ -162,6 +165,7 @@ watch(
|
||||
() => storeBuild.floorList,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
|
||||
floorList.value = [
|
||||
{
|
||||
title: "All",
|
||||
@ -175,7 +179,6 @@ watch(
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => storeBuild.deptList,
|
||||
(newValue) => {
|
||||
@ -199,7 +202,20 @@ watch(
|
||||
<template>
|
||||
<div class="w-full chart-data relative px-3 mb-3">
|
||||
<div class="flex flex-wrap items-center justify-between">
|
||||
<h2 class="font-light">{{ $t("dashboard.last_30_days_energy_trend") }}</h2>
|
||||
<h2 class="font-light pt-1 px-1">
|
||||
{{ $t("dashboard.last_30_days_energy_trend") }}
|
||||
</h2>
|
||||
<Select
|
||||
:value="currentType"
|
||||
class="w-auto my-2"
|
||||
selectClass="border-info focus-within:border-info btn-xs text-xs"
|
||||
name="name"
|
||||
Attribute="title"
|
||||
:options="buildingList"
|
||||
:isTopLabelExist="false"
|
||||
:isBottomLabelExist="false"
|
||||
>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="h-[200px]">
|
||||
<BarChart
|
||||
|
@ -114,7 +114,7 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.state-box {
|
||||
@apply h-[21rem] border border-light-info shadow-md shadow-blue-300 rounded-sm py-2 px-6 mb-5 text-white relative;
|
||||
@apply h-[21rem] border border-light-info shadow-md shadow-blue-300 rounded-sm py-2 px-6 mb-2 text-white relative;
|
||||
}
|
||||
|
||||
.state-box:after {
|
||||
|
Loading…
Reference in New Issue
Block a user