From ad1aceb23ab49d0cf2a9f561754bd42d0cb45f6a Mon Sep 17 00:00:00 2001
From: cjl <909710561@qq.com>
Date: Tue, 19 May 2026 16:46:05 +0800
Subject: [PATCH] 雷达

---
 src/views/radar/index.vue |  264 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 264 insertions(+), 0 deletions(-)

diff --git a/src/views/radar/index.vue b/src/views/radar/index.vue
new file mode 100644
index 0000000..56f4436
--- /dev/null
+++ b/src/views/radar/index.vue
@@ -0,0 +1,264 @@
+<template>
+  <div
+    id="chartTableContent"
+    style="width: 100%; height: 100%"
+  >
+  <div class="topSelect">
+
+      <el-input-number
+        v-model="high1"
+        :min="0"
+        :max="15000"
+        label="������������"
+        style="width: 130px; margin-left: 10px"
+        controls-position="right"
+      ></el-input-number>
+      <el-input-number
+        v-model="high2"
+        :min="0"
+        :max="15000"
+        label="������������"
+        style="width: 130px; margin-left: 10px"
+        controls-position="right"
+      ></el-input-number>
+      <component
+        :is="dataType"
+        ref="picker"
+        style="padding-left: 0; margin-left: 20px; width: 160px"
+        class="select11"
+        @sendPickerChild="showPickerChild"
+
+      />
+      <!--������������-->
+      <el-button
+        class="btn1"
+        @click="selectData"
+      >
+        ������
+      </el-button>
+    </div>
+    <div class="pm-profile">
+      <h2 >PM2.5 / PM10 ���������������������������</h2>
+      <div ref="chart" class="chart-container"></div>
+      <div class="controls">
+        <p>���������������������������������������</p>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+import HourPicker from '@/components/Form/HourPicker1'
+export default {
+  name: 'PMProfile',
+  components: {
+    HourPicker
+  },
+  props: {
+    chartData: {
+      type: Object,
+      default: null
+    }
+  },
+  data() {
+
+    return {
+      chart: null,
+      dataType: 'HourPicker',
+      defaultData: {},
+      newData: [],
+      high1: 1000,
+      high2: 7000,
+      timeList: null,
+      currentTimeIdx: 0
+    };
+  },
+  watch: {
+    select1 (nv, ov) {
+      this.unit = 'FiveMinute'
+    }
+  },
+  computed: {
+    chartDataResolved() {
+      return this.chartData || this.defaultData;
+    }
+  },
+   mounted() {
+     const now = new Date();
+     const startTime = new Date(now.getTime() - 20 * 60 * 1000);
+     const fmt = (d) => {
+       const Y = d.getFullYear();
+       const M = String(d.getMonth() + 1).padStart(2, '0');
+       const D = String(d.getDate()).padStart(2, '0');
+       const h = String(d.getHours()).padStart(2, '0');
+       const m = String(d.getMinutes()).padStart(2, '0');
+       const s = String(d.getSeconds()).padStart(2, '0');
+       return `${Y}-${M}-${D} ${h}:${m}:${s}`;
+     };
+     const defaultVal = [fmt(startTime), fmt(now)];
+     this.$refs.picker.value1 = defaultVal;
+     this.$nextTick(() => this.selectData());
+   },
+  beforeDestroy() {
+    if (this.chart) {
+      this.chart.dispose();
+      this.chart = null;
+    }
+  },
+ 
+  methods: {
+    initChart() {
+      const DATA = this.chartDataResolved;
+      const chartEl = this.$refs.chart;
+      if (!chartEl) return;
+
+      const chartLib = this.$echarts || echarts;
+      if (!chartLib || !chartLib.init) return;
+
+      if (this.chart) {
+        this.chart.dispose();
+        this.chart = null;
+      }
+      this.chart = chartLib.init(chartEl);
+      console.log(DATA);
+      if (!DATA || !DATA.time || !DATA.time.length) {
+        console.log(222);
+        this.chart.setOption({
+          graphic: {
+            type: 'text',
+            left: 'center',
+            top: 'center',
+            style: {
+              text: '������������������',
+              fontSize: 18,
+              fill: '#909399'
+            }
+          }
+        });
+        return;
+      }
+      this.timeList = DATA.time;
+      this.currentTimeIdx = 0;
+      this.chart.setOption({
+        baseOption: {
+          timeline: {
+            axisType: 'category',
+            autoPlay: true,
+            playInterval: 1000,
+            data: DATA.time,
+            label: {
+              formatter: function (s) { return s.slice(0, 5); }
+            },
+            checkpointStyle: { borderColor: '#fff', borderWidth: 2 },
+            controlStyle: { showNextBtn: true, showPrevBtn: true }
+          },
+          title: { text: '', left: 'center', top: 0 },
+          tooltip: {
+            trigger: 'axis',
+            formatter: (params) => {
+              const time = this.timeList ? this.timeList[this.currentTimeIdx] : '';
+              var res = '������: ' + time + '<br>';
+              params.forEach(function (p) {
+                res += '<span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:' + p.color + ';margin-right:4px"></span> '
+                  + p.seriesName + ': ' + p.value[0] + ' ��g/m�� @ ' + p.value[1] + 'm<br>';
+              });
+              return res;
+            }
+          },
+          legend: { data: ['PM2.5', 'PM10'], top: 35 },
+          grid: { top: 60, bottom: 100, left: 50, right: 50 },
+          xAxis: { type: 'value', name: '������ (��g/m��)', position: 'top', splitLine: { show: true } },
+          //yAxis: { type: 'value', name: '������ (m)',  splitLine: { show: true } },
+          yAxis: { type: 'value', name: '������ (m)', min: this.high1, max: this.high2, splitLine: { show: true } },
+          series: [
+            {
+              name: 'PM2.5', type: 'line', smooth: true, symbol: 'circle', symbolSize: 6,
+              lineStyle: { width: 3, color: '#ef4444' }, itemStyle: { color: '#ef4444' },
+              areaStyle: { color: 'rgba(239,68,68,0.2)' }, data: []
+            },
+            {
+              name: 'PM10', type: 'line', smooth: true, symbol: 'circle', symbolSize: 6,
+              lineStyle: { width: 3, color: '#3b82f6' }, itemStyle: { color: '#3b82f6' },
+              areaStyle: { color: 'rgba(59,130,246,0.2)' }, data: []
+            }
+          ]
+        },
+        options: DATA.time.map(function (time, idx) {
+          return {
+            title: { text: '������������: ' + time },
+            series: [
+              { data: DATA.pm25[idx] },
+              { data: DATA.pm10[idx] }
+            ]
+          };
+        })
+      });
+
+      this.chart.on('timelinechanged', (params) => {
+        this.currentTimeIdx = params.currentIndex;
+      });
+    },
+    selectData () {
+    
+      this.$request({
+        url: '/historyRadar/list',
+        method: 'post',
+        data: {
+          startTime: this.newData[0],
+          endTime: this.newData[1],
+          high1: this.high1,
+          high2: this.high2
+        }
+      })
+        .then((res) => {
+          
+          this.defaultData  = res.data
+          this.$nextTick(() => this.initChart());
+        }).catch((err) => {
+       
+        })
+    },
+    showPickerChild (data) {
+      this.newData = data
+    }
+  }
+};
+</script>
+
+<style scoped>
+.pm-profile {
+  width: 100%;
+  background: #fff;
+  padding: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+}
+.pm-profile h2 {
+  text-align: center;
+  color: #303133;
+  margin: 0 0 20px 0;
+  font-size: 20px;
+}
+.chart-container {
+  width: 100%;
+  height: 600px;
+}
+.controls {
+  text-align: center;
+  margin-top: 10px;
+  color: #909399;
+  font-size: 14px;
+}
+.controls p {
+  margin: 0;
+}
+.topSelect {
+  display: flex;
+  margin-bottom: 20px;
+  padding: 20px 15px 0 15px;
+}
+.select11 {
+  width: 20% !important;
+}
+</style>

--
Gitblit v1.8.0