From 9e0df95ffda0ef9f2339f7caf413b357640aea28 Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期一, 06 五月 2024 08:45:14 +0800
Subject: [PATCH] 完成历史轨迹展示

---
 src/views/historymode/HistoryMode.vue   |   87 ++++
 package-lock.json                       |   14 
 src/model/FactorDatas.js                |  168 ++++++++
 src/model/Factor.js                     |  222 +++++++++++
 src/components/search/SearchBar.vue     |   27 +
 src/utils/map/calculate.js              |   57 +++
 src/components/search/OptionTime.vue    |    1 
 src/styles/elementUI.scss               |   12 
 src/assets/3dmap.css                    |   11 
 src/components/map/MapToolbox.vue       |   10 
 src/model/Legend.js                     |  294 +++++++++++++++
 src/components/monitor/FactorRadio.vue  |   24 +
 src/assets/base.css                     |    2 
 src/api/monitorDataApi.js               |   23 +
 index.html                              |    2 
 package.json                            |    2 
 src/constant/device-type.js             |   12 
 src/components/search/OptionMission.vue |    4 
 src/components/search/OptionType.vue    |    2 
 vite.config.js                          |    1 
 src/constant/radio-options.js           |  156 ++++---
 21 files changed, 1,012 insertions(+), 119 deletions(-)

diff --git a/index.html b/index.html
index 0c69b21..fc727ed 100644
--- a/index.html
+++ b/index.html
@@ -4,7 +4,7 @@
     <meta charset="UTF-8" />
     <link rel="icon" href="/favicon.ico" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Vite App</title>
+    <title>椋炵窘澶ф皵鐜鏅鸿兘璧拌埅鐩戞祴绯荤粺</title>
   </head>
   <body>
     <div id="app"></div>
diff --git a/package-lock.json b/package-lock.json
index 34e52f7..e5db76b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -33,7 +33,7 @@
         "eslint-plugin-vue": "^9.17.0",
         "jsdom": "^24.0.0",
         "prettier": "^3.0.3",
-        "sass": "^1.72.0",
+        "sass": "^1.76.0",
         "vite": "^5.1.6",
         "vitest": "^1.4.0"
       }
@@ -3514,9 +3514,9 @@
       "dev": true
     },
     "node_modules/sass": {
-      "version": "1.72.0",
-      "resolved": "https://registry.npmmirror.com/sass/-/sass-1.72.0.tgz",
-      "integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==",
+      "version": "1.76.0",
+      "resolved": "https://registry.npmmirror.com/sass/-/sass-1.76.0.tgz",
+      "integrity": "sha512-nc3LeqvF2FNW5xGF1zxZifdW3ffIz5aBb7I7tSvOoNu7z1RQ6pFt9MBuiPtjgaI62YWrM/txjWlOCFiGtf2xpw==",
       "dev": true,
       "dependencies": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -6966,9 +6966,9 @@
       "dev": true
     },
     "sass": {
-      "version": "1.72.0",
-      "resolved": "https://registry.npmmirror.com/sass/-/sass-1.72.0.tgz",
-      "integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==",
+      "version": "1.76.0",
+      "resolved": "https://registry.npmmirror.com/sass/-/sass-1.76.0.tgz",
+      "integrity": "sha512-nc3LeqvF2FNW5xGF1zxZifdW3ffIz5aBb7I7tSvOoNu7z1RQ6pFt9MBuiPtjgaI62YWrM/txjWlOCFiGtf2xpw==",
       "dev": true,
       "requires": {
         "chokidar": ">=3.0.0 <4.0.0",
diff --git a/package.json b/package.json
index b023b5e..cac16c5 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,7 @@
     "eslint-plugin-vue": "^9.17.0",
     "jsdom": "^24.0.0",
     "prettier": "^3.0.3",
-    "sass": "^1.72.0",
+    "sass": "^1.76.0",
     "vite": "^5.1.6",
     "vitest": "^1.4.0"
   }
diff --git a/src/api/monitorDataApi.js b/src/api/monitorDataApi.js
index 0b9970f..60130ec 100644
--- a/src/api/monitorDataApi.js
+++ b/src/api/monitorDataApi.js
@@ -1,11 +1,26 @@
 import { $http } from './index';
 
 /**
- *
+ * 璧拌埅鐩戞祴鏁版嵁鐩稿叧API
  */
 export default {
-  fethcRealtimeData(deviceCode, type, page, perPage) {
-    const params = `deviceCode=${deviceCode}&type=${type}&page=${page}&perPage=${perPage}`;
-    $http.get(`air/realtime/sec?${params}`);
+  /**
+   * 鑾峰彇鏈�鏂版暟鎹�
+   * @returns
+   */
+  fethcRealtimeData({ deviceCode, type, page, perPage }) {
+    return this.fetchHistroyData({ deviceCode, type, page, perPage });
+  },
+
+  /**
+   * 鑾峰彇鍘嗗彶鏁版嵁
+   * @returns
+   */
+  fetchHistroyData({ deviceCode, startTime, endTime, type, page, perPage }) {
+    let params = `deviceCode=${deviceCode}&page=${page}&perPage=${perPage}`;
+    params += type ? `&type=${type}` : '';
+    params += startTime ? `&startTime=${startTime}` : '';
+    params += endTime ? `&type=${endTime}` : '';
+    return $http.get(`air/realtime/sec?${params}`).then((res) => res.data);
   }
 };
diff --git a/src/assets/3dmap.css b/src/assets/3dmap.css
index 0ddf6ed..489d0bf 100644
--- a/src/assets/3dmap.css
+++ b/src/assets/3dmap.css
@@ -68,7 +68,7 @@
 .map-factor-selector {
     position: absolute;
     left: 1px;
-    top: 64px;
+    top: 41px;
     z-index: 100px;
 }
 
@@ -96,12 +96,11 @@
 }
 
 .map-date-selector {
-    position: absolute;
+    position: relative;
     left: 0;
     right: 0;
-    top: 70px;
-    padding: 0 4px;
-    /* background-color: #ffffffb0; */
+    top: 0px;
+    /* padding: 0 4px; */
     /* color: ffffffbd; */
 }
 
@@ -165,7 +164,7 @@
 .map-mode-change {
     position: absolute;
     left: 10px;
-    top: 80px;
+    top: 104px;
     z-index: 1000px;
     padding: 1px;
     font-size: 1rem;
diff --git a/src/assets/base.css b/src/assets/base.css
index b87ba0d..12df2d2 100644
--- a/src/assets/base.css
+++ b/src/assets/base.css
@@ -12,7 +12,7 @@
 }
 
 body {
-  --screen-min-width: 1200px;
+  --screen-min-width: 1440px;
   --screen-min-height: 600px;
   min-height: var(--screen-min-height);
   min-width: var(--screen-min-width);
diff --git a/src/components/map/MapToolbox.vue b/src/components/map/MapToolbox.vue
index 0ad54f6..ba324db 100644
--- a/src/components/map/MapToolbox.vue
+++ b/src/components/map/MapToolbox.vue
@@ -101,17 +101,7 @@
   left: 2px;
 }
 
-.el-button-custom {
-  --el-button-bg-color: var(--bg-color);
-  --el-button-hover-text-color: var(--select_color);
-  --el-button-hover-bg-color: var(--bg-color);
-  --el-button-border-color: var(--font-color);
-  --el-button-active-border-color: transparent;
-}
 
-.el-button-custom:focus-visible {
-  outline: 0px solid var(--el-button-outline-color);
-}
 
 .el-button {
   margin: initial !important;
diff --git a/src/components/monitor/FactorRadio.vue b/src/components/monitor/FactorRadio.vue
index 8d8d1c6..5282125 100644
--- a/src/components/monitor/FactorRadio.vue
+++ b/src/components/monitor/FactorRadio.vue
@@ -13,14 +13,34 @@
 <script>
 // 鐩戞祴鍥犲瓙鍗曢�夋
 import { radioOptions } from '@/constant/radio-options';
+import { TYPE0 } from '@/constant/device-type';
+
 export default {
+  props: {
+    deviceType: {
+      type: String,
+      // type0: 杞﹁浇鎴栨棤浜烘満; type1:鏃犱汉鑸�
+      default: TYPE0
+    }
+  },
   emits: ['change'],
   data() {
     return {
-      radio: radioOptions.type0[0].value,
-      options: radioOptions.type0
+      radio: radioOptions(TYPE0)[0].value
     };
   },
+  computed: {
+    options() {
+      return radioOptions(this.deviceType);
+    }
+  },
+  watch: {
+    deviceType(nV, oV) {
+      if (nV != oV) {
+        this.radio = this.options[0].value;
+      }
+    }
+  },
   method: {
     handleChange(value) {
       this.$emit('change', value);
diff --git a/src/components/search/OptionMission.vue b/src/components/search/OptionMission.vue
index 8e200aa..195e3d2 100644
--- a/src/components/search/OptionMission.vue
+++ b/src/components/search/OptionMission.vue
@@ -18,7 +18,7 @@
 </template>
 
 <script>
-import missionApi from '../../api/missionApi';
+import missionApi from '@/api/missionApi';
 import { useFetchData } from '@/composables/fetchData';
 
 export default {
@@ -64,7 +64,7 @@
   }
 };
 </script>
-<style scoped>
+<style>
 /* :deep() .el-form-item__label {
   color: red !important;
 } */
diff --git a/src/components/search/OptionTime.vue b/src/components/search/OptionTime.vue
index 0f352f7..24a1d9f 100644
--- a/src/components/search/OptionTime.vue
+++ b/src/components/search/OptionTime.vue
@@ -37,4 +37,3 @@
   }
 };
 </script>
-<style scoped></style>
diff --git a/src/components/search/OptionType.vue b/src/components/search/OptionType.vue
index 5b9334f..5ed124c 100644
--- a/src/components/search/OptionType.vue
+++ b/src/components/search/OptionType.vue
@@ -43,6 +43,7 @@
   },
   methods: {
     handleChange(value) {
+      // todo 鏍规嵁璁惧绫诲瀷鍒囨崲鍦板浘杞藉叿鐨勫浘鏍囥��
       this.$emit('update:modelValue', value);
     }
   },
@@ -51,4 +52,3 @@
   }
 };
 </script>
-<style scoped></style>
diff --git a/src/components/search/SearchBar.vue b/src/components/search/SearchBar.vue
index 03e4082..003c1a0 100644
--- a/src/components/search/SearchBar.vue
+++ b/src/components/search/SearchBar.vue
@@ -1,5 +1,5 @@
 <template>
-  <BaseCard class="map-date-selector">
+  <BaseCard class="map-date-selector flexbox-col align-items">
     <template #content>
       <el-form :inline="true">
         <OptionMission v-model="formSearch.missionCode"></OptionMission>
@@ -9,6 +9,9 @@
           v-model="formSearch.deviceCode"
         ></OptionDevice>
         <OptionTime v-model="formSearch.timeArray"></OptionTime>
+        <el-button type="primary" class="el-button-custom" @click="handleClick">
+          鍒嗘瀽
+        </el-button>
       </el-form>
     </template>
   </BaseCard>
@@ -17,6 +20,9 @@
 <script>
 // 鎼滅储妗�
 export default {
+  props: {
+    searchTime: Array
+  },
   data() {
     return {
       formSearch: {
@@ -27,7 +33,22 @@
       }
     };
   },
-  method: {}
+  emits: ['search'],
+  watch: {
+    searchTime(nV, oV) {
+      if (nV != oV) {
+        this.timeArray = this.searchTime;
+      }
+    }
+  },
+  method: {
+    handleClick() {
+      this.$emit('search', this.formSearch);
+    }
+  }
 };
 </script>
-<style scoped></style>
+<style lang="scss">
+.fy-container {
+}
+</style>
diff --git a/src/constant/device-type.js b/src/constant/device-type.js
new file mode 100644
index 0000000..8d163f8
--- /dev/null
+++ b/src/constant/device-type.js
@@ -0,0 +1,12 @@
+// 杞﹁浇
+const TYPE0 = '0a';
+// 鏃犱汉鏈�
+const TYPE1 = '0b';
+// 鏃犱汉鑸�
+const TYPE2 = '0c';
+// 瀹氱偣鐩戞祴
+const TYPE3 = '0d';
+// 鐢ㄧ數閲�
+const TYPE4 = '31';
+
+export { TYPE0, TYPE1, TYPE2, TYPE3, TYPE4 };
diff --git a/src/constant/radio-options.js b/src/constant/radio-options.js
index 3e5b2d8..28df36d 100644
--- a/src/constant/radio-options.js
+++ b/src/constant/radio-options.js
@@ -1,74 +1,84 @@
+import { TYPE0, TYPE1, TYPE2 } from '@/constant/device-type';
+
 // 鐩戞祴鍥犲瓙鍗曢�夋閫夐」
-export const radioOptions = {
-  type0: [
-    //鏃犱汉鏈�
-    {
-      label: 'NO2',
-      name: 'NO2',
-      value: '1'
-    },
-    {
-      label: 'CO',
-      name: 'CO',
-      value: '2'
-    },
-    {
-      label: 'H2S',
-      name: 'H2S',
-      value: '3'
-    },
-    {
-      label: 'SO2',
-      name: 'SO2',
-      value: '4'
-    },
-    {
-      label: 'O3',
-      name: 'NO2',
-      value: '5'
-    },
-    {
-      label: 'PM2.5',
-      name: 'PM25',
-      value: '6'
-    },
-    {
-      label: 'PM10',
-      name: 'PM10',
-      value: '7'
-    },
-    {
-      label: 'TVOC',
-      name: 'VOC',
-      value: '10'
-    }
-  ],
-  type1: [
-    //鏃犱汉鑸�
-    {
-      label: '娓╁害',
-      name: '娓╁害',
-      value: '1'
-    },
-    {
-      label: '鐢靛鐜�',
-      name: '鐢靛鐜�',
-      value: '2'
-    },
-    {
-      label: '娴婂害',
-      name: '娴婂害',
-      value: '3'
-    },
-    {
-      label: '婧惰В姘�',
-      name: '婧惰В姘�',
-      value: '4'
-    },
-    {
-      label: 'PH',
-      name: 'PH',
-      value: '5'
-    }
-  ]
-};
+function radioOptions(deviceType) {
+  if ([TYPE0, TYPE1].includes(deviceType)) {
+    return option1;
+  } else if (deviceType == TYPE2) {
+    return option2;
+  } else {
+    return [];
+  }
+}
+
+const option1 = [
+  {
+    label: 'NO2',
+    name: 'NO2',
+    value: '1'
+  },
+  {
+    label: 'CO',
+    name: 'CO',
+    value: '2'
+  },
+  {
+    label: 'H2S',
+    name: 'H2S',
+    value: '3'
+  },
+  {
+    label: 'SO2',
+    name: 'SO2',
+    value: '4'
+  },
+  {
+    label: 'O3',
+    name: 'NO2',
+    value: '5'
+  },
+  {
+    label: 'PM2.5',
+    name: 'PM25',
+    value: '6'
+  },
+  {
+    label: 'PM10',
+    name: 'PM10',
+    value: '7'
+  },
+  {
+    label: 'TVOC',
+    name: 'VOC',
+    value: '10'
+  }
+];
+
+const option2 = [
+  {
+    label: '娓╁害',
+    name: '娓╁害',
+    value: '1'
+  },
+  {
+    label: '鐢靛鐜�',
+    name: '鐢靛鐜�',
+    value: '2'
+  },
+  {
+    label: '娴婂害',
+    name: '娴婂害',
+    value: '3'
+  },
+  {
+    label: '婧惰В姘�',
+    name: '婧惰В姘�',
+    value: '4'
+  },
+  {
+    label: 'PH',
+    name: 'PH',
+    value: '5'
+  }
+];
+export { radioOptions };
diff --git a/src/model/Factor.js b/src/model/Factor.js
new file mode 100644
index 0000000..47730e4
--- /dev/null
+++ b/src/model/Factor.js
@@ -0,0 +1,222 @@
+import { Legend } from './Legend';
+
+const _hMap = {
+  1: [0, 1000], //NO2
+  2: [0, 2000], //CO
+  3: [0, 1000], //H2S
+  4: [0, 1000], //SO2
+  5: [0, 1000], //O3
+  6: [0, 1000], //PM2.5
+  7: [0, 1000], //PM10
+  8: [0, 100], //TEMPERATURE
+  9: [0, 100], //HUMIDITY
+  10: [0, 500], //VOC
+  11: [0, 1000] //NOI
+};
+const _hRange = [0, 1000];
+
+function getFactorHeight(type, data, _range) {
+  var range = _range == undefined ? _hMap.get(type) : _range;
+  var min = range[0];
+  var max = range[1];
+  var scale = max - min == 0 ? 0 : (_hRange[1] - _hRange[0]) / (max - min);
+  var offset = min;
+  // console.log("height:" + (data - offset) * scale * 10);
+  if (data < range[0]) {
+    return (range[0] - offset) * scale * 10;
+  } else if (data > range[1]) {
+    return (range[1] - offset) * scale * 10;
+  } else {
+    return (data - offset) * scale * 10;
+  }
+}
+
+/**
+ * 鐩戞祴鍥犲瓙绫�
+ * 瀛樺偍鏌愪竴绫诲瀷鐨勭洃娴嬪洜瀛愭暟鎹紝鎻愪緵3d鍦板浘缁樺埗楂樺害鎹㈢畻锛岀粯鍥捐寖鍥磋瀹氱瓑鍔熻兘
+ * 鐢ㄤ簬3d鍦板浘缁樺埗
+ */
+function Factor(options) {
+  /**
+    * {factorData: 43.209
+        factorId: "1"
+        factorName: "NO2"
+        physicalQuantity: 211.1
+        sensorId: null
+        statusList: null}
+    */
+  this.datas = []; // 鍘熷鏁版嵁
+  // this.lnglats = [] //3d鍦板浘褰撳墠灞曠ず鍧愭爣鐐规暟缁�
+  this.factorName;
+  this.factorId;
+  this.heights = []; //3d鍦板浘褰撳墠灞曠ず鍧愭爣鐐瑰搴旂殑楂樺害鏁扮粍
+  this.colors = []; // 3d鍦板浘褰撳墠灞曠ず鍧愭爣鐐瑰搴旂殑棰滆壊鏁扮粍
+  this.bottomColor; //鏈�灏忓�煎搴旂殑鍥句緥鑹�
+  this.min = -1; // 褰撳墠鏄剧ず鐨勬渶灏忓��
+  this.max = -1; // 褰撳墠鏄剧ず鐨勬渶澶у��
+  this.originMin = -1; // 鍘熷鏁版嵁涓殑鏈�灏忓��
+  this.originMax = -1; // 鍘熷鏁版嵁涓殑鏈�澶у��
+  this.standardMin = -1; //鐩戞祴鍥犲瓙绫诲瀷瀵瑰簲鐨勬爣鍑嗘渶灏忓��
+  this.standardMax = -1; //鐩戞祴鍥犲瓙绫诲瀷瀵瑰簲鐨勬爣鍑嗘渶澶у��
+
+  this.legendType = Legend.S_TYPE; //鍥句緥妯″紡
+
+  if (options != undefined) {
+    this.datas = options.datas;
+    this.heights = options.heights;
+    this.min = options.min;
+    this.max = options.max;
+    this.originMin = options.originMin;
+    this.originMax = options.originMax;
+
+    this.factorName = options.factorName;
+    this.factorId = options.factorId;
+    this.colors = options.colors;
+    this.bottomColor = options.bottomColor;
+    this.standardMin = options.standardMin;
+    this.standardMax = options.standardMax;
+  }
+}
+
+Factor.prototype = {
+  // drawMode: 缁樺埗妯″紡锛�0锛氳嚜鍔ㄦā寮忥紝鑷姩璁$畻褰撳墠鏁版嵁鐨勮寖鍥达紝缁樺埗鍚堥�傜殑姣斾緥锛�1锛氭墜鍔ㄦā寮忥紝鏍规嵁椤甸潰璁剧疆鐨勭粯鍥捐寖鍥磋繘琛岀粯鍒�
+  pushData: function (data, drawMode) {
+    if (this.factorName == undefined) {
+      this.factorName = data.factorName;
+      this.factorId = data.factorId;
+    } else {
+      if (this.factorName != data.factorName) {
+        console.log(
+          '閿欒: Factor涓彃鍏ョ殑鏁版嵁鍓嶅悗鍚嶇О涓嶄竴鑷达紝鍘熷洜瀛愶細' +
+            this.factorName +
+            '锛屾柊鍥犲瓙锛�' +
+            data.factorName
+        );
+      }
+    }
+    this.datas.push(data);
+    this.getRange(data, drawMode);
+
+    if (this.standardMin == -1) {
+      var range = Legend.getStandardRange(this.factorName);
+      this.standardMin = range[0];
+      this.standardMax = range[1];
+    }
+  },
+  getRange: function (data, drawMode) {
+    if (this.min == -1) {
+      this.min = data.factorData;
+      this.max = data.factorData;
+    }
+    if (this.originMin == -1) {
+      this.originMin = data.factorData;
+      this.originMax = data.factorData;
+    }
+    if (drawMode == 0) {
+      this.min = Math.min(this.min, data.factorData);
+      this.max = Math.max(this.max, data.factorData);
+      // this.min = this.standardMin
+      // this.max = this.standardMax
+    }
+    this.originMin = Math.min(this.originMin, data.factorData);
+    this.originMax = Math.max(this.originMax, data.factorData);
+  },
+  getHeight: function () {
+    this.heights = [];
+    this.colors = [];
+    this.datas.forEach((d) => {
+      var h = getFactorHeight(d.factorId, d.factorData, [this.min, this.max]);
+      if (d.factorData == -1) {
+        h = -1;
+      }
+      this.heights.push(h);
+      var c = Legend.getColor(
+        this.factorName,
+        this.legendType,
+        d.factorData,
+        this.min,
+        this.max
+      );
+      this.colors.push(c);
+      // this.heights.push(d.factorData)
+    });
+    this.bottomColor = Legend.getColor(
+      this.factorName,
+      this.legendType,
+      this.standardMin,
+      this.min,
+      this.max
+    );
+    // console.log(this.factorName + ':' + this.bottomColor);
+  },
+  setRange: function (range) {
+    this.min = range[0];
+    this.max = range[1];
+    this.legendType = Legend.C_TYPE;
+    this.getHeight();
+  },
+  clearRange: function () {
+    this.min = this.originMin;
+    this.max = this.originMax;
+    this.legendType = Legend.D_TYPE;
+    this.getHeight();
+  },
+  standardRange: function () {
+    this.min = this.originMin;
+    this.max = this.originMax;
+    // this.min = this.standardMin
+    // this.max = this.standardMax
+    this.legendType = Legend.S_TYPE;
+    this.getHeight();
+  },
+  // 鏍规嵁寮�濮嬪拰缁撴潫涓嬫爣鑾峰彇瀵瑰簲浣嶇疆鏁版嵁闆�
+  getByIndex: function (s, e) {
+    var d = this.datas.slice(s, e);
+    var h = this.heights.slice(s, e);
+    return new Factor({
+      datas: d,
+      heights: h,
+      min: this.min,
+      max: this.max,
+      originMin: this.originMin,
+      originMax: this.originMax,
+      factorName: this.factorName,
+      colors: this.colors,
+      bottomColor: this.bottomColor,
+      standardMin: this.standardMin,
+      standardMax: this.standardMax
+    });
+  },
+  // 鏂板鏁版嵁鍚屾椂鎻掑抚
+  insertFrame: function (factor, count, isDraw) {
+    var d1 = this.datas[this.datas.length - 1];
+    var d2 = factor.datas[0];
+    if (d1 == undefined || d2 == undefined) {
+      return;
+    }
+    // 鍗曞抚鏁版嵁鍊肩殑宸��
+    var dValue = {
+      factorData: (d2.factorData - d1.factorData) / count,
+      physicalQuantity: (d2.physicalQuantity - d2.physicalQuantity) / count
+    };
+    for (let i = 0; i < count - 1; i++) {
+      var _data = {
+        factorData: d1.factorData + dValue.factorData * (i + 1),
+        factorId: d1.factorId,
+        factorName: d1.factorName,
+        physicalQuantity:
+          d1.physicalQuantity + dValue.physicalQuantity * (i + 1),
+        sensorId: d1.sensorId,
+        statusList: d1.statusList
+      };
+      if (!isDraw) {
+        _data.factorData = -1;
+        _data.physicalQuantity = -1;
+      }
+      this.datas.push(_data);
+    }
+    // this.datas.push(d2)
+  }
+};
+
+export { Factor };
diff --git a/src/model/FactorDatas.js b/src/model/FactorDatas.js
new file mode 100644
index 0000000..b6b1d30
--- /dev/null
+++ b/src/model/FactorDatas.js
@@ -0,0 +1,168 @@
+import { Factor } from "./Factor";
+import calculate from "@/utils/map/calculate";
+
+/**
+ *
+ */
+function FactorDatas(options) {
+  // 鏃堕棿
+  this.times = [];
+  // 鍘熷缁忕含搴︼紙GPS锛�
+  this.lnglats_GPS = [];
+  // 楂樺痉缁忕含搴�
+  this.lnglats_GD = [];
+  // 锛堥珮寰峰湴鍥撅級杞崲鍚庣殑3d鍦板浘缁樺埗鍧愭爣
+  this.coors_GD = [];
+  // 鐩戞祴鍥犲瓙鏁版嵁锛孧ap<String, Factor>
+  this.factor = new Map();
+
+  if (options != undefined) {
+    this.times = options.times;
+    this.lnglats_GPS = options.lnglats_GPS;
+    this.lnglats_GD = options.lnglats_GD;
+    this.coors_GD = options.coors_GD;
+    this.factor = options.factor;
+  }
+}
+
+FactorDatas.prototype = {
+  /**
+     * @param drawMode 缁樺埗妯″紡锛�0锛氳嚜鍔ㄦā寮忥紝鑷姩璁$畻褰撳墠鏁版嵁鐨勮寖鍥达紝缁樺埗鍚堥�傜殑姣斾緥锛�1锛氭墜鍔ㄦā寮忥紝鏍规嵁椤甸潰璁剧疆鐨勭粯鍥捐寖鍥磋繘琛岀粯鍒�
+     * @param  dataList 缁撴瀯濡備笅
+     * [{
+        "time": "2021-04-21 21:11:59",
+        "deviceCode": "0a",
+        "lng": 121.229385,
+        "lat": 30.828487
+        "values": [
+            {
+            "factorId": "1",
+            "factorName": "NO2",
+            "sensorId": null,
+            "factorData": 65.4,
+            "physicalQuantity": 215.39,
+            "statusList": null
+            },
+        ],
+        }]
+        */
+  setData: function (dataList, drawMode, callback) {
+    this.clearData();
+
+    dataList.forEach((d) => {
+      this.times.push(d.time);
+      this.lnglats_GPS.push([d.lng, d.lat]);
+      d.values.forEach((v) => {
+        var f = this.factor[v.factorId];
+        if (f == undefined) {
+          f = new Factor();
+          this.factor[v.factorId] = f;
+        }
+        f.pushData(v, drawMode == undefined ? 0 : drawMode);
+      });
+    });
+
+    
+
+    this.convertGPS(this.lnglats_GPS, callback);
+  },
+
+  // 鏂板涓�涓柊鏁版嵁
+  addData: function (dataList, drawMode, callback) {
+    var newGps = [];
+    dataList.forEach((data) => {
+      this.times.push(data.time);
+      this.lnglats_GPS.push([data.lng, data.lat]);
+      newGps.push([data.lng, data.lat]);
+      // this.coors_GD锛� 3d鍦板浘鐨勫潗鏍囬�氳繃绗竴娆$粯鍒朵箣鍚庤幏寰�
+      data.values.forEach((d) => {
+        var f = this.factor[d.factorId];
+        if (f == undefined) {
+          f = new Factor();
+          this.factor[d.factorId] = f;
+        }
+        f.pushData(d, drawMode == undefined ? 0 : drawMode);
+      });
+    });
+    this.convertGPS(newGps, callback);
+  },
+
+  convertGPS: function (gpsList, callback) {
+    var that = this;
+    calculate.convertFromGPS(gpsList, function (result) {
+      var gd = that.lnglats_GD;
+      gd.push.apply(gd, result);
+
+      var coor_GD = calculate.lngLatToGeodeticCoord(result);
+      var coor = that.coors_GD;
+      coor.push.apply(coor, coor_GD);
+
+      if (typeof callback === 'function') {
+        callback();
+      }
+    });
+  },
+
+  clearData: function () {
+    this.times = [];
+    this.lnglats_GPS = [];
+    this.lnglats_GD = [];
+    this.coors_GD = [];
+    this.factor = new Map();
+  },
+
+  // 璁剧疆缁樺浘鑼冨洿
+  setRange: function (key, range) {
+    this.factor[key].setRange(range);
+  },
+
+  // 閲嶇疆缁樺浘鑼冨洿
+  resetRange: function (key) {
+    this.factor[key].clearRange();
+  },
+
+  // 璁剧疆涓烘爣鍑嗙粯鍥捐寖鍥�
+  standardRange: function (key) {
+    this.factor[key].standardRange();
+  },
+
+  // 鏍规嵁褰撳墠缁樺浘鑼冨洿閲嶆柊璁$畻缁樺浘楂樺害
+  refreshHeight: function (key) {
+    if (key != undefined) {
+      this.factor[key].getHeight();
+    } else {
+      for (const k in this.factor) {
+        this.factor[k].getHeight();
+      }
+    }
+  },
+
+  // 鏍规嵁寮�濮嬪拰缁撴潫涓嬫爣鑾峰彇瀵瑰簲浣嶇疆鏁版嵁闆�
+  getByIndex: function (s, e) {
+    var t = this.times.slice(s, e);
+    var l = this.lnglats_GPS.slice(s, e);
+    var l_GD = this.lnglats_GD.slice(s, e);
+    var c = this.coors_GD.slice(s, e);
+    var f = new Map();
+    for (const key in this.factor) {
+      if (Object.hasOwnProperty.call(this.factor, key)) {
+        const element = this.factor[key];
+        f[key] = element.getByIndex(s, e);
+      }
+    }
+    return new FactorDatas({
+      times: t,
+      lnglats_GPS: l,
+      lnglats_GD: l_GD,
+      coors_GD: c,
+      factor: f
+    });
+  },
+
+  // 鑾峰彇鏁版嵁闀垮害
+  length: function () {
+    return this.lnglats_GD.length;
+  },
+};
+
+export { FactorDatas };
diff --git a/src/model/Legend.js b/src/model/Legend.js
new file mode 100644
index 0000000..054ad4b
--- /dev/null
+++ b/src/model/Legend.js
@@ -0,0 +1,294 @@
+/**
+ * 鐩戞祴鍥犲瓙鍥句緥
+ */
+const Legend = {
+  S_TYPE: 0, //鏍囧噯鍥句緥
+  D_TYPE: 1, //鍔ㄦ�佸浘渚�
+  C_TYPE: 2, //鑷畾涔夎寖鍥村浘渚�
+
+  //鍚勭洃娴嬪洜瀛愭暟鎹垎绾э紙鏍囧噯锛�
+  _legend_r: {
+    NO2: [0, 100, 200, 700, 1200, 2340],
+    CO: [0, 5, 10, 35, 60, 90],
+    H2S: [0, 150, 500, 650, 800, 1600],
+    SO2: [0, 150, 500, 650, 800, 1600],
+    O3: [0, 160, 200, 300, 400, 800],
+    PM25: [0, 35, 75, 115, 150, 250],
+    PM10: [0, 50, 150, 250, 350, 420],
+    VOC: [0, 200, 400, 600, 1000, 2000, 4000],
+    TMP: [-10, 0, 10, 20, 30, 40],
+    spC: [0, 200, 400, 600, 800, 1000],
+    tur: [0, 50, 100, 150, 200, 250],
+    DO: [0, 3, 5, 7, 9, 11],
+    PH: [1, 3, 5, 7, 9, 11, 13]
+  },
+
+  //鍚勭洃娴嬪洜瀛愭暟鎹垎绾э紙鏍囧噯锛夊搴旈鑹�
+  _legend_c: {
+    NO2: [
+      [0, 0.89, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [0.49, 0, 0.14, 0.75]
+    ],
+    CO: [
+      [0, 0.89, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [0.49, 0, 0.14, 0.75]
+    ],
+    H2S: [
+      [0, 0.89, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [0.49, 0, 0.14, 0.75]
+    ],
+    SO2: [
+      [0, 0.89, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [0.49, 0, 0.14, 0.75]
+    ],
+    O3: [
+      [0, 0.89, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [0.49, 0, 0.14, 0.75]
+    ],
+    PM25: [
+      [0, 0.89, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [0.49, 0, 0.14, 0.75]
+    ],
+    PM10: [
+      [0, 0.89, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [0.49, 0, 0.14, 0.75]
+    ],
+    VOC: [
+      [0, 0.89, 0, 0.75],
+      [0, 0.7, 0, 0.75],
+      [0.8, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.4, 0, 0.3, 0.75],
+      [0.6, 0, 0.3, 0.75]
+    ],
+    TMP: [
+      [0, 0.89, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [0.49, 0, 0.14, 0.75]
+    ],
+    spC: [
+      [0, 0.89, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [0.49, 0, 0.14, 0.75]
+    ],
+    tur: [
+      [0, 0.89, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [0.49, 0, 0.14, 0.75]
+    ],
+    DO: [
+      [0.49, 0, 0.14, 0.75],
+      [0.6, 0, 0.3, 0.75],
+      [1, 0, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 1, 0, 0.75],
+      [0, 0.89, 0, 0.75]
+    ],
+    PH: [
+      [0, 0.89, 0, 0.75],
+      [0, 0.7, 0, 0.75],
+      [0.8, 1, 0, 0.75],
+      [1, 0.49, 0, 0.75],
+      [1, 0, 0, 0.75],
+      [0.4, 0, 0.3, 0.75],
+      [0.6, 0, 0.3, 0.75]
+    ]
+  },
+
+  _custom: [
+    [0.05, 0.9, 0.03, 0.75],
+    [0.3, 0.65, 0.02, 0.75],
+    [0.87, 0.92, 0.03, 0.75],
+    [0.8, 0.67, 0.04, 0.75],
+    [0.92, 0.28, 0.07, 0.75],
+    [0.6, 0.05, 0.05, 0.75]
+  ],
+
+  getStandardRange: function (name) {
+    var range = this._legend_r[name];
+    if (range == undefined) {
+      range = this._legend_r['PM25'];
+    }
+    var min = range[0];
+    var max = range[range.length - 1];
+    // for (const key in range) {
+    //   if (min == undefined) {
+    //     min = parseInt(key)
+    //   }
+    //   max = parseInt(key)
+    // }
+    if (name == 'CO') {
+      min *= 1000;
+      max *= 1000;
+    }
+
+    return [min, max];
+  },
+
+  getColor: function (name, type, data, min, max) {
+    if (type == this.S_TYPE) {
+      return this.getStandardColor(name, data);
+    } else {
+      return this.getCustomColor(data, min, max);
+    }
+  },
+
+  /**
+   * 鑾峰彇鐩戞祴鍥犲瓙褰撳墠娴撳害瀵瑰簲鐨勯鑹�
+   * @param name 鐩戞祴鍥犲瓙鍚嶇О
+   * @param data 鐩戞祴鍥犲瓙娴撳害
+   */
+  getStandardColor: function (name, data) {
+    var range = this._legend_r[name];
+    var colors = this._legend_c[name];
+    if (range == undefined) {
+      range = this._legend_r['PM25'];
+      colors = this._legend_c['PM25'];
+    }
+    // return colors[0]
+
+    var selected = undefined;
+    for (let i = 0; i < range.length; i++) {
+      const d = range[i];
+      var d1 = d;
+      if (name == 'CO') {
+        d1 *= 1000;
+      }
+      if (data >= d1) {
+        selected = i;
+      } else {
+        break;
+      }
+    }
+
+    // 閬垮厤涓嬫爣瓒婄晫
+    if (selected >= colors.length) {
+      selected = colors.length - 1;
+    }
+
+    // console.log(name + ': ' + selected);
+    return colors[selected];
+  },
+
+  getCustomColor: function (data, min, max) {
+    var per = (max - min) / this._custom.length;
+    var i = parseInt(data / per);
+    if (i >= this._custom.length) {
+      i = this._custom.length - 1;
+    }
+    return this._custom[i];
+  },
+
+  /**
+   * 鑾峰彇鍒嗘瀽鍥句緥
+   */
+  refreshLegend: function (eId, name, animation, type, min, max) {
+    var legend = $('#' + eId);
+    legend.empty();
+
+    var r = this._legend_r[name];
+    var c = this._legend_c[name];
+    // 娌℃湁鎵惧埌鏍囧噯鍥句緥鐨勫洜瀛愶紝榛樿浣跨敤鑷畾涔夎寖鍥村浘渚�
+    if (r == undefined) {
+      type = this.C_TYPE;
+    }
+    var range = [];
+    if (type != this.S_TYPE && min != undefined && max != undefined) {
+      var count = this._custom.length;
+      var per = (max - min) / count;
+      for (let i = 0; i < count; i++) {
+        range.push([(min + per * i).toFixed(1), this._custom[i]]);
+      }
+    } else {
+      for (let i = 0; i < r.length; i++) {
+        range.push([r[i], c[i]]);
+      }
+    }
+
+    for (let i = 0; i < range.length; i++) {
+      const r = range[i];
+      const nextR = range[i + 1];
+      var div1 = $('<div></div>');
+      div1.addClass('flexbox align-items margin-top');
+      var div2 = $('<div></div>');
+      div2.addClass('rectangle');
+
+      var color = r[1];
+      var bgcolor =
+        'rgba(' +
+        color[0] * 255 +
+        ', ' +
+        color[1] * 255 +
+        ', ' +
+        color[2] * 255 +
+        ', ' +
+        color[3] +
+        ')';
+      div2.css('background-color', bgcolor);
+      var div3 = $('<div></div>');
+      var d;
+      if (nextR != undefined) {
+        d = r[0] + '&nbsp;~' + nextR[0] + '&nbsp;' + Util.factorUnit2[name];
+      } else {
+        d =
+          '&nbsp;&nbsp;&nbsp;&nbsp; > &nbsp;' +
+          r[0] +
+          ' &nbsp;' +
+          Util.factorUnit2[name];
+      }
+      div3.append(d);
+      div1.append(div2);
+      div1.append(div3);
+      legend.append(div1);
+    }
+
+    if (animation == false) {
+      return;
+    }
+    legend.hide('fast', function () {
+      setTimeout(() => {
+        legend.show('fast');
+      }, 500);
+    });
+  }
+};
+
+export { Legend };
diff --git a/src/styles/elementUI.scss b/src/styles/elementUI.scss
index 281d6e2..813ba05 100644
--- a/src/styles/elementUI.scss
+++ b/src/styles/elementUI.scss
@@ -13,3 +13,15 @@
 // .el-radio {
 //   --el-radio-text-color: white;
 // }
+
+.el-button-custom {
+  --el-button-bg-color: var(--bg-color);
+  --el-button-hover-text-color: var(--select_color);
+  --el-button-hover-bg-color: var(--bg-color);
+  --el-button-border-color: var(--font-color);
+  --el-button-active-border-color: transparent;
+}
+
+.el-button-custom:focus-visible {
+  outline: 0px solid var(--el-button-outline-color);
+}
\ No newline at end of file
diff --git a/src/utils/map/calculate.js b/src/utils/map/calculate.js
index 058531f..505d082 100644
--- a/src/utils/map/calculate.js
+++ b/src/utils/map/calculate.js
@@ -4,6 +4,52 @@
 
 import { map } from './index_old';
 
+function _prepare4convert(lnglats) {
+  var coor = [];
+  var maxLength = 1000;
+  var start = 0;
+  var end = start + maxLength;
+  while (end <= lnglats.length) {
+    coor.push(lnglats.slice(start, end));
+    start += maxLength;
+    end += maxLength;
+  }
+  if (start < lnglats.length) {
+    coor.push(lnglats.slice(start));
+  }
+  return coor;
+}
+
+function parse2LngLat(lnglats) {
+  // 鍒涘缓鍖呭惈4涓妭鐐圭殑鎶樼嚎鍙婃枃瀛楁爣娉�
+  var path = [];
+  lnglats.forEach(function (value) {
+    // eslint-disable-next-line no-undef
+    path.push(new AMap.LngLat(value[0], value[1]));
+  });
+  return path;
+}
+
+/**
+ * 灏唃ps缁忕含搴﹁浆鎹负楂樺痉鍦板浘缁忕含搴�
+ * @param {*} lnglats
+ * @param {*} callback
+ */
+function _convertLatlng(index, coor, lnglats, callback) {
+  if (index < coor.length) {
+    var path = parse2LngLat(coor[index]);
+    // eslint-disable-next-line no-undef
+    AMap.convertFrom(path, 'gps', function (status, result) {
+      if (result.info === 'ok') {
+        lnglats.push.apply(lnglats, result.locations);
+        _convertLatlng(index + 1, coor, lnglats, callback);
+      }
+    });
+  } else {
+    callback(lnglats);
+  }
+}
+
 export default {
   /**
    * 鏍规嵁鍧愭爣鐐广�佽窛绂诲拰瑙掑害锛屽緱鍒板彟涓�涓潗鏍囩偣
@@ -55,5 +101,16 @@
       coors_GD.push(p);
     }
     return coors_GD;
+  },
+
+  convertFromGPS: function (gps, callback) {
+    var coor = _prepare4convert(gps);
+    _convertLatlng(0, coor, [], function (result) {
+      var gd = [];
+      result.forEach((r) => {
+        gd.push([r.lng, r.lat]);
+      });
+      callback(gd);
+    });
   }
 };
diff --git a/src/views/historymode/HistoryMode.vue b/src/views/historymode/HistoryMode.vue
index 1c71387..50dc1f0 100644
--- a/src/views/historymode/HistoryMode.vue
+++ b/src/views/historymode/HistoryMode.vue
@@ -1,22 +1,44 @@
 <template>
   <div class="fy-container">
-    <FactorRadio @change="(e) => (factorType = e)"></FactorRadio>
-    <SearchBar></SearchBar>
+    <el-row justify="center">
+      <SearchBar search-time="" @search="fetchHistroyData"></SearchBar>
+    </el-row>
+    <FactorRadio
+      :device-type="deviceType"
+      @change="(e) => (factorType = e)"
+    ></FactorRadio>
   </div>
 </template>
 
 <script>
 import Layer from '@/utils/map/3dLayer';
 import marks from '@/utils/map/marks';
+import monitorDataApi from '@/api/monitorDataApi';
+import { useFetchData } from '@/composables/fetchData';
+import moment from 'moment';
+import { TYPE0 } from '@/constant/device-type';
+import { FactorDatas } from '@/model/FactorDatas';
 
 export default {
-  name: 'HistoryPage',
+  setup() {
+    const { loading, fetchData } = useFetchData(10000);
+    return { loading, fetchData };
+  },
   data() {
     return {
-      factorType: '',
-      factorDatas: [],
+      // 鐩戞祴璁惧绫诲瀷
+      deviceType: TYPE0,
+      // 鐩戞祴鍥犲瓙鐨勭被鍨嬬紪鍙�
+      factorType: '1',
+      // 鐩戞祴鏁版嵁
+      factorDatas: new FactorDatas(),
+      // 鍐冲畾缁樺埗3D鍥惧舰鏃舵槸鍚︿笌鍘熷浘鍍忓悎骞�
       merge: false,
-      setCenter: true
+      // 鍐冲畾缁樺埗瀹�3D鍥惧舰鍚庡湴鍥捐瑙掓槸鍚﹁嚜鍔ㄥ洖涓�
+      setCenter: true,
+      // 缁樺埗妯″紡锛�0锛氳嚜鍔ㄦā寮忥紝鑷姩璁$畻褰撳墠鏁版嵁鐨勮寖鍥达紝缁樺埗鍚堥�傜殑姣斾緥锛�1锛氭墜鍔ㄦā寮忥紝鏍规嵁椤甸潰璁剧疆鐨勭粯鍥捐寖鍥磋繘琛岀粯鍒�
+      drawMode: 0,
+      searchTime: []
     };
   },
   watch: {
@@ -28,6 +50,7 @@
   },
   methods: {
     draw() {
+      // todo 鍒锋柊鍥句緥
       const factor = this.factorDatas.factor[this.factorType];
       this.drawRoadMap(factor);
       this.drawMassMarks(factor);
@@ -54,12 +77,62 @@
         // 4. 琛ㄦ牸鏁版嵁璺宠浆瀹氫綅
         // Table.locate(i);
       });
+    },
+    onFetchData(type, data) {
+      // todo 鏍规嵁璁惧绫诲瀷鍒囨崲鍦板浘鐩戞祴鍥犲瓙灞曠ず鍗曢�夋銆佹姌绾垮浘澶嶉�夋銆佹暟鎹〃鏍煎閫夋鐨勫洜瀛愮被鍨�
+      this.deviceType = type;
+      this.factorDatas.setData(data, this.drawMode, () => {
+        this.factorDatas.refreshHeight(this.factorType);
+        this.draw();
+      });
+    },
+    fetchHistroyData(option) {
+      const { deviceCode, type, timeArray } = option;
+      let startTime, endTime;
+      if (timeArray && timeArray.length == 2) {
+        startTime = moment(timeArray[0]).format('YYYY-MM-DD HH:mm:ss');
+        endTime = moment(timeArray[1]).format('YYYY-MM-DD HH:mm:ss');
+      }
+      this.fetchData((page, pageSize) => {
+        return monitorDataApi
+          .fetchHistroyData({
+            deviceCode,
+            startTime,
+            endTime,
+            type,
+            page,
+            perPage: pageSize
+          })
+          .then((res) => this.onFetchData(type, res.data));
+      });
+    },
+    fetchRealTimeData() {
+      // fixme 2024.5.3 姝ゅ鍒濆鑾峰彇鐨勬暟鎹紝鍙傛暟搴旇鐢眘earchbar鍐冲畾锛屽悗缁慨鏀�
+      this.fetchData((page, pageSize) => {
+        return monitorDataApi
+          .fetchHistroyData({
+            deviceCode: '0a0000000001',
+            // type: TYPE0,
+            page,
+            perPage: 100
+          })
+          .then((res) => {
+            if (res.data.length > 0) {
+              const s = new Date(res.data[0].time);
+              const e = new Date(res.data[res.data.length - 1].time);
+              this.searchTime = [s, e];
+            }
+            this.onFetchData(TYPE0, res.data);
+          });
+      });
     }
+  },
+  mounted() {
+    this.fetchRealTimeData();
   }
 };
 </script>
 <style scoped>
 .fy-container {
-  background-color: antiquewhite;
 }
 </style>
diff --git a/vite.config.js b/vite.config.js
index 3487c29..ae49381 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -34,6 +34,7 @@
     preprocessorOptions: {
       scss: {
         additionalData: `@use "@/styles/index.scss" as *;`
+        // additionalData: '@import   "@/styles/index.scss";'
       }
     }
   },

--
Gitblit v1.9.3