1. 优化3D动画中风向的变化逻辑;
2. 修复折线图切换因子时,数据直接跳转至起始处的问题;
3. 折线图和表格加回风向因子;
4. 优化风向的均值计算为矢量计算,同时最大最小值不显示;
5. 新增表格数据导出功能;
已修改11个文件
已添加1个文件
522 ■■■■ 文件已修改
package-lock.json 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/chart/ProgressLineChart.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/monitor/DataSummary.vue 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/monitor/DataTable.vue 119 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/constant/checkbox-options/options-jingan.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/model/Factor.js 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/file.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/map/animation.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/map/dialog.js 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/historymode/HistoryMode.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/historymode/component/DataSheet.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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",
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": {
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() {
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: çœŸå®žè§’度处于第一象限,修正值为+0°
         * avgU>0;avgV<0: çœŸå®žè§’度处于第二象限,修正值为+180°
         * avgU<0;avgV<0: çœŸå®žè§’度处于第三象限,修正值为+180°
         * avgU<0;avgV>0: çœŸå®žè§’度处于第四象限,修正值为+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>
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;
    }
  }
};
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'
  // }
];
src/model/Factor.js
@@ -194,24 +194,49 @@
    if (d1 == undefined || d2 == undefined) {
      return;
    }
    let diffValue = d2.factorData - d1.factorData;
    // å¯¹äºŽé£Žå‘矢量来说,动画的变化应该从两个风向夹角较小的那一侧进行变化
    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);
    }
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,并把sheet添加进去
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, xls, sheet);
    // å°†workbook转为二进制xlsx文件并下载
    XLSX.writeFile(wb, excelName);
  }
};
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);
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);
  }
};
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 æ ¹æ®è®¾å¤‡ç±»åž‹åˆ‡æ¢åœ°å›¾ç›‘测因子展示单选框、折线图复选框、数据表格复选框的因子类型
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
  },