feat:对接参数记录echart、空调度数获取设置
This commit is contained in:
@ -15,50 +15,50 @@
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
<view class="connection-status" :class="connectionStatus.isConnected ? 'connected' : 'disconnected'">
|
||||
{{ connectionStatus.isConnected ? 'MQTT已连接' : 'MQTT未连接' }}
|
||||
</view>
|
||||
<!-- <view class="data-status" :class="dataStatus.dataSource">
|
||||
<text class="status-text">{{ dataStatus.dataSource === 'api' ? '实时数据' : '示例数据' }}</text>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<!-- 温度趋势图表 -->
|
||||
<view class="chart-card">
|
||||
<view class="chart-header">
|
||||
<text class="chart-title">温度趋势</text>
|
||||
<view class="status-indicator">
|
||||
<text class="chart-title">温度趋势 (WD)</text>
|
||||
<!-- <view class="status-indicator">
|
||||
<view class="status-dot temperature-dot"></view>
|
||||
<text class="status-text">正常</text>
|
||||
</view>
|
||||
<text class="status-text">{{ chartData.temperature.length > 0 ? '有数据' : '无数据' }}</text>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="chart-container">
|
||||
<canvas canvas-id="temperatureChart" class="chart-canvas"></canvas>
|
||||
<e-chart ref="temperatureChartRef" @ready="initTemperatureChart" :height="400" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 湿度趋势图表 -->
|
||||
<view class="chart-card">
|
||||
<view class="chart-header">
|
||||
<text class="chart-title">湿度趋势</text>
|
||||
<view class="status-indicator">
|
||||
<text class="chart-title">湿度趋势 (SD)</text>
|
||||
<!-- <view class="status-indicator">
|
||||
<view class="status-dot humidity-dot"></view>
|
||||
<text class="status-text">正常</text>
|
||||
</view>
|
||||
<text class="status-text">{{ chartData.humidity.length > 0 ? '有数据' : '无数据' }}</text>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="chart-container">
|
||||
<canvas canvas-id="humidityChart" class="chart-canvas"></canvas>
|
||||
<e-chart ref="humidityChartRef" @ready="initHumidityChart" :height="400" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- PM2.5趋势图表 -->
|
||||
<view class="chart-card">
|
||||
<view class="chart-header">
|
||||
<text class="chart-title">PM2.5趋势</text>
|
||||
<view class="status-indicator">
|
||||
<text class="chart-title">PM趋势 (PM)</text>
|
||||
<!-- <view class="status-indicator">
|
||||
<view class="status-dot pm25-dot"></view>
|
||||
<text class="status-text">正常</text>
|
||||
</view>
|
||||
<text class="status-text">{{ chartData.pm.length > 0 ? '有数据' : '无数据' }}</text>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="chart-container">
|
||||
<canvas canvas-id="pm25Chart" class="chart-canvas"></canvas>
|
||||
<e-chart ref="pm25ChartRef" @ready="initPM25Chart" :height="400" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -67,11 +67,16 @@
|
||||
|
||||
<script>
|
||||
import mqttDataManager from '@/utils/mqttDataManager.js'
|
||||
import { dataHistoryApi } from '@/utils/api.js'
|
||||
import EChart from '@/uni_modules/e-chart/components/e-chart/e-chart.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EChart
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedDate: '2025-09-01',
|
||||
selectedDate: this.getTodayDate(), // 默认选择今天
|
||||
// 24小时数据 (0-23点)
|
||||
temperatureData: [22, 25, 28, 32, 35, 38, 40, 38, 35, 32, 28, 25, 22, 20, 18, 20, 22, 25, 28, 30, 32, 30, 28, 25],
|
||||
humidityData: [45, 50, 55, 60, 65, 70, 75, 70, 65, 60, 55, 50, 45, 40, 35, 40, 45, 50, 55, 60, 65, 60, 55, 50],
|
||||
@ -79,15 +84,233 @@ export default {
|
||||
connectionStatus: {
|
||||
isConnected: false,
|
||||
lastUpdate: null
|
||||
},
|
||||
// 历史数据
|
||||
historyData: [],
|
||||
// 处理后的图表数据
|
||||
chartData: {
|
||||
temperature: [],
|
||||
humidity: [],
|
||||
pm: []
|
||||
},
|
||||
// 数据状态
|
||||
dataStatus: {
|
||||
isRealData: false,
|
||||
lastUpdateTime: null,
|
||||
dataSource: 'empty' // 'api' | 'empty' | 'error'
|
||||
},
|
||||
// ECharts配置选项
|
||||
temperatureOption: {
|
||||
title: {
|
||||
text: '温度趋势',
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
color: '#333'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function(params) {
|
||||
const data = params[0];
|
||||
return `时间: ${data.axisValue}<br/>温度: ${data.value}°C`;
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: Array.from({length: 24}, (_, i) => `${i.toString().padStart(2, '0')}:00`),
|
||||
axisLabel: {
|
||||
interval: 3, // 每4个小时显示一个标签
|
||||
fontSize: 10
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: '温度(°C)',
|
||||
min: 0,
|
||||
max: 100,
|
||||
axisLabel: {
|
||||
formatter: '{value}°C',
|
||||
fontSize: 10
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: '温度',
|
||||
type: 'line',
|
||||
data: [],
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
color: '#ff6b35',
|
||||
width: 3
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#ff6b35'
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: 'rgba(255, 107, 53, 0.3)'
|
||||
}, {
|
||||
offset: 1, color: 'rgba(255, 107, 53, 0.1)'
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
humidityOption: {
|
||||
title: {
|
||||
text: '湿度趋势',
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
color: '#333'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function(params) {
|
||||
const data = params[0];
|
||||
return `时间: ${data.axisValue}<br/>湿度: ${data.value}%`;
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: Array.from({length: 24}, (_, i) => `${i.toString().padStart(2, '0')}:00`),
|
||||
axisLabel: {
|
||||
interval: 3,
|
||||
fontSize: 10
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: '湿度(%)',
|
||||
min: 0,
|
||||
max: 100,
|
||||
axisLabel: {
|
||||
formatter: '{value}%',
|
||||
fontSize: 10
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: '湿度',
|
||||
type: 'line',
|
||||
data: [],
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
color: '#4a90e2',
|
||||
width: 3
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#4a90e2'
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: 'rgba(74, 144, 226, 0.3)'
|
||||
}, {
|
||||
offset: 1, color: 'rgba(74, 144, 226, 0.1)'
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
pm25Option: {
|
||||
title: {
|
||||
text: 'PM2.5趋势',
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
color: '#333'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function(params) {
|
||||
const data = params[0];
|
||||
return `时间: ${data.axisValue}<br/>PM2.5: ${data.value}μg/m³`;
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: Array.from({length: 24}, (_, i) => `${i.toString().padStart(2, '0')}:00`),
|
||||
axisLabel: {
|
||||
interval: 3,
|
||||
fontSize: 10
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: 'PM2.5(μg/m³)',
|
||||
min: 0,
|
||||
max: 100,
|
||||
axisLabel: {
|
||||
formatter: '{value}μg/m³',
|
||||
fontSize: 10
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: 'PM2.5',
|
||||
type: 'line',
|
||||
data: [],
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
color: '#7ed321',
|
||||
width: 3
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#7ed321'
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: 'rgba(126, 211, 33, 0.3)'
|
||||
}, {
|
||||
offset: 1, color: 'rgba(126, 211, 33, 0.1)'
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
console.log('参数记录页面加载')
|
||||
this.$nextTick(() => {
|
||||
this.drawCharts()
|
||||
})
|
||||
console.log('参数记录页面加载', new Date().toISOString().split('T')[0])
|
||||
this.initMqttListener()
|
||||
// 调用历史数据接口
|
||||
this.getHistoryData()
|
||||
},
|
||||
onUnload() {
|
||||
// 页面卸载时移除监听器
|
||||
@ -99,12 +322,20 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取今天的日期(本地时区)
|
||||
getTodayDate() {
|
||||
const today = new Date()
|
||||
const year = today.getFullYear()
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(today.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
},
|
||||
// 初始化MQTT监听
|
||||
initMqttListener() {
|
||||
// 监听数据更新
|
||||
this.dataUpdateHandler = (data) => {
|
||||
console.log('参数记录页面收到MQTT数据:', data)
|
||||
this.updateChartData(data)
|
||||
// this.updateChartData(data)
|
||||
}
|
||||
mqttDataManager.addListener('dataUpdate', this.dataUpdateHandler)
|
||||
|
||||
@ -130,17 +361,21 @@ export default {
|
||||
|
||||
// 更新对应小时的数据
|
||||
if (data.temperature !== undefined) {
|
||||
this.temperatureData[currentHour] = Math.round(data.temperature)
|
||||
Math.round(data.temperature) && (this.temperatureData[currentHour] = Math.round(data.temperature))
|
||||
console.log(`✅ 温度数据已更新 - 小时${currentHour}:`, this.temperatureData[currentHour])
|
||||
}
|
||||
if (data.humidity !== undefined) {
|
||||
this.humidityData[currentHour] = Math.round(data.humidity)
|
||||
Math.round(data.humidity) && (this.humidityData[currentHour] = Math.round(data.humidity))
|
||||
console.log(`✅ 湿度数据已更新 - 小时${currentHour}:`, this.humidityData[currentHour])
|
||||
}
|
||||
if (data.pm !== undefined) {
|
||||
Math.round(data.pm) && (this.pm25Data[currentHour] = Math.round(data.pm))
|
||||
console.log(`✅ PM2.5数据已更新 - 小时${currentHour}:`, this.pm25Data[currentHour])
|
||||
}
|
||||
|
||||
// 重新绘制图表
|
||||
this.$nextTick(() => {
|
||||
this.drawCharts()
|
||||
this.updateCharts()
|
||||
})
|
||||
|
||||
console.log('✅ 图表数据更新完成:', {
|
||||
@ -152,109 +387,299 @@ export default {
|
||||
console.log('⚠️ 非WSD设备数据,跳过图表更新:', data.deviceType)
|
||||
}
|
||||
},
|
||||
|
||||
// 图表初始化方法
|
||||
initTemperatureChart() {
|
||||
console.log('初始化温度图表')
|
||||
this.temperatureOption.series[0].data = this.temperatureData
|
||||
this.$refs.temperatureChartRef.init(this.temperatureOption)
|
||||
},
|
||||
|
||||
initHumidityChart() {
|
||||
console.log('初始化湿度图表')
|
||||
this.humidityOption.series[0].data = this.humidityData
|
||||
this.$refs.humidityChartRef.init(this.humidityOption)
|
||||
},
|
||||
|
||||
initPM25Chart() {
|
||||
console.log('初始化PM2.5图表')
|
||||
this.pm25Option.series[0].data = this.pm25Data
|
||||
this.$refs.pm25ChartRef.init(this.pm25Option)
|
||||
},
|
||||
|
||||
onDateChange(e) {
|
||||
this.selectedDate = e.detail.value
|
||||
this.$nextTick(() => {
|
||||
this.drawCharts()
|
||||
console.log('📅 日期已更改为:', this.selectedDate)
|
||||
|
||||
// 显示加载状态
|
||||
uni.showLoading({
|
||||
title: '加载数据中...'
|
||||
})
|
||||
|
||||
// 重新获取历史数据
|
||||
this.getHistoryData().finally(() => {
|
||||
uni.hideLoading()
|
||||
})
|
||||
},
|
||||
drawCharts() {
|
||||
this.drawTemperatureChart()
|
||||
this.drawHumidityChart()
|
||||
this.drawPM25Chart()
|
||||
},
|
||||
drawTemperatureChart() {
|
||||
const ctx = uni.createCanvasContext('temperatureChart', this)
|
||||
this.drawLineChart(ctx, this.temperatureData, '#ff6b35', '°C')
|
||||
},
|
||||
drawHumidityChart() {
|
||||
const ctx = uni.createCanvasContext('humidityChart', this)
|
||||
this.drawLineChart(ctx, this.humidityData, '#4a90e2', '%')
|
||||
},
|
||||
drawPM25Chart() {
|
||||
const ctx = uni.createCanvasContext('pm25Chart', this)
|
||||
this.drawLineChart(ctx, this.pm25Data, '#7ed321', 'μg/m³')
|
||||
},
|
||||
drawLineChart(ctx, data, color, unit) {
|
||||
const canvasWidth = 300
|
||||
const canvasHeight = 200
|
||||
const padding = 40
|
||||
const chartWidth = canvasWidth - padding * 2
|
||||
const chartHeight = canvasHeight - padding * 2
|
||||
|
||||
// 清空画布
|
||||
ctx.clearRect(0, 0, canvasWidth, canvasHeight)
|
||||
|
||||
// 绘制网格
|
||||
ctx.setStrokeStyle('#f0f0f0')
|
||||
ctx.setLineWidth(1)
|
||||
|
||||
// 水平网格线
|
||||
for (let i = 0; i <= 5; i++) {
|
||||
const y = padding + (chartHeight / 5) * i
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(padding, y)
|
||||
ctx.lineTo(padding + chartWidth, y)
|
||||
ctx.stroke()
|
||||
|
||||
// 更新图表数据
|
||||
updateCharts() {
|
||||
if (this.$refs.temperatureChartRef) {
|
||||
this.temperatureOption.series[0].data = this.temperatureData
|
||||
this.$refs.temperatureChartRef.setOption(this.temperatureOption)
|
||||
}
|
||||
|
||||
// 垂直网格线
|
||||
for (let i = 0; i <= 6; i++) {
|
||||
const x = padding + (chartWidth / 6) * i
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x, padding)
|
||||
ctx.lineTo(x, padding + chartHeight)
|
||||
ctx.stroke()
|
||||
if (this.$refs.humidityChartRef) {
|
||||
this.humidityOption.series[0].data = this.humidityData
|
||||
this.$refs.humidityChartRef.setOption(this.humidityOption)
|
||||
}
|
||||
|
||||
// 绘制数据线
|
||||
ctx.setStrokeStyle(color)
|
||||
ctx.setLineWidth(3)
|
||||
ctx.beginPath()
|
||||
|
||||
data.forEach((value, index) => {
|
||||
const x = padding + (chartWidth / 23) * index
|
||||
const y = padding + chartHeight - (value / 100) * chartHeight
|
||||
if (this.$refs.pm25ChartRef) {
|
||||
this.pm25Option.series[0].data = this.pm25Data
|
||||
this.$refs.pm25ChartRef.setOption(this.pm25Option)
|
||||
}
|
||||
},
|
||||
|
||||
// 获取历史数据
|
||||
async getHistoryData() {
|
||||
try {
|
||||
// 根据选择的日期构建时间范围
|
||||
const startTime = `${this.selectedDate} 00:00:00`
|
||||
const endTime = `${this.selectedDate} 23:59:59`
|
||||
|
||||
if (index === 0) {
|
||||
ctx.moveTo(x, y)
|
||||
const params = {
|
||||
startTime: startTime,
|
||||
endTime: endTime
|
||||
}
|
||||
|
||||
console.log('📊 请求历史数据:', params)
|
||||
|
||||
const response = await dataHistoryApi.getHistory(params)
|
||||
|
||||
console.log('✅ 历史数据获取成功:', response)
|
||||
|
||||
// 处理历史数据
|
||||
if (response && Array.isArray(response) && response.length > 0) {
|
||||
this.historyData = response
|
||||
this.processHistoryData(response)
|
||||
|
||||
// 更新数据状态
|
||||
this.dataStatus = {
|
||||
isRealData: true,
|
||||
lastUpdateTime: new Date().toLocaleString(),
|
||||
dataSource: 'api'
|
||||
}
|
||||
} else {
|
||||
ctx.lineTo(x, y)
|
||||
console.log('📊 没有历史数据,显示空状态')
|
||||
// 没有数据时显示空状态
|
||||
this.showEmptyState()
|
||||
|
||||
// 更新数据状态
|
||||
this.dataStatus = {
|
||||
isRealData: false,
|
||||
lastUpdateTime: new Date().toLocaleString(),
|
||||
dataSource: 'empty'
|
||||
}
|
||||
}
|
||||
|
||||
return response
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 历史数据获取失败:', error)
|
||||
// 出错时显示空状态
|
||||
this.showEmptyState()
|
||||
|
||||
// 更新数据状态
|
||||
this.dataStatus = {
|
||||
isRealData: false,
|
||||
lastUpdateTime: new Date().toLocaleString(),
|
||||
dataSource: 'error'
|
||||
}
|
||||
|
||||
// 显示错误提示
|
||||
uni.showToast({
|
||||
title: '数据加载失败',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
// 使用默认数据
|
||||
useDefaultData() {
|
||||
console.log('🎨 使用默认数据展示图表')
|
||||
|
||||
// 使用预设的示例数据
|
||||
this.temperatureData = [22, 25, 28, 32, 35, 38, 40, 38, 35, 32, 28, 25, 22, 20, 18, 20, 22, 25, 28, 30, 32, 30, 28, 25]
|
||||
this.humidityData = [45, 50, 55, 60, 65, 70, 75, 70, 65, 60, 55, 50, 45, 40, 35, 40, 45, 50, 55, 60, 65, 60, 55, 50]
|
||||
this.pm25Data = [15, 18, 22, 25, 28, 32, 35, 32, 28, 25, 22, 18, 15, 12, 10, 12, 15, 18, 22, 25, 28, 25, 22, 18]
|
||||
|
||||
// 更新数据状态
|
||||
this.dataStatus = {
|
||||
isRealData: false,
|
||||
lastUpdateTime: new Date().toLocaleString(),
|
||||
dataSource: 'default'
|
||||
}
|
||||
|
||||
// 更新图表
|
||||
this.$nextTick(() => {
|
||||
this.updateCharts()
|
||||
})
|
||||
},
|
||||
|
||||
// 显示空状态
|
||||
showEmptyState() {
|
||||
console.log('🎨 显示空状态,默认值为0')
|
||||
|
||||
// 设置默认数据为0
|
||||
this.temperatureData = new Array(24).fill(0)
|
||||
this.humidityData = new Array(24).fill(0)
|
||||
this.pm25Data = new Array(24).fill(0)
|
||||
|
||||
// 更新图表
|
||||
this.$nextTick(() => {
|
||||
this.updateCharts()
|
||||
})
|
||||
},
|
||||
processHistoryData(data) {
|
||||
console.log('🔄 开始处理历史数据:', data.length, '条记录')
|
||||
console.log('📊 原始数据示例:', data[0])
|
||||
|
||||
// 初始化图表数据
|
||||
this.chartData = {
|
||||
temperature: [],
|
||||
humidity: [],
|
||||
pm: []
|
||||
}
|
||||
|
||||
// 按时间排序
|
||||
const sortedData = data.sort((a, b) => {
|
||||
const timeA = new Date(a.createTime || a.timestamp || a.time)
|
||||
const timeB = new Date(b.createTime || b.timestamp || b.time)
|
||||
return timeA - timeB
|
||||
})
|
||||
|
||||
// 处理每条数据
|
||||
sortedData.forEach(item => {
|
||||
const time = new Date(item.createTime || item.timestamp || item.time)
|
||||
const hour = time.getHours()
|
||||
const minute = time.getMinutes()
|
||||
|
||||
// 处理温度数据 (wd是温度)
|
||||
const temperature = item.wd || item.temperature || item.temp || item.T
|
||||
if (temperature !== undefined && temperature !== null && temperature >= 0) {
|
||||
this.chartData.temperature.push({
|
||||
time: hour + minute / 60,
|
||||
value: Number(temperature),
|
||||
timestamp: item.createTime || item.timestamp || item.time
|
||||
})
|
||||
}
|
||||
|
||||
// 处理湿度数据 (sd是湿度)
|
||||
const humidity = item.sd || item.humidity || item.hum || item.H
|
||||
if (humidity !== undefined && humidity !== null && humidity >= 0) {
|
||||
this.chartData.humidity.push({
|
||||
time: hour + minute / 60,
|
||||
value: Number(humidity),
|
||||
timestamp: item.createTime || item.timestamp || item.time
|
||||
})
|
||||
}
|
||||
|
||||
// 处理PM数据 (支持多种字段名)
|
||||
const pm = item.pm || item.pm25 || item.pm2_5 || item.PM
|
||||
if (pm !== undefined && pm !== null && pm >= 0) {
|
||||
this.chartData.pm.push({
|
||||
time: hour + minute / 60,
|
||||
value: Number(pm),
|
||||
timestamp: item.createTime || item.timestamp || item.time
|
||||
})
|
||||
}
|
||||
})
|
||||
ctx.stroke()
|
||||
|
||||
// 绘制数据点
|
||||
ctx.setFillStyle(color)
|
||||
data.forEach((value, index) => {
|
||||
const x = padding + (chartWidth / 23) * index
|
||||
const y = padding + chartHeight - (value / 100) * chartHeight
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.arc(x, y, 4, 0, 2 * Math.PI)
|
||||
ctx.fill()
|
||||
console.log('📈 处理后的图表数据:', {
|
||||
temperature: this.chartData.temperature.length,
|
||||
humidity: this.chartData.humidity.length,
|
||||
pm: this.chartData.pm.length
|
||||
})
|
||||
|
||||
// 绘制X轴标签
|
||||
ctx.setFillStyle('#666')
|
||||
ctx.setFontSize(12)
|
||||
ctx.setTextAlign('center')
|
||||
|
||||
const timeLabels = ['00', '04', '08', '12', '16', '20', '23']
|
||||
timeLabels.forEach((label, index) => {
|
||||
const x = padding + (chartWidth / 6) * index
|
||||
ctx.fillText(label, x, canvasHeight - 10)
|
||||
// 重新绘制图表
|
||||
this.$nextTick(() => {
|
||||
this.updateChartsWithHistoryData()
|
||||
})
|
||||
},
|
||||
|
||||
// 使用历史数据更新图表
|
||||
updateChartsWithHistoryData() {
|
||||
console.log('🎨 使用历史数据更新图表')
|
||||
|
||||
// 绘制Y轴标签
|
||||
ctx.setTextAlign('right')
|
||||
for (let i = 0; i <= 5; i++) {
|
||||
const y = padding + chartHeight - (chartHeight / 5) * i + 5
|
||||
const value = (100 / 5) * i
|
||||
ctx.fillText(value.toString(), padding - 10, y)
|
||||
// 处理温度数据
|
||||
if (this.chartData.temperature.length > 0) {
|
||||
const temperatureData = new Array(24).fill(0)
|
||||
this.chartData.temperature.forEach(item => {
|
||||
const hour = Math.floor(item.time)
|
||||
if (hour >= 0 && hour < 24) {
|
||||
temperatureData[hour] = item.value || 0
|
||||
}
|
||||
})
|
||||
this.temperatureData = temperatureData
|
||||
if (this.$refs.temperatureChartRef) {
|
||||
this.temperatureOption.series[0].data = temperatureData
|
||||
this.$refs.temperatureChartRef.setOption(this.temperatureOption)
|
||||
}
|
||||
} else {
|
||||
// 没有温度数据时,使用0填充
|
||||
this.temperatureData = new Array(24).fill(0)
|
||||
if (this.$refs.temperatureChartRef) {
|
||||
this.temperatureOption.series[0].data = this.temperatureData
|
||||
this.$refs.temperatureChartRef.setOption(this.temperatureOption)
|
||||
}
|
||||
}
|
||||
|
||||
ctx.draw()
|
||||
// 处理湿度数据
|
||||
if (this.chartData.humidity.length > 0) {
|
||||
const humidityData = new Array(24).fill(0)
|
||||
this.chartData.humidity.forEach(item => {
|
||||
const hour = Math.floor(item.time)
|
||||
if (hour >= 0 && hour < 24) {
|
||||
humidityData[hour] = item.value || 0
|
||||
}
|
||||
})
|
||||
this.humidityData = humidityData
|
||||
if (this.$refs.humidityChartRef) {
|
||||
this.humidityOption.series[0].data = humidityData
|
||||
this.$refs.humidityChartRef.setOption(this.humidityOption)
|
||||
}
|
||||
} else {
|
||||
// 没有湿度数据时,使用0填充
|
||||
this.humidityData = new Array(24).fill(0)
|
||||
if (this.$refs.humidityChartRef) {
|
||||
this.humidityOption.series[0].data = this.humidityData
|
||||
this.$refs.humidityChartRef.setOption(this.humidityOption)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理PM数据
|
||||
if (this.chartData.pm.length > 0) {
|
||||
const pmData = new Array(24).fill(0)
|
||||
this.chartData.pm.forEach(item => {
|
||||
const hour = Math.floor(item.time)
|
||||
if (hour >= 0 && hour < 24) {
|
||||
pmData[hour] = item.value || 0
|
||||
}
|
||||
})
|
||||
this.pm25Data = pmData
|
||||
if (this.$refs.pm25ChartRef) {
|
||||
this.pm25Option.series[0].data = pmData
|
||||
this.$refs.pm25ChartRef.setOption(this.pm25Option)
|
||||
}
|
||||
} else {
|
||||
// 没有PM数据时,使用0填充
|
||||
this.pm25Data = new Array(24).fill(0)
|
||||
if (this.$refs.pm25ChartRef) {
|
||||
this.pm25Option.series[0].data = this.pm25Data
|
||||
this.$refs.pm25ChartRef.setOption(this.pm25Option)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -290,9 +715,25 @@ export default {
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
.connection-status.disconnected {
|
||||
background-color: #ffebee;
|
||||
color: #ff4444;
|
||||
.data-status {
|
||||
font-size: 24rpx;
|
||||
font-weight: bold;
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.data-status.api {
|
||||
background-color: #e8f5e8;
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
.data-status.default {
|
||||
background-color: #fff3e0;
|
||||
color: #ff9800;
|
||||
}
|
||||
|
||||
.data-status .status-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.date-picker {
|
||||
@ -317,15 +758,15 @@ export default {
|
||||
.chart-card {
|
||||
background: white;
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx;
|
||||
margin-bottom: 15rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.chart-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
@ -372,12 +813,7 @@ export default {
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.chart-canvas {
|
||||
width: 280px;
|
||||
height: 180px;
|
||||
width: 100%;
|
||||
// padding: 0 20rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user