HTML
<!-- 温湿度传感器 -->
<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-select v-model="WenduTimeType" placeholder="请选择时间维度" style="width: 200px;margin-right: 20px;"
@change="handleWenduTimeTypeChange">
<el-option label="小时" value="hour" />
<el-option label="日" value="day" />
<el-option label="月" value="month" />
<el-option label="年" value="year" />
</el-select> -->
<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 wenduChart = ref<any>(null);
const wenduRef = ref<HTMLElement | null>(null)
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 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
}).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();
});
}
// const botlineType = ref<'day' | 'month' | 'year'>('day');
// 新增温湿度图更新方法
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()
}
// 新增温湿度时间维度切换
const handleWenduTimeTypeChange = () => {
if (WenduTimeType.value === 'day') {
WenduSelectedHour.value = new Date()
} else if (WenduTimeType.value === 'month') {
WenduSelectedMonth.value = new Date()
} else if (WenduTimeType.value === 'year') {
WenduSelectedYear.value = new Date()
} else if (WenduTimeType.value === 'hour') {
WenduSelectedHour.value = new Date()
}
generateWenduData()
}
// 监听暗黑模式变化时,初始化新图表--若有需要
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === 'class') {
nextTick(() => {if (props.deviceTypeId === '2') {
generateWenduData();
}
});
}
});
});
//渲染
// 页面加载和激活时都调用
function waitForContainerAndInitChart() {
const chartDomwendu = document.querySelector('.wendu-chart') as HTMLElement;
if (!chartDom || !chartDomradar || !chartDomwendu) {
requestAnimationFrame(waitForContainerAndInitChart);
return;
}
const { width, height } = chartDom.getBoundingClientRect();
const { width: wenduWidth, height: wenduHeight } = chartDomwendu.getBoundingClientRect();
if (width === 0 || height === 0 || radarWidth === 0 || radarHeight === 0 || wenduWidth === 0 || wenduHeight === 0) {
requestAnimationFrame(waitForContainerAndInitChart);
return;
}
if (props.deviceTypeId === '2') {
generateWenduData();
}
}
// 生命周期钩子模拟
window.addEventListener('resize', handleResize);
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class']
});
// 用 requestAnimationFrame 递归检测容器宽高直到可用再初始化 ECharts
// 页面加载和激活时都调用
waitForContainerAndInitChart();
window.addEventListener('pageshow', () => {
waitForContainerAndInitChart();
});
// 页面卸载时清理
window.addEventListener('beforeunload', () => {
window.removeEventListener('resize', handleResize);
if (wenduChart.value) wenduChart.value.dispose && wenduChart.value.dispose();
observer.disconnect();
});
// 页面加载时请求一次
onMounted(() => {
if (props.deviceTypeId === '2') {
generateWenduData();
}
window.addEventListener('resize', handleResize);
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class']
});
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
if (wenduChart.value) wenduChart.value.dispose && wenduChart.value.dispose();
observer.disconnect();
});