因為放在了子組件才監聽,加載渲染調用,有暗黑模式才調用,
<!-- 溫濕度傳感器 --><el-row v-if="deviceTypeId === '2'"><el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24"><div class="chart-container"><div class="filter-container"><el-radio-group v-model="WenduTimeType" size="small" @change="generateWenduData"><el-radio-button label="day">日</el-radio-button><el-radio-button label="month">月</el-radio-button><el-radio-button label="year">年</el-radio-button></el-radio-group></div><div id="wenduRef" ref="wendurRef" style=" width: 100%;height: 400px;" class="chart wendu-chart"></div></div></el-col></el-row>
const timeType = ref<'day' | 'month' | 'year' | 'hour'>('day')
const selectedHour = ref<Date>(new Date())
const selectedDay = ref<Date>(new Date())
const selectedMonth = ref<Date>(new Date())
const selectedYear = ref<Date>(new Date())
const radarTimeType = ref<'day' | 'month' | 'year' | 'hour'>('day')
const radarSelectedHour = ref<Date>(new Date())
const radarSelectedDay = ref<Date>(new Date())
const radarSelectedMonth = ref<Date>(new Date())
const radarSelectedYear = ref<Date>(new Date())
const WenduTimeType = ref<'day' | 'month' | 'year' | 'hour'>('day')
const WenduSelectedHour = ref<Date>(new Date())
const WenduSelectedDay = ref<Date>(new Date())
const WenduSelectedMonth = ref<Date>(new Date())
const WenduSelectedYear = ref<Date>(new Date())
const chartRef = ref<HTMLElement | null>(null)
const radarRef = ref<HTMLElement | null>(null)
const wenduRef = ref<HTMLElement | null>(null)// 計量圖表數據
const chartXAxisData = ref<string[]>([])
const chartData = ref<number[]>([])
const RadarXAxisData = ref<string[]>([])
const RadarData = ref<number[]>([])
const WenduXAxisDatatem = ref<string[]>([])
const WenduDatatem = ref<number[]>([])
const WenduXAxisDatahum = ref<string[]>([])
const WenduDatahum = ref<number[]>([])
const WenduXAxisDataill = ref<string[]>([])
const WenduDataill = ref<number[]>([])
// 新增溫濕度圖數據生成函數
function generateWenduData() {let timeAmount = '1';let timeUnit = 'd';if (WenduTimeType.value === 'day') timeUnit = 'd';else if (WenduTimeType.value === 'month') timeUnit = 'mo';else if (WenduTimeType.value === 'year') timeUnit = 'y';else if (WenduTimeType.value === 'hour') timeUnit = 'h';DashAPI.getsensor({// deviceCode: props.deviceCode,deviceCode: deviceCodeCS.value,timeAmount,timeUnit,roomId: roomId.value}).then(res => {const data = Array.isArray(res) ? res : [];const tem = data.find((item: any) => item.name === "temperature");const hum = data.find((item: any) => item.name === "humidity");const ill = data.find((item: any) => item.name === "illuminance");WenduXAxisDatatem.value = tem?.time || [];WenduDatatem.value = tem?.value || [];WenduXAxisDatahum.value = hum?.time || [];WenduDatahum.value = hum?.value || [];WenduXAxisDataill.value = ill?.time || [];WenduDataill.value = ill?.value || [];console.log("getsensor", data);updateWenduChart();});
}
// 新增溫濕度圖更新方法
function updateWenduChart(retry = 0) {function tryWendu() {const chartDom = document.querySelector('.wendu-chart') as HTMLElement;if (!chartDom || chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) {requestAnimationFrame(tryWendu);return;}// 1. ECharts實例和DOM同步if (wenduChart.value &&typeof (wenduChart.value as any).getDom === 'function' &&(wenduChart.value as any).getDom() !== chartDom) {wenduChart.value.dispose();wenduChart.value = null;}if (!wenduChart.value) {wenduChart.value = echarts.init(chartDom);}const option = {color: ['#5470C6', '#91CC75', '#EE6666'],tooltip: { trigger: 'axis', axisPointer: { type: 'cross' } },grid: {right: '20%'},xAxis: [{type: 'category',axisTick: { alignWithLabel: true, color: getTextColor() },data: WenduXAxisDatatem.value, // 以溫度時間為主axisLine: { lineStyle: { color: getTextColor() } }}],yAxis: [{ type: 'value', name: '溫度°C', position: 'left', alignTicks: true, axisLine: { show: true, lineStyle: { color: '#5470C6' } }, axisLabel: { formatter: '{value}' } },{ type: 'value', name: '濕度%', position: 'right', alignTicks: true, axisLine: { show: true, lineStyle: { color: '#91CC75' } }, axisLabel: { formatter: '{value} ' } },{ type: 'value', name: '光照lux', position: 'right', alignTicks: true, offset: 80, axisLine: { show: true, lineStyle: { color: '#EE6666' } }, axisLabel: { formatter: '{value} ' } }],series: [{ name: '溫度', type: 'line', yAxisIndex: 0, data: WenduDatatem.value },{ name: '濕度', type: 'line', yAxisIndex: 1, data: WenduDatahum.value },{ name: '光照', type: 'line', yAxisIndex: 2, data: WenduDataill.value }]};wenduChart.value.setOption(option);wenduChart.value.resize();};tryWendu()
}
// 監聽 deviceInfo 變化時,初始化新圖表
watch(() => props.deviceInfo, () => {nextTick(() => {charts.value.forEach((chart: any) => chart.dispose());charts.value = [];initTemperatureGauge();initHumidityGauge();if (props.deviceTypeId === '6' || props.deviceTypeId === '5') {generateRadarData();//雷達} else if (props.deviceTypeId === '4' || props.deviceTypeId === '8') {// 清空舊數據,確保圖表使用新數據chartXAxisData.value = [];chartData.value = [];fetchMeasurementData();//計量} else if (props.deviceTypeId === '2') {// if (props.deviceCode) {generateWenduData();// }}});
}, { deep: true });
// 監聽暗黑模式變化時,初始化新圖表
const observer = new MutationObserver((mutations) => {mutations.forEach((mutation) => {if (mutation.attributeName === 'class') {charts.value.forEach((chart: any) => {chart.dispose();});charts.value = [];nextTick(() => {initTemperatureGauge();initHumidityGauge();if (props.deviceTypeId === '4' || props.deviceTypeId === '8') {fetchMeasurementData();} else if (props.deviceTypeId === '2') {// if (props.deviceCode) {generateWenduData();// }} else if (props.deviceTypeId === '6' || props.deviceTypeId === '5') {generateRadarData();//雷達}});}});
});
// 頁面加載和激活時都調用
function waitForContainerAndInitChart() {const chartDom = document.querySelector('.dianliang-chart') as HTMLElement;const chartDomradar = document.querySelector('.radar-chart') as HTMLElement;const chartDomwendu = document.querySelector('.wendu-chart') as HTMLElement;if (!chartDom || !chartDomradar || !chartDomwendu) {requestAnimationFrame(waitForContainerAndInitChart);return;}const { width, height } = chartDom.getBoundingClientRect();const { width: radarWidth, height: radarHeight } = chartDomradar.getBoundingClientRect();const { width: wenduWidth, height: wenduHeight } = chartDomwendu.getBoundingClientRect();if (width === 0 || height === 0 || radarWidth === 0 || radarHeight === 0 || wenduWidth === 0 || wenduHeight === 0) {requestAnimationFrame(waitForContainerAndInitChart);return;}initTemperatureGauge();initHumidityGauge();if (props.deviceTypeId === '6' || props.deviceTypeId === '5') {generateRadarData();} else if (props.deviceTypeId === '4' || props.deviceTypeId === '8') {// 清空舊數據,確保圖表使用新數據chartXAxisData.value = [];chartData.value = [];fetchMeasurementData();} else if (props.deviceTypeId === '2') {// if (props.deviceCode) {generateWenduData();// }}
}
// 頁面加載時請求一次
onMounted(() => {if (props.deviceTypeId === '6' || props.deviceTypeId === '5') {generateRadarData();} else if (props.deviceTypeId === '4' || props.deviceTypeId === '8') {// 清空舊數據,確保圖表使用新數據chartXAxisData.value = [];chartData.value = [];fetchMeasurementData();} else if (props.deviceTypeId === '2') {// if (props.deviceCode) {generateWenduData();// }} else if (props.deviceTypeId === '7' || props.deviceTypeId === '8' || props.deviceTypeId === '10') {console.log("設備表格")// if (props.deviceCode) {// nextTick(() => {// getSwitchData();// })// }getSwitchData();}//initTemperatureGauge();initHumidityGauge();window.addEventListener('resize', handleResize);observer.observe(document.documentElement, {attributes: true,attributeFilter: ['class']});
});
onUnmounted(() => {window.removeEventListener('resize', handleResize);if (dianliangChart.value) dianliangChart.value.dispose();if (radarChart.value) radarChart.value.dispose();if (wenduChart.value) wenduChart.value.dispose && wenduChart.value.dispose();observer.disconnect();
});