From c40500d288339cd9b2200f8f909e3cd5471c0c22 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期五, 30 八月 2024 17:38:29 +0800
Subject: [PATCH] 1. 优化3D动画中风向的变化逻辑; 2. 修复折线图切换因子时,数据直接跳转至起始处的问题; 3. 折线图和表格加回风向因子; 4. 优化风向的均值计算为矢量计算,同时最大最小值不显示; 5. 新增表格数据导出功能;

---
 src/components/monitor/DataTable.vue            |  119 +++++++++++-
 src/utils/map/animation.js                      |   10 
 src/views/historymode/HistoryMode.vue           |   15 +
 package-lock.json                               |  156 +++++++++++++++++
 src/utils/map/dialog.js                         |   56 ++---
 src/components/monitor/DataSummary.vue          |   93 +++++++--
 package.json                                    |    1 
 src/model/Factor.js                             |   39 +++
 src/views/historymode/component/DataSheet.vue   |    2 
 src/components/chart/ProgressLineChart.vue      |    3 
 src/constant/checkbox-options/options-jingan.js |   10 
 src/utils/file.js                               |   18 ++
 12 files changed, 426 insertions(+), 96 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 61ffb58..4c6118f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,6 +29,7 @@
         "unplugin-vue-components": "^0.26.0",
         "vue": "^3.4.21",
         "vue-router": "^4.3.0",
+        "xlsx": "^0.18.5",
         "xml2json": "^0.12.0"
       },
       "devDependencies": {
@@ -1371,6 +1372,14 @@
         "node": ">=0.4.0"
       }
     },
+    "node_modules/adler-32": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmmirror.com/adler-32/-/adler-32-1.3.1.tgz",
+      "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
     "node_modules/agent-base": {
       "version": "7.1.0",
       "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.0.tgz",
@@ -1601,6 +1610,18 @@
       "resolved": "https://registry.npmmirror.com/caseless/-/caseless-0.12.0.tgz",
       "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
     },
+    "node_modules/cfb": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/cfb/-/cfb-1.2.2.tgz",
+      "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
+      "dependencies": {
+        "adler-32": "~1.3.0",
+        "crc-32": "~1.2.0"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
     "node_modules/chai": {
       "version": "4.4.1",
       "resolved": "https://registry.npmmirror.com/chai/-/chai-4.4.1.tgz",
@@ -1688,6 +1709,14 @@
       "resolved": "https://registry.npmmirror.com/cldrjs/-/cldrjs-0.5.5.tgz",
       "integrity": "sha512-KDwzwbmLIPfCgd8JERVDpQKrUUM1U4KpFJJg2IROv89rF172lLufoJnqJ/Wea6fXL5bO6WjuLMzY8V52UWPvkA=="
     },
+    "node_modules/codepage": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmmirror.com/codepage/-/codepage-1.15.0.tgz",
+      "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
     "node_modules/color-convert": {
       "version": "2.0.1",
       "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
@@ -1750,6 +1779,17 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.2.tgz",
       "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
+    },
+    "node_modules/crc-32": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/crc-32/-/crc-32-1.2.2.tgz",
+      "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
+      "bin": {
+        "crc32": "bin/crc32.njs"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
     },
     "node_modules/cross-spawn": {
       "version": "7.0.3",
@@ -2598,6 +2638,14 @@
       },
       "engines": {
         "node": ">= 6"
+      }
+    },
+    "node_modules/frac": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz",
+      "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
+      "engines": {
+        "node": ">=0.8"
       }
     },
     "node_modules/fs.realpath": {
@@ -4507,6 +4555,17 @@
       "resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz",
       "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
     },
+    "node_modules/ssf": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmmirror.com/ssf/-/ssf-0.11.2.tgz",
+      "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
+      "dependencies": {
+        "frac": "~1.1.2"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
     "node_modules/sshpk": {
       "version": "1.18.0",
       "resolved": "https://registry.npmmirror.com/sshpk/-/sshpk-1.18.0.tgz",
@@ -5324,6 +5383,22 @@
         "node": ">=8"
       }
     },
+    "node_modules/wmf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/wmf/-/wmf-1.0.2.tgz",
+      "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/word": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/word/-/word-0.3.0.tgz",
+      "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
     "node_modules/wrap-ansi": {
       "version": "8.1.0",
       "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
@@ -5427,6 +5502,26 @@
         "utf-8-validate": {
           "optional": true
         }
+      }
+    },
+    "node_modules/xlsx": {
+      "version": "0.18.5",
+      "resolved": "https://registry.npmmirror.com/xlsx/-/xlsx-0.18.5.tgz",
+      "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
+      "dependencies": {
+        "adler-32": "~1.3.0",
+        "cfb": "~1.2.1",
+        "codepage": "~1.15.0",
+        "crc-32": "~1.2.1",
+        "ssf": "~0.11.2",
+        "wmf": "~1.0.1",
+        "word": "~0.3.0"
+      },
+      "bin": {
+        "xlsx": "bin/xlsx.njs"
+      },
+      "engines": {
+        "node": ">=0.8"
       }
     },
     "node_modules/xml-name-validator": {
@@ -6419,6 +6514,11 @@
       "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
       "dev": true
     },
+    "adler-32": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmmirror.com/adler-32/-/adler-32-1.3.1.tgz",
+      "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A=="
+    },
     "agent-base": {
       "version": "7.1.0",
       "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.0.tgz",
@@ -6607,6 +6707,15 @@
       "resolved": "https://registry.npmmirror.com/caseless/-/caseless-0.12.0.tgz",
       "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
     },
+    "cfb": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/cfb/-/cfb-1.2.2.tgz",
+      "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
+      "requires": {
+        "adler-32": "~1.3.0",
+        "crc-32": "~1.2.0"
+      }
+    },
     "chai": {
       "version": "4.4.1",
       "resolved": "https://registry.npmmirror.com/chai/-/chai-4.4.1.tgz",
@@ -6676,6 +6785,11 @@
       "resolved": "https://registry.npmmirror.com/cldrjs/-/cldrjs-0.5.5.tgz",
       "integrity": "sha512-KDwzwbmLIPfCgd8JERVDpQKrUUM1U4KpFJJg2IROv89rF172lLufoJnqJ/Wea6fXL5bO6WjuLMzY8V52UWPvkA=="
     },
+    "codepage": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmmirror.com/codepage/-/codepage-1.15.0.tgz",
+      "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA=="
+    },
     "color-convert": {
       "version": "2.0.1",
       "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
@@ -6729,6 +6843,11 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.2.tgz",
       "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
+    },
+    "crc-32": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/crc-32/-/crc-32-1.2.2.tgz",
+      "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
     },
     "cross-spawn": {
       "version": "7.0.3",
@@ -7384,6 +7503,11 @@
         "combined-stream": "^1.0.8",
         "mime-types": "^2.1.12"
       }
+    },
+    "frac": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz",
+      "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA=="
     },
     "fs.realpath": {
       "version": "1.0.0",
@@ -8822,6 +8946,14 @@
       "resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz",
       "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
     },
+    "ssf": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmmirror.com/ssf/-/ssf-0.11.2.tgz",
+      "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
+      "requires": {
+        "frac": "~1.1.2"
+      }
+    },
     "sshpk": {
       "version": "1.18.0",
       "resolved": "https://registry.npmmirror.com/sshpk/-/sshpk-1.18.0.tgz",
@@ -9399,6 +9531,16 @@
         "stackback": "0.0.2"
       }
     },
+    "wmf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/wmf/-/wmf-1.0.2.tgz",
+      "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw=="
+    },
+    "word": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/word/-/word-0.3.0.tgz",
+      "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA=="
+    },
     "wrap-ansi": {
       "version": "8.1.0",
       "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
@@ -9475,6 +9617,20 @@
       "dev": true,
       "requires": {}
     },
+    "xlsx": {
+      "version": "0.18.5",
+      "resolved": "https://registry.npmmirror.com/xlsx/-/xlsx-0.18.5.tgz",
+      "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
+      "requires": {
+        "adler-32": "~1.3.0",
+        "cfb": "~1.2.1",
+        "codepage": "~1.15.0",
+        "crc-32": "~1.2.1",
+        "ssf": "~0.11.2",
+        "wmf": "~1.0.1",
+        "word": "~0.3.0"
+      }
+    },
     "xml-name-validator": {
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
diff --git a/package.json b/package.json
index c9aa419..afe157a 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
     "unplugin-vue-components": "^0.26.0",
     "vue": "^3.4.21",
     "vue-router": "^4.3.0",
+    "xlsx": "^0.18.5",
     "xml2json": "^0.12.0"
   },
   "devDependencies": {
diff --git a/src/components/chart/ProgressLineChart.vue b/src/components/chart/ProgressLineChart.vue
index 861af1e..482740d 100644
--- a/src/components/chart/ProgressLineChart.vue
+++ b/src/components/chart/ProgressLineChart.vue
@@ -128,7 +128,8 @@
     },
     // 淇敼鍥捐〃灞曠ず鐨勬姌绾垮浘绫诲瀷
     changeChartSeries() {
-      this.option.series = this.getShowSeries();
+      const { sIndex, eIndex, startPer, endPer } = this.getRange();
+      this.option.series = this.getShowSeries(sIndex, eIndex);
       this.lineChart.setOption(this.option, { notMerge: true });
     },
     changeChartRange() {
diff --git a/src/components/monitor/DataSummary.vue b/src/components/monitor/DataSummary.vue
index 39a61f0..250cdd7 100644
--- a/src/components/monitor/DataSummary.vue
+++ b/src/components/monitor/DataSummary.vue
@@ -26,7 +26,7 @@
             header-cell-class-name="t-header-cell"
           >
             <el-table-column prop="factor" label="鍥犲瓙" width="66" />
-            <el-table-column prop="avg" label="鍧囧��" width="66" />
+            <el-table-column prop="avg" label="鍧囧��" width="84" />
             <el-table-column prop="min" label="鏈�灏忓��" width="66" />
             <el-table-column prop="max" label="鏈�澶у��" width="66" />
           </el-table>
@@ -38,6 +38,7 @@
 <script>
 import { FactorDatas } from '@/model/FactorDatas';
 import { factorName } from '@/constant/factor-name';
+import { windDir } from '@/constant/wind-dir';
 
 export default {
   props: {
@@ -56,29 +57,40 @@
       for (const key in this.factorDatas.factor) {
         if (Object.hasOwnProperty.call(this.factorDatas.factor, key)) {
           const f = this.factorDatas.factor[key];
-          let min,
-            max,
-            total = 0,
-            count = 0;
-          f.datas.forEach((v) => {
-            if (!min || v.factorData < min) {
-              min = v.factorData;
-            }
-            if (!max || v.factorData > max) {
-              max = v.factorData;
-            }
-            total += v.factorData;
-            count++;
-          });
-          let _avg = count == 0 ? 0 : Math.round((total / count) * 100) / 100;
-          if (isNaN(_avg)) _avg = '-';
-          list.push({
-            factorId: f.factorId,
-            factor: factorName[f.factorName],
-            min,
-            max,
-            avg: _avg
-          });
+          if (f.factorName == 'WIND_DIRECTION') {
+            const avg = this.windDirAvg(f);
+            list.push({
+              factorId: f.factorId,
+              factor: factorName[f.factorName],
+              min: '-',
+              max: '-',
+              avg: `${avg}(${windDir(avg)})`
+            });
+          } else {
+            let min,
+              max,
+              total = 0,
+              count = 0;
+            f.datas.forEach((v) => {
+              if (!min || v.factorData < min) {
+                min = v.factorData;
+              }
+              if (!max || v.factorData > max) {
+                max = v.factorData;
+              }
+              total += v.factorData;
+              count++;
+            });
+            let _avg = count == 0 ? 0 : Math.round((total / count) * 100) / 100;
+            if (isNaN(_avg)) _avg = '-';
+            list.push({
+              factorId: f.factorId,
+              factor: factorName[f.factorName],
+              min,
+              max,
+              avg: _avg
+            });
+          }
         }
       }
       return list;
@@ -88,6 +100,39 @@
         return this.selectFactorType.includes(v.factorId);
       });
     }
+  },
+  methods: {
+    windDirAvg(factor) {
+      let u = 0, // 涓滆タ鏂瑰悜鍒嗛噺鎬诲拰
+        v = 0, // 鍗楀寳鏂瑰悜鍒嗛噺鎬诲拰
+        c = 0; // 椋庡悜鏁版嵁涓暟
+      factor.datas.forEach((value) => {
+        let r = (value.factorData / 180.0) * Math.PI;
+        u += Math.sin(r);
+        v += Math.cos(r);
+        c++;
+      });
+      if (c != 0) {
+        const avgU = u / c;
+        const avgV = v / c;
+        let a = Math.atan(avgU / avgV);
+        /**
+         * avgU>0;avgV>0: 鐪熷疄瑙掑害澶勪簬绗竴璞¢檺锛屼慨姝e�间负+0掳
+         * avgU>0;avgV<0: 鐪熷疄瑙掑害澶勪簬绗簩璞¢檺锛屼慨姝e�间负+180掳
+         * avgU<0;avgV<0: 鐪熷疄瑙掑害澶勪簬绗笁璞¢檺锛屼慨姝e�间负+180掳
+         * avgU<0;avgV>0: 鐪熷疄瑙掑害澶勪簬绗洓璞¢檺锛屼慨姝e�间负+360掳
+         */
+        a = (a * 180.0) / Math.PI;
+        if (avgV > 0) {
+          a += avgU > 0 ? 0 : 360;
+        } else {
+          a += 180;
+        }
+        return parseInt(a);
+      } else {
+        return 0;
+      }
+    }
   }
 };
 </script>
diff --git a/src/components/monitor/DataTable.vue b/src/components/monitor/DataTable.vue
index 217aeb9..b99e67a 100644
--- a/src/components/monitor/DataTable.vue
+++ b/src/components/monitor/DataTable.vue
@@ -1,3 +1,4 @@
+<!-- eslint-disable no-unused-vars -->
 <template>
   <BaseCard size="medium" direction="right">
     <template #content>
@@ -34,6 +35,7 @@
             v-if="selectFactorType.includes(item.value)"
             :prop="item.name"
             :label="item.label"
+            :formatter="factorFormatter"
             align="center"
             width="79"
             sortable="custom"
@@ -54,7 +56,18 @@
     </template>
 
     <template #footer>
-      <el-row justify="end">
+      <el-row justify="space-between" class="p-b-2">
+        <el-button
+          :loading="downloadLoading"
+          type="primary"
+          class="el-button-custom"
+          size="small"
+          @click="handleDownload"
+          :disabled="downloadLoading"
+          :icon="downloadLoading ? '' : 'download'"
+        >
+          瀵煎嚭鏁版嵁
+        </el-button>
         <el-text size="small" type="warning"
           >鍏� {{ tableData.length }} 鏉★紝{{ pageSize }}鏉�/椤�</el-text
         >
@@ -69,6 +82,7 @@
 import { checkboxOptions } from '@/constant/checkbox-options';
 import { TYPE0 } from '@/constant/device-type';
 import { windDir } from '@/constant/wind-dir';
+import fileUtil from '@/utils/file';
 
 export default {
   props: {
@@ -79,6 +93,7 @@
       // type0: 杞﹁浇鎴栨棤浜烘満; type1:鏃犱汉鑸�
       default: TYPE0
     },
+    deviceCode: String,
     selectFactorType: {
       type: Array,
       default: () => []
@@ -92,21 +107,39 @@
       total: 0,
       currentPage: 1,
       pageSize: 200,
-      rowHeight: undefined
+      rowHeight: undefined,
+      // tableData:[],
+      showData: [],
+      downloadLoading: false
     };
   },
   emits: ['tableClick'],
   watch: {
     locateIndex(nV, oV) {
       if (nV == oV) return;
-      this.$refs.tableRef.setCurrentRow(this.tableData[nV]);
+      const _index = this.tableData.findIndex((v) => v.index == nV);
+      this.$refs.tableRef.setCurrentRow(this.tableData[_index]);
       // 璁$畻鍒嗛〉
-      this.currentPage = parseInt(nV / this.pageSize) + 1;
+      this.currentPage = parseInt(_index / this.pageSize) + 1;
       // 璁$畻瀵瑰簲鍒嗛〉涓殑绱㈠紩
-      const index = nV % this.pageSize;
+      const index = _index % this.pageSize;
 
       const h = this.getRowHeight();
-      this.$refs.tableRef.setScrollTop(h * index - 350);
+      setTimeout(() => {
+        this.$refs.tableRef.setScrollTop(h * index - 350);
+      }, 200);
+    },
+    currentPage(nV, oV) {
+      if (nV == oV) return;
+      this.getShowData();
+    },
+    pageSize(nV, oV) {
+      if (nV == oV) return;
+      this.getShowData();
+    },
+    tableData(nV, oV) {
+      if (nV == oV) return;
+      this.getShowData();
     }
   },
   computed: {
@@ -118,9 +151,6 @@
           f.datas.forEach((v, i) => {
             const name = f.factorName;
             let value = v.factorData;
-            if (name == 'WIND_DIRECTION') {
-              value = windDir(value);
-            }
             if (list.length <= i) {
               list.push({
                 index: i,
@@ -134,16 +164,28 @@
       }
       return list;
     },
-    showData() {
-      const sIndex = (this.currentPage - 1) * this.pageSize;
-      const eIndex = sIndex + this.pageSize;
-      return this.tableData.slice(sIndex, eIndex);
-    },
+    // showData: {
+    //   get() {
+    //     // const sIndex = (this.currentPage - 1) * this.pageSize;
+    //     // const eIndex = sIndex + this.pageSize;
+    //     // return this.tableData.slice(sIndex, eIndex);
+    //     this.pageData = this.getShowData();
+    //     return this.pageData
+    //   },
+    //   set(newValue) {
+    //     this.pageData = newValue
+    //   }
+    // },
     tableColumn() {
       return checkboxOptions(this.deviceType);
     }
   },
   methods: {
+    getShowData() {
+      const sIndex = (this.currentPage - 1) * this.pageSize;
+      const eIndex = sIndex + this.pageSize;
+      this.showData = this.tableData.slice(sIndex, eIndex);
+    },
     // 鑾峰彇琛ㄦ牸绗竴琛岄珮搴�
     getRowHeight() {
       if (!this.rowHeight) {
@@ -160,6 +202,13 @@
     timeFormatter(row, col, cellValue, index) {
       return moment(cellValue).format('HH:mm:ss');
     },
+    factorFormatter(row, col, cellValue, index) {
+      if (col.property == 'WIND_DIRECTION') {
+        return windDir(cellValue);
+      } else {
+        return cellValue;
+      }
+    },
     handleRowClick(row, col, event) {
       this.$emit('tableClick', row.index);
       // console.log(row);
@@ -167,9 +216,45 @@
       // console.log(event.target.getBoundingClientRect().height);
     },
     handleSort({ column, prop, order }) {
-      console.log(column);
-      console.log(prop);
-      console.log(order);
+      // console.log(column);
+      // console.log(prop);
+      // console.log(order);
+      this.tableData.sort((a, b) => {
+        if (order == 'ascending') {
+          if (a[prop] != b[prop]) {
+            return a[prop] - b[prop];
+          } else {
+            return a.TIME - b.TIME;
+          }
+        } else if (order == 'descending') {
+          if (a[prop] != b[prop]) {
+            return b[prop] - a[prop];
+          } else {
+            return a.TIME - b.TIME;
+          }
+        } else {
+          return a.TIME - b.TIME;
+        }
+      });
+      this.getShowData();
+    },
+    handleDownload() {
+      this.downloadLoading = true;
+      setTimeout(() => {
+        this.downloadLoading = false;
+      }, 2000);
+      const excelData = this.tableData.map((v) => {
+        const res = {
+          缂栧彿: ++v.index,
+          鏃堕棿: moment(v.TIME).format('YYYY-MM-DD HH:mm:ss')
+        };
+        this.tableColumn.forEach((c) => {
+          res[c.label] = v[c.name];
+        });
+        return res;
+      });
+      fileUtil.exportToExcel(excelData, this.deviceCode, '璧拌埅鐩戞祴鏁版嵁.xlsx');
+      this.downloadLoading = false;
     }
   }
 };
diff --git a/src/constant/checkbox-options/options-jingan.js b/src/constant/checkbox-options/options-jingan.js
index 7d23581..f270d4d 100644
--- a/src/constant/checkbox-options/options-jingan.js
+++ b/src/constant/checkbox-options/options-jingan.js
@@ -42,10 +42,10 @@
     label: '椋庨��',
     name: 'WIND_SPEED',
     value: '16'
+  },
+  {
+    label: '椋庡悜',
+    name: 'WIND_DIRECTION',
+    value: '17'
   }
-  // {
-  //   label: '椋庡悜',
-  //   name: 'WIND_DIRECTION',
-  //   value: '17'
-  // }
 ];
diff --git a/src/model/Factor.js b/src/model/Factor.js
index 354a585..1aaa149 100644
--- a/src/model/Factor.js
+++ b/src/model/Factor.js
@@ -194,24 +194,49 @@
     if (d1 == undefined || d2 == undefined) {
       return;
     }
+    let diffValue = d2.factorData - d1.factorData;
+    // 瀵逛簬椋庡悜鐭㈤噺鏉ヨ锛屽姩鐢荤殑鍙樺寲搴旇浠庝袱涓鍚戝す瑙掕緝灏忕殑閭d竴渚ц繘琛屽彉鍖�
+    if (this.factorName == 'WIND_DIRECTION') {
+      // 椋庡悜瑙掑害宸�
+      if (diffValue > 180) {
+        diffValue -= 360;
+      } else if (diffValue < -180) {
+        diffValue += 360;
+      }
+    }
     // 鍗曞抚鏁版嵁鍊肩殑宸��
-    var dValue = {
-      factorData: (d2.factorData - d1.factorData) / count,
-      physicalQuantity: (d2.physicalQuantity - d2.physicalQuantity) / count
+    const dValue = {
+      factorData: diffValue / count
+      // physicalQuantity: (d2.physicalQuantity - d2.physicalQuantity) / count
+    };
+
+    // 椋庡悜鐭㈤噺淇
+    const correct = (v) => {
+      if (this.factorName == 'WIND_DIRECTION') {
+        if (v < 0) {
+          return 360 + v;
+        } else if (v > 360) {
+          return v - 360;
+        } else {
+          return v;
+        }
+      } else {
+        return v;
+      }
     };
     for (let i = 0; i < count - 1; i++) {
       var _data = {
-        factorData: d1.factorData + dValue.factorData * (i + 1),
+        factorData: correct(d1.factorData + dValue.factorData * (i + 1)),
         factorId: d1.factorId,
         factorName: d1.factorName,
-        physicalQuantity:
-          d1.physicalQuantity + dValue.physicalQuantity * (i + 1),
+        // physicalQuantity:
+        //   d1.physicalQuantity + dValue.physicalQuantity * (i + 1),
         sensorId: d1.sensorId,
         statusList: d1.statusList
       };
       if (!isDraw) {
         _data.factorData = -1;
-        _data.physicalQuantity = -1;
+        // _data.physicalQuantity = -1;
       }
       this.datas.push(_data);
     }
diff --git a/src/utils/file.js b/src/utils/file.js
new file mode 100644
index 0000000..61fcfa3
--- /dev/null
+++ b/src/utils/file.js
@@ -0,0 +1,18 @@
+import * as XLSX from 'xlsx/xlsx.mjs';
+
+export default {
+  exportToExcel(exportData, sheet = 'Sheet1', excelName = 'data.xlsx') {
+    // 鍒涘缓xlsx瀵硅薄
+    const xls = XLSX.utils.json_to_sheet(exportData);
+
+    // 缂栬緫琛ㄥご琛�       淇敼琛ㄥご
+    // excelColumnsName.forEach((item) => {
+    //   xls[item[0]].v = item[1]
+    // })
+    // 鍒涘缓workbook锛屽苟鎶妔heet娣诲姞杩涘幓
+    const wb = XLSX.utils.book_new();
+    XLSX.utils.book_append_sheet(wb, xls, sheet);
+    // 灏唚orkbook杞负浜岃繘鍒秞lsx鏂囦欢骞朵笅杞�
+    XLSX.writeFile(wb, excelName);
+  }
+};
diff --git a/src/utils/map/animation.js b/src/utils/map/animation.js
index 6ac8216..4180e7d 100644
--- a/src/utils/map/animation.js
+++ b/src/utils/map/animation.js
@@ -83,7 +83,7 @@
       if (i == endIndex || i == factorDatas.length() - 1) {
         break;
       }
-      // 鍔ㄧ敾杞ㄨ抗
+      // 鍔ㄧ敾杞ㄨ抗锛堝凡缁樺埗閮ㄥ垎锛�
       var animationData = factorDatas.getByIndex(0, i + 1);
 
       // 璺緞鐐�
@@ -105,14 +105,14 @@
       var d = distance / count;
       // 姣忎釜fps瀵瑰簲鐨勫疄闄呮椂闀�(榛樿1绉�)
       var t = 1;
-      // 涓ょ偣闂翠笉杩炵画鏃�
+      // 涓ょ偣闂翠笉杩炵画鏃讹紝浣跨敤榛樿鏃堕暱锛岄伩鍏�
       if (distance > this.maxD) {
-        count = 4 * this._fps;
+        count = this.frameAnimation.taskPeriod * this._fps;
         d = distance / count;
         t = duration / (count / this._fps);
       }
 
-      // 鐩戞祴鏁版嵁
+      // 鐩戞祴鏁版嵁锛堝緟缁樺埗鏁版嵁鐐癸紝鍦ㄥ凡缁樺埗閮ㄥ垎鍜岃鏁版嵁鐐逛箣闂达紝鎻掑叆鍔ㄧ敾甯ф暟鎹偣锛�
       // var fData1 = factorDatas.getByIndex(i, i + 1)
       var fData2 = factorDatas.getByIndex(i + 1, i + 2);
 
@@ -135,7 +135,7 @@
         }
         animationData.times.push(time);
       }
-      // factor
+      // 缁欐瘡涓洃娴嬪洜瀛愯繘琛屾彃甯�
       for (const key in animationData.factor) {
         var factor = animationData.factor[key];
         factor.insertFrame(fData2.factor[key], count, distance <= this.maxD);
diff --git a/src/utils/map/dialog.js b/src/utils/map/dialog.js
index 713af62..5c1ada9 100644
--- a/src/utils/map/dialog.js
+++ b/src/utils/map/dialog.js
@@ -3,6 +3,7 @@
 import { factorUnit } from '@/constant/factor-unit';
 import { windDir } from '@/constant/wind-dir';
 import { map } from './index_old';
+import { checkboxOptions } from '@/constant/checkbox-options';
 
 export const DialogUtil = {
   show: true,
@@ -21,8 +22,9 @@
    * @param {*} onClose 鍏抽棴寮瑰嚭妗嗗洖璋�
    * @returns
    */
-  createInfoWindow(deviceCode, factorDatas, i, onClose) {
+  createInfoWindow(deviceType, deviceCode, factorDatas, i, onClose) {
     let m = {
+      deviceType: deviceType,
       deviceCode: deviceCode,
       data: factorDatas,
       index: i,
@@ -40,22 +42,6 @@
     return m.window;
   },
 
-  createInfoWindow2(factorData, onClose) {
-    let m = {
-      time: factorData.time,
-      factorList: factorData.values,
-      window: '',
-      close: onClose
-    };
-    // eslint-disable-next-line no-undef
-    m.window = new AMap.InfoWindow({
-      isCustom: true, //浣跨敤鑷畾涔夌獥浣�
-      content: this.createWindowContent2(m),
-      // eslint-disable-next-line no-undef
-      offset: new AMap.Pixel(16, -45)
-    });
-    return m.window;
-  },
   /**
    * 绔欑偣鏍囪淇℃伅绐椾綋
    */
@@ -74,6 +60,7 @@
   },
 
   createWindowContent2(marker) {
+    const factorTypes = checkboxOptions(marker.deviceType);
     const time = marker.time;
     const factorList = marker.factorList;
     //瀹炰緥鍖栦俊鎭獥浣�
@@ -89,14 +76,17 @@
     var _contents = new Map();
     factorList.forEach((f) => {
       // 鍒犻�変笉鏄剧ず鐨勫洜瀛�
-      if (
-        f.factorName == 'NOI' ||
-        f.factorName == 'LNG' ||
-        f.factorName == 'LAT' ||
-        f.factorName == 'VELOCITY' ||
-        f.factorName == 'TIME' ||
-        f.factorName == 'HEIGHT'
-      ) {
+      // if (
+      //   f.factorName == 'NOI' ||
+      //   f.factorName == 'LNG' ||
+      //   f.factorName == 'LAT' ||
+      //   f.factorName == 'VELOCITY' ||
+      //   f.factorName == 'TIME' ||
+      //   f.factorName == 'HEIGHT'
+      // ) {
+      //   return;
+      // }
+      if (!factorTypes.find((v) => v.name == f.factorName)) {
         return;
       }
 
@@ -253,15 +243,15 @@
     return info;
   },
 
-  openNewWindow(deviceCode, factorDatas, i, onClose) {
+  openNewWindow(deviceType, deviceCode, factorDatas, i, onClose) {
     if (!this.show) return;
-    const window = this.createInfoWindow(deviceCode, factorDatas, i, onClose);
+    const window = this.createInfoWindow(
+      deviceType,
+      deviceCode,
+      factorDatas,
+      i,
+      onClose
+    );
     window.open(map, factorDatas.lnglats_GD[i]);
-  },
-
-  openNewWindow2(factorData, position, onClose) {
-    if (!this.show) return;
-    const window = this.createInfoWindow2(factorData, onClose);
-    window.open(map, position);
   }
 };
diff --git a/src/views/historymode/HistoryMode.vue b/src/views/historymode/HistoryMode.vue
index d75c5b2..cbf22c8 100644
--- a/src/views/historymode/HistoryMode.vue
+++ b/src/views/historymode/HistoryMode.vue
@@ -42,6 +42,7 @@
       @table-click="handelIndexChange"
       :factor-datas="factorDatas"
       :device-type="deviceType"
+      :device-code="deviceCode"
     ></DataSheet>
   </div>
 </template>
@@ -152,10 +153,16 @@
       mapUtil.setCenter(pr.p);
       // mapUtil.setFitSector(pr);
       // 2. 缁樺埗瀵硅瘽妗�
-      DialogUtil.openNewWindow(this.deviceCode, this.factorDatas, index, () => {
-        // 绉婚櫎鎵囧舰鍖哄煙
-        sector.clearSector();
-      });
+      DialogUtil.openNewWindow(
+        this.deviceType,
+        this.deviceCode,
+        this.factorDatas,
+        index,
+        () => {
+          // 绉婚櫎鎵囧舰鍖哄煙
+          sector.clearSector();
+        }
+      );
     },
     onFetchData(deviceType, data) {
       // todo 鏍规嵁璁惧绫诲瀷鍒囨崲鍦板浘鐩戞祴鍥犲瓙灞曠ず鍗曢�夋銆佹姌绾垮浘澶嶉�夋銆佹暟鎹〃鏍煎閫夋鐨勫洜瀛愮被鍨�
diff --git a/src/views/historymode/component/DataSheet.vue b/src/views/historymode/component/DataSheet.vue
index 778d322..8caa27a 100644
--- a/src/views/historymode/component/DataSheet.vue
+++ b/src/views/historymode/component/DataSheet.vue
@@ -24,6 +24,7 @@
           :select-factor-type="selectFactorType"
           :factor-datas="factorDatas"
           :device-type="deviceType"
+          :device-code="deviceCode"
           :locate-index="locateIndex"
           @table-click="handleTableClick"
         ></DataTable>
@@ -58,6 +59,7 @@
       // type0: 杞﹁浇鎴栨棤浜烘満; type1:鏃犱汉鑸�
       default: TYPE0
     },
+    deviceCode: String,
     // 褰撳墠閫変腑楂樹寒鐨勬暟鎹偣绱㈠紩
     locateIndex: Number
   },

--
Gitblit v1.9.3