empower_front/src/views/dashboard/components/DashboardHumidity.vue
MJM_2025_05\polly 2e15353384 fix: 首頁與歷史資料頁圖表顯示優化
首頁:

1. 室內/冷藏與溫度/濕度位置互換

2. 碳排圖表改為顯示「每日」資料

3. 平面圖點擊 icons 顯示彈跳視窗

歷史資料頁:

1. 調整折線圖 X 軸過密的顯示問題
2025-07-31 11:01:07 +08:00

185 lines
4.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import LineChart from "@/components/chart/LineChart.vue";
import { SECOND_CHART_COLOR } from "@/constant";
import dayjs from "dayjs";
import { ref, watch, onMounted, onUnmounted, computed } from "vue";
import useActiveBtn from "@/hooks/useActiveBtn";
import { getDashboardTemp } from "@/apis/dashboard";
import useSearchParams from "@/hooks/useSearchParam";
import useBuildingStore from "@/stores/useBuildingStore";
import { useI18n } from "vue-i18n";
const { t, locale } = useI18n();
const { searchParams } = useSearchParams();
const buildingStore = useBuildingStore();
const intervalType = "immediateTemp";
const timeoutTimer = ref("");
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
const data = ref([]);
const other_real_temp_chart = ref(null);
const currentOptionType = ref(1); // 1: 溫度, 2: 濕度
const noData = ref(false);
const defaultChartOption = ref({
tooltip: {
trigger: "axis",
},
legend: {
data: [],
textStyle: {
color: "#ffffff",
fontSize: 16,
},
},
grid: {
top: "10%",
left: "0%",
right: "0%",
bottom: "0%",
containLabel: true,
},
xAxis: {
type: "category",
splitLine: { show: false },
axisLabel: { color: "#ffffff" },
data: [],
},
yAxis: {
type: "value",
splitLine: { show: false },
axisLabel: { color: "#ffffff" },
},
series: [],
});
const getData = async () => {
const res = await getDashboardTemp({
building_guid: buildingStore.selectedBuilding.building_guid,
tempOption: 2, // 參數 tempOption 1:室溫 2:冷藏
timeInterval: 1,
option: currentOptionType.value, // 參數 option1:溫度 2:濕度
});
if (res.isSuccess) {
const key = "冷藏溫度";
const label = currentOptionType.value === 1 ? "溫度" : "濕度";
console.log(`冷藏${label}資料:`, res.data[key]);
data.value = res.data[key] || [];
noData.value = !data.value || data.value.length === 0;
} else {
noData.value = true;
}
};
const buttonItems = computed(() => [
{ key: 1, title: t("dashboard.temperature"), active: true },
{ key: 2, title: t("dashboard.humidity"), active: false },
]);
// 當語言改變時,重新設定項目
watch(
() => locale.value,
() => {
setItems(buttonItems.value);
},
{ immediate: true }
);
watch(
selectedBtn,
(newValue) => {
if (timeoutTimer.value) {
clearInterval(timeoutTimer.value);
}
if (newValue?.key === 1 || newValue?.key === 2) {
currentOptionType.value = newValue.key;
getData();
timeoutTimer.value = setInterval(() => {
getData();
}, 60 * 1000);
}
},
{ immediate: true, deep: true }
);
watch(
data,
(newValue) => {
if (newValue?.length > 0 && other_real_temp_chart.value?.chart) {
const firstItem = newValue[0];
if (firstItem?.data?.length > 0) {
const validData = firstItem.data.filter(
(item) => item.value !== null && item.value !== undefined
);
if (validData.length > 0) {
const minValue = Math.min(...validData.map(({ value }) => value));
const maxValue = Math.max(...validData.map(({ value }) => value));
other_real_temp_chart.value.chart.setOption({
legend: {
data: newValue.map(({ full_name }) => full_name),
},
xAxis: {
data: firstItem.data.map(({ time }) =>
dayjs(time).format("HH:mm:ss")
),
},
yAxis: {
min: Math.floor(minValue),
max: Math.ceil(maxValue),
},
series: newValue.map(({ full_name, data }, index) => ({
name: full_name,
type: "line",
data: data.map(({ value }) => value),
showSymbol: false,
itemStyle: {
color: SECOND_CHART_COLOR[index % SECOND_CHART_COLOR.length],
},
})),
});
}
}
}
},
{ deep: true }
);
onUnmounted(() => {
if (timeoutTimer.value) {
clearInterval(timeoutTimer.value);
}
});
</script>
<template>
<h3 class="text-info text-xl text-center">
{{ $t("dashboard.refrig_chart") }}
</h3>
<div className="my-3 w-full flex justify-center relative">
<ButtonConnectedGroup
:items="items"
:onclick="(e, item) => changeActiveBtn(item)"
/>
</div>
<div
v-if="noData"
class="text-center text-white text-lg min-h-[260px] flex items-center justify-center"
>
無資料
</div>
<LineChart
v-else
id="dashboard_other_real_temp"
class="min-h-[260px] max-h-fit"
:option="defaultChartOption"
ref="other_real_temp_chart"
/>
</template>
<style lang="scss" scoped></style>