|
@@ -72,7 +72,7 @@
|
|
|
<!-- </div>-->
|
|
|
|
|
|
<!-- 图表容器 -->
|
|
|
- <div v-loading="loading" class="chart" ref="chartRef"></div>
|
|
|
+ <div v-loading="loading" style="height: 100%" ref="chartContainer"></div>
|
|
|
</div>
|
|
|
</ContentWrap>
|
|
|
</ContentWrap>
|
|
@@ -82,6 +82,9 @@
|
|
|
import { DICT_TYPE, getDictLabel } from '@/utils/dict'
|
|
|
import TdDeviceLabel from '@/views/pms/device/monitor/TdDeviceLabel.vue'
|
|
|
import {IotDeviceApi} from "@/api/pms/device";
|
|
|
+import * as echarts from 'echarts'
|
|
|
+import dayjs from 'dayjs'
|
|
|
+import {IotStatApi} from "@/api/pms/stat";
|
|
|
|
|
|
const { params, name } = useRoute() // 查询参数
|
|
|
const info = ref({})
|
|
@@ -95,149 +98,89 @@ const formData = ref({
|
|
|
lastInlineTime: ''
|
|
|
})
|
|
|
const specs = ref([])
|
|
|
-onMounted(async () => {
|
|
|
- formLoading.value = true
|
|
|
- formData.value.deviceCode = params.code
|
|
|
- formData.value.deviceName = params.name
|
|
|
- formData.value.lastInlineTime = params.time
|
|
|
- formData.value.ifInline = params.ifInline
|
|
|
- await IotDeviceApi.getIotDeviceTds(id).then(res => {
|
|
|
- specs.value = res
|
|
|
- specs.value = specs.value.sort((a, b) => {
|
|
|
- return b.modelOrder - a.modelOrder
|
|
|
- })
|
|
|
- formLoading.value = false
|
|
|
- topic.value = specs.value[0].identifier
|
|
|
- fetchData()
|
|
|
- })
|
|
|
- initDefaultDate()
|
|
|
- initChart()
|
|
|
-})
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-import * as echarts from 'echarts'
|
|
|
-import dayjs from 'dayjs'
|
|
|
-
|
|
|
-// ECharts 实例
|
|
|
-const chartRef = ref(null)
|
|
|
-let chartInstance = null
|
|
|
|
|
|
// 响应式数据
|
|
|
const startTime = ref('')
|
|
|
const endTime = ref('')
|
|
|
-const chartData = ref([])
|
|
|
+const topicName = ref([])
|
|
|
const loading = ref(false)
|
|
|
const topic = ref('')
|
|
|
|
|
|
const labelSelect = (row) =>{
|
|
|
topic.value = row.identifier
|
|
|
+ topicName.value = row.modelName
|
|
|
+ debugger
|
|
|
+ initChart()
|
|
|
}
|
|
|
-// 初始化默认时间范围
|
|
|
-const initDefaultDate = () => {
|
|
|
- const now = dayjs()
|
|
|
- startTime.value = now.subtract(1, 'day').format('YYYY-MM-DDTHH:mm')
|
|
|
- endTime.value = now.format('YYYY-MM-DDTHH:mm')
|
|
|
+
|
|
|
+const chartContainer = ref(null)
|
|
|
+let chartInstance = null
|
|
|
+
|
|
|
+// 时间格式化(HH:mm)
|
|
|
+const formatTime = timestamp => {
|
|
|
+ return new Date(timestamp)
|
|
|
+ .toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit',second:'2-digit' })
|
|
|
+ .slice(0, 5)
|
|
|
}
|
|
|
|
|
|
-// 空数据占位处理
|
|
|
-const displayData = computed(() => {
|
|
|
- return chartData.value.length > 0
|
|
|
- ? chartData.value
|
|
|
- : [{ time: startTime.value, value: 0 }, { time: endTime.value, value: 0 }]
|
|
|
-})
|
|
|
+// 初始化图表
|
|
|
+const initChart = async () => {
|
|
|
+ if (!chartContainer.value) return
|
|
|
|
|
|
-// 初始化图表配置
|
|
|
-const initChart = () => {
|
|
|
- chartInstance = echarts.init(chartRef.value)
|
|
|
+ // 销毁旧实例
|
|
|
+ if (chartInstance) chartInstance.dispose()
|
|
|
|
|
|
+ chartInstance = markRaw(echarts.init(chartContainer.value))
|
|
|
+ const result = await IotStatApi.getDeviceInfoChart(params.code, topic.value)
|
|
|
const option = {
|
|
|
- title: {
|
|
|
- text: '近一天数据趋势图',
|
|
|
- left: 'center'
|
|
|
- },
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- formatter: params => {
|
|
|
- if (chartData.value.length === 0) return '暂无数据'
|
|
|
- return `${params[0].axisValue}<br/>${params[0].marker} ${params[0].value}`
|
|
|
- }
|
|
|
+ title:{
|
|
|
+ text: topicName.value+'数据趋势',
|
|
|
+ left:'center',
|
|
|
},
|
|
|
+ tooltip: { trigger: 'axis', },
|
|
|
xAxis: {
|
|
|
- type: 'time',
|
|
|
- boundaryGap: false,
|
|
|
- axisLabel: {
|
|
|
- formatter: value => dayjs(value).format('MM-DD HH:mm')
|
|
|
- }
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- type: 'value',
|
|
|
- min: value => Math.max(0, value.min - 5)
|
|
|
+ type: 'category',
|
|
|
+ data: result.map(d => formatTime(d.timestamp)),
|
|
|
+ axisLabel: { rotate: 45 } // X轴标签旋转防止重叠
|
|
|
},
|
|
|
+ yAxis: { type: 'value' },
|
|
|
+ dataZoom: [{
|
|
|
+ type: 'slider',
|
|
|
+ xAxisIndex: 0,
|
|
|
+ start: 0, // 初始显示范围开始位置
|
|
|
+ end: 100 // 初始显示范围结束位置:ml-citation{ref="7" data="citationList"}
|
|
|
+ }],
|
|
|
series: [{
|
|
|
- name: '数据',
|
|
|
+ data: result.map(d => d.value),
|
|
|
type: 'line',
|
|
|
- showSymbol: chartData.value.length > 0,
|
|
|
- data: displayData.value.map(item => [item.time, item.value]),
|
|
|
- areaStyle: chartData.value.length > 0 ? {} : null
|
|
|
- }],
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '4%',
|
|
|
- bottom: '3%',
|
|
|
- containLabel: true
|
|
|
- }
|
|
|
+ smooth: true,
|
|
|
+ areaStyle: {} // 显示区域填充
|
|
|
+ }]
|
|
|
}
|
|
|
|
|
|
chartInstance.setOption(option)
|
|
|
- window.addEventListener('resize', () => chartInstance.resize())
|
|
|
-}
|
|
|
-
|
|
|
-// 获取数据(示例)
|
|
|
-const fetchData = async () => {
|
|
|
- try {
|
|
|
- loading.value = true
|
|
|
|
|
|
- // 模拟API请求
|
|
|
- const mockData = [] // 测试空数据时设置为空数组
|
|
|
-
|
|
|
- // 实际应替换为:
|
|
|
- // const { data } = await api.getData({
|
|
|
- // start: dayjs(startTime.value).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
- // end: dayjs(endTime.value).format('YYYY-MM-DD HH:mm:ss')
|
|
|
- // })
|
|
|
-
|
|
|
- chartData.value = mockData
|
|
|
- updateChart()
|
|
|
- } catch (error) {
|
|
|
- console.error('数据获取失败:', error)
|
|
|
- } finally {
|
|
|
- loading.value = false
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 更新图表
|
|
|
-const updateChart = () => {
|
|
|
- const options = {
|
|
|
- series: [{
|
|
|
- data: displayData.value.map(item => [item.time, item.value]),
|
|
|
- showSymbol: chartData.value.length > 0,
|
|
|
- areaStyle: chartData.value.length > 0 ? {} : null
|
|
|
- }]
|
|
|
- }
|
|
|
- chartInstance.setOption(options)
|
|
|
-}
|
|
|
-
|
|
|
-// 日期变更处理
|
|
|
-const handleDateChange = () => {
|
|
|
- if (dayjs(startTime.value).isAfter(endTime.value)) {
|
|
|
- endTime.value = startTime.value
|
|
|
- }
|
|
|
+ // 窗口自适应
|
|
|
+ window.addEventListener('resize', () => chartInstance.resize())
|
|
|
}
|
|
|
+onMounted(async () => {
|
|
|
+ formLoading.value = true
|
|
|
+ formData.value.deviceCode = params.code
|
|
|
+ formData.value.deviceName = params.name
|
|
|
+ formData.value.lastInlineTime = params.time
|
|
|
+ formData.value.ifInline = params.ifInline
|
|
|
+ await IotDeviceApi.getIotDeviceTds(id).then(res => {
|
|
|
+ specs.value = res
|
|
|
+ specs.value = specs.value.sort((a, b) => {
|
|
|
+ return b.modelOrder - a.modelOrder
|
|
|
+ })
|
|
|
+ formLoading.value = false
|
|
|
+ topic.value = specs.value[0].identifier
|
|
|
+ debugger
|
|
|
+ topicName.value = specs.value[0].modelName
|
|
|
+ })
|
|
|
+ await initChart()
|
|
|
|
|
|
-onBeforeUnmount(() => {
|
|
|
- window.removeEventListener('resize', () => chartInstance.resize())
|
|
|
- chartInstance.dispose()
|
|
|
})
|
|
|
</script>
|
|
|
<style scoped lang="scss">
|
|
@@ -294,11 +237,11 @@ input[type="datetime-local"]:focus {
|
|
|
opacity: 0.8;
|
|
|
}
|
|
|
|
|
|
-.chart {
|
|
|
- width: 100%;
|
|
|
- height: 500px;
|
|
|
- margin-top: 20px;
|
|
|
-}
|
|
|
+//.chart {
|
|
|
+// width: 100%;
|
|
|
+// height: 500px;
|
|
|
+// margin-top: 20px;
|
|
|
+//}
|
|
|
.custom-label{
|
|
|
font-size: 15px;
|
|
|
}
|