Browse Source

Merge branch 'main' of http://124.70.43.205:3000/xufenqi/PowerAnalysis into main

chenminghua 2 years ago
parent
commit
679f6a82f6
43 changed files with 4632 additions and 503 deletions
  1. 33 29
      components.d.ts
  2. BIN
      node_modules.rar
  3. 303 80
      package-lock.json
  4. 1 1
      package.json
  5. 2 2
      src/api/config.js
  6. 1 1
      src/assets/css/main.css
  7. 6 4
      src/components/Header.vue
  8. 5 3
      src/components/Sidebar.vue
  9. 1 1
      src/components/SubmitBtn.vue
  10. 1 1
      src/components/tree.vue
  11. 1 1
      src/main.js
  12. 398 0
      src/pages/dataAnalysis/agcAnalysis/components/configStation.json
  13. 0 0
      src/pages/dataAnalysis/agcAnalysis/components/current-scatter-chart.json
  14. 344 0
      src/pages/dataAnalysis/agcAnalysis/components/current-scatter-chart.vue
  15. 75 0
      src/pages/dataAnalysis/agcAnalysis/components/search.vue
  16. 53 0
      src/pages/dataAnalysis/agcAnalysis/components/table.vue
  17. 177 0
      src/pages/dataAnalysis/agcAnalysis/index.vue
  18. 10 8
      src/pages/dataAnalysis/combine/components/chartTheme.json
  19. 10 2
      src/pages/dataAnalysis/combine/components/current-scatter-chart.vue
  20. 26 29
      src/pages/dataAnalysis/combine/index.vue
  21. 397 0
      src/pages/dataAnalysis/lineAnalysis/components/barChart.json
  22. 184 0
      src/pages/dataAnalysis/lineAnalysis/components/barChart.vue
  23. 10 8
      src/pages/dataAnalysis/lineAnalysis/components/chartTheme.json
  24. 10 2
      src/pages/dataAnalysis/lineAnalysis/components/current-scatter-chart.vue
  25. 132 85
      src/pages/dataAnalysis/lineAnalysis/index.vue
  26. 47 30
      src/pages/dataAnalysis/rateAnalysis/components/chart.vue
  27. 17 11
      src/pages/dataAnalysis/rateAnalysis/components/lineChart.vue
  28. 29 23
      src/pages/dataAnalysis/rateAnalysis/components/scatterSingleChart.vue
  29. 137 95
      src/pages/dataAnalysis/rateAnalysis/index.vue
  30. 393 0
      src/pages/dataAnalysis/rateAnalysis/rateAnalysis.json
  31. 397 0
      src/pages/dataAnalysis/tempAnalysis/components/barChart.json
  32. 184 0
      src/pages/dataAnalysis/tempAnalysis/components/barChart.vue
  33. 185 0
      src/pages/dataAnalysis/tempAnalysis/components/current-scatter-chart.vue
  34. 185 0
      src/pages/dataAnalysis/tempAnalysis/components/lineChart.vue
  35. 29 0
      src/pages/dataAnalysis/tempAnalysis/components/search.vue
  36. 594 0
      src/pages/dataAnalysis/tempAnalysis/index.vue
  37. 2 2
      src/pages/dataAnalysis/rateAnalysis/chartTheme.json
  38. 14 3
      src/pages/dataFilter/prepare/components/search.vue
  39. 22 18
      src/pages/dataFilter/prepare/index.vue
  40. 22 18
      src/pages/dataFilter/process/index.vue
  41. 25 1
      src/router/index.js
  42. 53 1
      src/tools/htmlToPdf.js
  43. 117 44
      yarn.lock

+ 33 - 29
components.d.ts

@@ -22,35 +22,36 @@ declare module '@vue/runtime-core' {
     DoubleLineChart: typeof import('./src/components/chart/line/double-line-chart.vue')['default']
     DoubleLineChartold: typeof import('./src/components/chart/line/double-line-chartold.vue')['default']
     DualPieChart: typeof import('./src/components/chart/pie/dual-pie-chart.vue')['default']
-    ElButton: typeof import('element-plus/es/el-button')['default']
-    ElCheckbox: typeof import('element-plus/es/el-checkbox')['default']
-    ElCheckboxGroup: typeof import('element-plus/es/el-checkbox-group')['default']
-    ElCol: typeof import('element-plus/es/el-col')['default']
-    ElDatePicker: typeof import('element-plus/es/el-date-picker')['default']
-    ElDialog: typeof import('element-plus/es/el-dialog')['default']
-    ElDropdown: typeof import('element-plus/es/el-dropdown')['default']
-    ElDropdownItem: typeof import('element-plus/es/el-dropdown-item')['default']
-    ElDropdownMenu: typeof import('element-plus/es/el-dropdown-menu')['default']
-    ElEmpty: typeof import('element-plus/es/el-empty')['default']
-    ElForm: typeof import('element-plus/es/el-form')['default']
-    ElFormItem: typeof import('element-plus/es/el-form-item')['default']
-    ElIcon: typeof import('element-plus/es/el-icon')['default']
-    ElInput: typeof import('element-plus/es/el-input')['default']
-    ElInputNumber: typeof import('element-plus/es/el-input-number')['default']
-    ElMenu: typeof import('element-plus/es/el-menu')['default']
-    ElMenuItem: typeof import('element-plus/es/el-menu-item')['default']
-    ElOption: typeof import('element-plus/es/el-option')['default']
-    ElProgress: typeof import('element-plus/es/el-progress')['default']
-    ElRadio: typeof import('element-plus/es/el-radio')['default']
-    ElRadioGroup: typeof import('element-plus/es/el-radio-group')['default']
-    ElRow: typeof import('element-plus/es/el-row')['default']
-    ElSelect: typeof import('element-plus/es/el-select')['default']
-    ElSubmenu: typeof import('element-plus/es/el-submenu')['default']
-    ElTable: typeof import('element-plus/es/el-table')['default']
-    ElTableColumn: typeof import('element-plus/es/el-table-column')['default']
-    ElTabPane: typeof import('element-plus/es/el-tab-pane')['default']
-    ElTabs: typeof import('element-plus/es/el-tabs')['default']
-    ElTree: typeof import('element-plus/es/el-tree')['default']
+    ElButton: typeof import('element-plus/es')['ElButton']
+    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
+    ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
+    ElCol: typeof import('element-plus/es')['ElCol']
+    ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
+    ElDialog: typeof import('element-plus/es')['ElDialog']
+    ElDropdown: typeof import('element-plus/es')['ElDropdown']
+    ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
+    ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
+    ElEmpty: typeof import('element-plus/es')['ElEmpty']
+    ElForm: typeof import('element-plus/es')['ElForm']
+    ElFormItem: typeof import('element-plus/es')['ElFormItem']
+    ElIcon: typeof import('element-plus/es')['ElIcon']
+    ElInput: typeof import('element-plus/es')['ElInput']
+    ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
+    ElMenu: typeof import('element-plus/es')['ElMenu']
+    ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
+    ElOption: typeof import('element-plus/es')['ElOption']
+    ElProgress: typeof import('element-plus/es')['ElProgress']
+    ElRadio: typeof import('element-plus/es')['ElRadio']
+    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
+    ElRow: typeof import('element-plus/es')['ElRow']
+    ElSelect: typeof import('element-plus/es')['ElSelect']
+    ElSubmenu: typeof import('element-plus/es')['ElSubmenu']
+    ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
+    ElTable: typeof import('element-plus/es')['ElTable']
+    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
+    ElTabPane: typeof import('element-plus/es')['ElTabPane']
+    ElTabs: typeof import('element-plus/es')['ElTabs']
+    ElTree: typeof import('element-plus/es')['ElTree']
     Excel: typeof import('./src/components/excel.vue')['default']
     Header: typeof import('./src/components/Header.vue')['default']
     HealthBarLineChart: typeof import('./src/components/chart/combination/health-bar-line-chart.vue')['default']
@@ -99,4 +100,7 @@ declare module '@vue/runtime-core' {
     WeatherLineChart: typeof import('./src/components/chart/line/weather-line-chart.vue')['default']
     ZoomLineChart: typeof import('./src/components/chart/line/zoom-line-chart.vue')['default']
   }
+  export interface ComponentCustomProperties {
+    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
+  }
 }

BIN
node_modules.rar


+ 303 - 80
package-lock.json

@@ -17,7 +17,7 @@
         "dayjs": "^1.10.7",
         "default-passive-events": "^2.0.0",
         "echarts": "^5.2.2",
-        "element-plus": "^1.0.2-beta.71",
+        "element-plus": "^2.2.26",
         "file-saver": "^2.0.5",
         "html2canvas": "^1.0.0-rc.7",
         "jsencrypt": "^3.2.1",
@@ -103,11 +103,13 @@
         "to-fast-properties": "^2.0.0"
       }
     },
-    "node_modules/@element-plus/icons": {
-      "version": "0.0.11",
-      "resolved": "https://registry.npmjs.org/@element-plus/icons/-/icons-0.0.11.tgz",
-      "integrity": "sha512-iKQXSxXu131Ai+I9Ymtcof9WId7kaXvB1+WRfAfpQCW7UiAMYgdNDqb/u0hgTo2Yq3MwC4MWJnNuTBEpG8r7+A==",
-      "deprecated": "Please use @element-plus/icons-vue instead."
+    "node_modules/@ctrl/tinycolor": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.5.0.tgz",
+      "integrity": "sha512-tlJpwF40DEQcfR/QF+wNMVyGMaO9FQp6Z1Wahj4Gk3CJQYHwA2xVG7iKDFdW6zuxZY9XWOpGcfNCTsX4McOsOg==",
+      "engines": {
+        "node": ">=10"
+      }
     },
     "node_modules/@element-plus/icons-vue": {
       "version": "2.0.10",
@@ -165,6 +167,19 @@
         "url": "https://opencollective.com/eslint"
       }
     },
+    "node_modules/@floating-ui/core": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.0.3.tgz",
+      "integrity": "sha512-27FDAEVHrAEQI1UV+7FIjZrFK862gBoAG0USoPMU7RoBCmaTDt6bnKVW/J2uPnOPI6TWqiWGtS7RFN+tN/k+vQ=="
+    },
+    "node_modules/@floating-ui/dom": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.8.tgz",
+      "integrity": "sha512-uUm1xYQ0xdmFLhtetKgjK9AtF4INwDVwuJZvpK19ENHg1wYn7T0w9phYyCL5+HEpgJtX4ZYG6HJkDbtd2yP6cg==",
+      "dependencies": {
+        "@floating-ui/core": "^1.0.3"
+      }
+    },
     "node_modules/@hapi/hoek": {
       "version": "9.3.0",
       "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
@@ -279,10 +294,10 @@
       }
     },
     "node_modules/@popperjs/core": {
-      "version": "2.9.2",
-      "resolved": "https://registry.npm.taobao.org/@popperjs/core/download/@popperjs/core-2.9.2.tgz?cache=0&sync_timestamp=1617290098226&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40popperjs%2Fcore%2Fdownload%2F%40popperjs%2Fcore-2.9.2.tgz",
-      "integrity": "sha1-rep7aVPLs0ZRdmsFSEaOdDxqI1M=",
-      "license": "MIT",
+      "name": "@sxzz/popperjs-es",
+      "version": "2.11.7",
+      "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
+      "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==",
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/popperjs"
@@ -362,6 +377,19 @@
       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
       "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
     },
+    "node_modules/@types/lodash": {
+      "version": "4.14.191",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
+      "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ=="
+    },
+    "node_modules/@types/lodash-es": {
+      "version": "4.17.6",
+      "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.6.tgz",
+      "integrity": "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==",
+      "dependencies": {
+        "@types/lodash": "*"
+      }
+    },
     "node_modules/@types/mini-css-extract-plugin": {
       "version": "0.9.1",
       "resolved": "https://registry.nlark.com/@types/mini-css-extract-plugin/download/@types/mini-css-extract-plugin-0.9.1.tgz?cache=0&sync_timestamp=1621241867700&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fmini-css-extract-plugin%2Fdownload%2F%40types%2Fmini-css-extract-plugin-0.9.1.tgz",
@@ -383,6 +411,11 @@
       "integrity": "sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==",
       "optional": true
     },
+    "node_modules/@types/web-bluetooth": {
+      "version": "0.0.16",
+      "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
+      "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
+    },
     "node_modules/@types/webpack": {
       "version": "5.28.0",
       "resolved": "https://registry.nlark.com/@types/webpack/download/@types/webpack-5.28.0.tgz?cache=0&sync_timestamp=1621533733988&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fwebpack%2Fdownload%2F%40types%2Fwebpack-5.28.0.tgz",
@@ -772,6 +805,89 @@
       "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.39.tgz",
       "integrity": "sha512-D3dl2ZB9qE6mTuWPk9RlhDeP1dgNRUKC3NJxji74A4yL8M2MwlhLKUC/49WHjrNzSPug58fWx/yFbaTzGAQSBw=="
     },
+    "node_modules/@vueuse/core": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.6.0.tgz",
+      "integrity": "sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==",
+      "dependencies": {
+        "@types/web-bluetooth": "^0.0.16",
+        "@vueuse/metadata": "9.6.0",
+        "@vueuse/shared": "9.6.0",
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@vueuse/core/node_modules/vue-demi": {
+      "version": "0.13.11",
+      "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
+      "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
+      "hasInstallScript": true,
+      "bin": {
+        "vue-demi-fix": "bin/vue-demi-fix.js",
+        "vue-demi-switch": "bin/vue-demi-switch.js"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0-rc.1",
+        "vue": "^3.0.0-0 || ^2.6.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vueuse/metadata": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.6.0.tgz",
+      "integrity": "sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w==",
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@vueuse/shared": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.6.0.tgz",
+      "integrity": "sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==",
+      "dependencies": {
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@vueuse/shared/node_modules/vue-demi": {
+      "version": "0.13.11",
+      "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
+      "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
+      "hasInstallScript": true,
+      "bin": {
+        "vue-demi-fix": "bin/vue-demi-fix.js",
+        "vue-demi-switch": "bin/vue-demi-switch.js"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0-rc.1",
+        "vue": "^3.0.0-0 || ^2.6.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@webassemblyjs/ast": {
       "version": "1.11.0",
       "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.11.0.tgz",
@@ -1142,10 +1258,9 @@
       }
     },
     "node_modules/async-validator": {
-      "version": "3.5.2",
-      "resolved": "https://registry.nlark.com/async-validator/download/async-validator-3.5.2.tgz",
-      "integrity": "sha1-aOhmqWgk6LJpT/eoMcGiXETV5QA=",
-      "license": "MIT"
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
+      "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
     },
     "node_modules/asynckit": {
       "version": "0.4.0",
@@ -1863,21 +1978,28 @@
       "license": "ISC"
     },
     "node_modules/element-plus": {
-      "version": "1.0.2-beta.71",
-      "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-1.0.2-beta.71.tgz",
-      "integrity": "sha512-tlfbRORIav8gJcIpjZI5F6aJIVHIaDuGO6/vKu43lgYq4JS2JPNRTjvrSE2p4f5xLfaFNfOWjCS3sybXLfMg8g==",
-      "dependencies": {
-        "@element-plus/icons": "^0.0.11",
-        "@popperjs/core": "^2.4.4",
-        "async-validator": "^3.4.0",
-        "dayjs": "1.x",
-        "lodash": "^4.17.20",
-        "mitt": "^2.1.0",
-        "normalize-wheel": "^1.0.1",
-        "resize-observer-polyfill": "^1.5.1"
+      "version": "2.2.26",
+      "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.2.26.tgz",
+      "integrity": "sha512-O/rdY5m9DkclpVg8r3GynyqCunm7MxSR142xSsjrZA77bi7bcwA3SIy6SPEDqHi5R4KqgkGYgKSp4Q4e3irbYg==",
+      "dependencies": {
+        "@ctrl/tinycolor": "^3.4.1",
+        "@element-plus/icons-vue": "^2.0.6",
+        "@floating-ui/dom": "^1.0.1",
+        "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
+        "@types/lodash": "^4.14.182",
+        "@types/lodash-es": "^4.17.6",
+        "@vueuse/core": "^9.1.0",
+        "async-validator": "^4.2.5",
+        "dayjs": "^1.11.3",
+        "escape-html": "^1.0.3",
+        "lodash": "^4.17.21",
+        "lodash-es": "^4.17.21",
+        "lodash-unified": "^1.0.2",
+        "memoize-one": "^6.0.0",
+        "normalize-wheel-es": "^1.2.0"
       },
       "peerDependencies": {
-        "vue": "3.1.x"
+        "vue": "^3.2.0"
       }
     },
     "node_modules/emmet": {
@@ -1988,6 +2110,11 @@
         "node": ">=6"
       }
     },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+    },
     "node_modules/escape-string-regexp": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@@ -3334,6 +3461,21 @@
       "integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=",
       "license": "MIT"
     },
+    "node_modules/lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+    },
+    "node_modules/lodash-unified": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
+      "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
+      "peerDependencies": {
+        "@types/lodash-es": "*",
+        "lodash": "*",
+        "lodash-es": "*"
+      }
+    },
     "node_modules/lodash.merge": {
       "version": "4.6.2",
       "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -3360,6 +3502,11 @@
         "sourcemap-codec": "^1.4.4"
       }
     },
+    "node_modules/memoize-one": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+      "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+    },
     "node_modules/merge-source-map": {
       "version": "1.1.0",
       "resolved": "https://registry.npm.taobao.org/merge-source-map/download/merge-source-map-1.1.0.tgz",
@@ -3437,12 +3584,6 @@
       "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=",
       "license": "MIT"
     },
-    "node_modules/mitt": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npm.taobao.org/mitt/download/mitt-2.1.0.tgz",
-      "integrity": "sha1-90BXfCMXbGIFsSGylzUU6t4bIjA=",
-      "license": "MIT"
-    },
     "node_modules/moment": {
       "version": "2.29.4",
       "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
@@ -3527,11 +3668,10 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/normalize-wheel": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/normalize-wheel/download/normalize-wheel-1.0.1.tgz",
-      "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU=",
-      "license": "BSD-3-Clause"
+    "node_modules/normalize-wheel-es": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
+      "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
     },
     "node_modules/nwmatcher": {
       "version": "1.4.4",
@@ -4072,12 +4212,6 @@
       "integrity": "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==",
       "dev": true
     },
-    "node_modules/resize-observer-polyfill": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npm.taobao.org/resize-observer-polyfill/download/resize-observer-polyfill-1.5.1.tgz",
-      "integrity": "sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ=",
-      "license": "MIT"
-    },
     "node_modules/resolve": {
       "version": "1.22.1",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
@@ -5738,10 +5872,10 @@
         "to-fast-properties": "^2.0.0"
       }
     },
-    "@element-plus/icons": {
-      "version": "0.0.11",
-      "resolved": "https://registry.npmjs.org/@element-plus/icons/-/icons-0.0.11.tgz",
-      "integrity": "sha512-iKQXSxXu131Ai+I9Ymtcof9WId7kaXvB1+WRfAfpQCW7UiAMYgdNDqb/u0hgTo2Yq3MwC4MWJnNuTBEpG8r7+A=="
+    "@ctrl/tinycolor": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.5.0.tgz",
+      "integrity": "sha512-tlJpwF40DEQcfR/QF+wNMVyGMaO9FQp6Z1Wahj4Gk3CJQYHwA2xVG7iKDFdW6zuxZY9XWOpGcfNCTsX4McOsOg=="
     },
     "@element-plus/icons-vue": {
       "version": "2.0.10",
@@ -5791,6 +5925,19 @@
         "strip-json-comments": "^3.1.1"
       }
     },
+    "@floating-ui/core": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.0.3.tgz",
+      "integrity": "sha512-27FDAEVHrAEQI1UV+7FIjZrFK862gBoAG0USoPMU7RoBCmaTDt6bnKVW/J2uPnOPI6TWqiWGtS7RFN+tN/k+vQ=="
+    },
+    "@floating-ui/dom": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.8.tgz",
+      "integrity": "sha512-uUm1xYQ0xdmFLhtetKgjK9AtF4INwDVwuJZvpK19ENHg1wYn7T0w9phYyCL5+HEpgJtX4ZYG6HJkDbtd2yP6cg==",
+      "requires": {
+        "@floating-ui/core": "^1.0.3"
+      }
+    },
     "@hapi/hoek": {
       "version": "9.3.0",
       "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
@@ -5882,9 +6029,9 @@
       }
     },
     "@popperjs/core": {
-      "version": "2.9.2",
-      "resolved": "https://registry.npm.taobao.org/@popperjs/core/download/@popperjs/core-2.9.2.tgz?cache=0&sync_timestamp=1617290098226&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40popperjs%2Fcore%2Fdownload%2F%40popperjs%2Fcore-2.9.2.tgz",
-      "integrity": "sha1-rep7aVPLs0ZRdmsFSEaOdDxqI1M="
+      "version": "npm:@sxzz/popperjs-es@2.11.7",
+      "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
+      "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
     },
     "@rollup/pluginutils": {
       "version": "4.1.0",
@@ -5950,6 +6097,19 @@
       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
       "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
     },
+    "@types/lodash": {
+      "version": "4.14.191",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
+      "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ=="
+    },
+    "@types/lodash-es": {
+      "version": "4.17.6",
+      "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.6.tgz",
+      "integrity": "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==",
+      "requires": {
+        "@types/lodash": "*"
+      }
+    },
     "@types/mini-css-extract-plugin": {
       "version": "0.9.1",
       "resolved": "https://registry.nlark.com/@types/mini-css-extract-plugin/download/@types/mini-css-extract-plugin-0.9.1.tgz?cache=0&sync_timestamp=1621241867700&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fmini-css-extract-plugin%2Fdownload%2F%40types%2Fmini-css-extract-plugin-0.9.1.tgz",
@@ -5969,6 +6129,11 @@
       "integrity": "sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==",
       "optional": true
     },
+    "@types/web-bluetooth": {
+      "version": "0.0.16",
+      "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
+      "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
+    },
     "@types/webpack": {
       "version": "5.28.0",
       "resolved": "https://registry.nlark.com/@types/webpack/download/@types/webpack-5.28.0.tgz?cache=0&sync_timestamp=1621533733988&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fwebpack%2Fdownload%2F%40types%2Fwebpack-5.28.0.tgz",
@@ -6259,6 +6424,46 @@
       "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.39.tgz",
       "integrity": "sha512-D3dl2ZB9qE6mTuWPk9RlhDeP1dgNRUKC3NJxji74A4yL8M2MwlhLKUC/49WHjrNzSPug58fWx/yFbaTzGAQSBw=="
     },
+    "@vueuse/core": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.6.0.tgz",
+      "integrity": "sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==",
+      "requires": {
+        "@types/web-bluetooth": "^0.0.16",
+        "@vueuse/metadata": "9.6.0",
+        "@vueuse/shared": "9.6.0",
+        "vue-demi": "*"
+      },
+      "dependencies": {
+        "vue-demi": {
+          "version": "0.13.11",
+          "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
+          "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
+          "requires": {}
+        }
+      }
+    },
+    "@vueuse/metadata": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.6.0.tgz",
+      "integrity": "sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w=="
+    },
+    "@vueuse/shared": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.6.0.tgz",
+      "integrity": "sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==",
+      "requires": {
+        "vue-demi": "*"
+      },
+      "dependencies": {
+        "vue-demi": {
+          "version": "0.13.11",
+          "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
+          "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
+          "requires": {}
+        }
+      }
+    },
     "@webassemblyjs/ast": {
       "version": "1.11.0",
       "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.11.0.tgz",
@@ -6562,9 +6767,9 @@
       "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="
     },
     "async-validator": {
-      "version": "3.5.2",
-      "resolved": "https://registry.nlark.com/async-validator/download/async-validator-3.5.2.tgz",
-      "integrity": "sha1-aOhmqWgk6LJpT/eoMcGiXETV5QA="
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
+      "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
     },
     "asynckit": {
       "version": "0.4.0",
@@ -7122,18 +7327,25 @@
       "integrity": "sha1-8HdWqpLKvVpu7G9JFSWmT+YvmLk="
     },
     "element-plus": {
-      "version": "1.0.2-beta.71",
-      "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-1.0.2-beta.71.tgz",
-      "integrity": "sha512-tlfbRORIav8gJcIpjZI5F6aJIVHIaDuGO6/vKu43lgYq4JS2JPNRTjvrSE2p4f5xLfaFNfOWjCS3sybXLfMg8g==",
-      "requires": {
-        "@element-plus/icons": "^0.0.11",
-        "@popperjs/core": "^2.4.4",
-        "async-validator": "^3.4.0",
-        "dayjs": "1.x",
-        "lodash": "^4.17.20",
-        "mitt": "^2.1.0",
-        "normalize-wheel": "^1.0.1",
-        "resize-observer-polyfill": "^1.5.1"
+      "version": "2.2.26",
+      "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.2.26.tgz",
+      "integrity": "sha512-O/rdY5m9DkclpVg8r3GynyqCunm7MxSR142xSsjrZA77bi7bcwA3SIy6SPEDqHi5R4KqgkGYgKSp4Q4e3irbYg==",
+      "requires": {
+        "@ctrl/tinycolor": "^3.4.1",
+        "@element-plus/icons-vue": "^2.0.6",
+        "@floating-ui/dom": "^1.0.1",
+        "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
+        "@types/lodash": "^4.14.182",
+        "@types/lodash-es": "^4.17.6",
+        "@vueuse/core": "^9.1.0",
+        "async-validator": "^4.2.5",
+        "dayjs": "^1.11.3",
+        "escape-html": "^1.0.3",
+        "lodash": "^4.17.21",
+        "lodash-es": "^4.17.21",
+        "lodash-unified": "^1.0.2",
+        "memoize-one": "^6.0.0",
+        "normalize-wheel-es": "^1.2.0"
       }
     },
     "emmet": {
@@ -7219,6 +7431,11 @@
       "resolved": "https://registry.nlark.com/escalade/download/escalade-3.1.1.tgz",
       "integrity": "sha1-2M/ccACWXFoBdLSoLqpcBVJ0LkA="
     },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+    },
     "escape-string-regexp": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@@ -8247,6 +8464,17 @@
       "resolved": "https://registry.nlark.com/lodash/download/lodash-4.17.21.tgz",
       "integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw="
     },
+    "lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+    },
+    "lodash-unified": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
+      "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
+      "requires": {}
+    },
     "lodash.merge": {
       "version": "4.6.2",
       "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -8271,6 +8499,11 @@
         "sourcemap-codec": "^1.4.4"
       }
     },
+    "memoize-one": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+      "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+    },
     "merge-source-map": {
       "version": "1.1.0",
       "resolved": "https://registry.npm.taobao.org/merge-source-map/download/merge-source-map-1.1.0.tgz",
@@ -8328,11 +8561,6 @@
       "resolved": "https://registry.nlark.com/minimist/download/minimist-1.2.5.tgz?cache=0&sync_timestamp=1618847017774&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fminimist%2Fdownload%2Fminimist-1.2.5.tgz",
       "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI="
     },
-    "mitt": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npm.taobao.org/mitt/download/mitt-2.1.0.tgz",
-      "integrity": "sha1-90BXfCMXbGIFsSGylzUU6t4bIjA="
-    },
     "moment": {
       "version": "2.29.4",
       "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
@@ -8394,10 +8622,10 @@
       "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=",
       "dev": true
     },
-    "normalize-wheel": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npm.taobao.org/normalize-wheel/download/normalize-wheel-1.0.1.tgz",
-      "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
+    "normalize-wheel-es": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
+      "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
     },
     "nwmatcher": {
       "version": "1.4.4",
@@ -8837,11 +9065,6 @@
       "integrity": "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==",
       "dev": true
     },
-    "resize-observer-polyfill": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npm.taobao.org/resize-observer-polyfill/download/resize-observer-polyfill-1.5.1.tgz",
-      "integrity": "sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ="
-    },
     "resolve": {
       "version": "1.22.1",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",

+ 1 - 1
package.json

@@ -17,7 +17,7 @@
     "dayjs": "^1.10.7",
     "default-passive-events": "^2.0.0",
     "echarts": "^5.2.2",
-    "element-plus": "^1.0.2-beta.71",
+    "element-plus": "^2.2.26",
     "file-saver": "^2.0.5",
     "html2canvas": "^1.0.0-rc.7",
     "jsencrypt": "^3.2.1",

+ 2 - 2
src/api/config.js

@@ -1,6 +1,6 @@
 const config = {
-    baseURL: 'http://192.168.1.5:9002',
-    socketURL: 'ws://192.168.1.5:9002'
+    baseURL: 'http://192.168.1.82:9002',
+    socketURL: 'ws://192.168.1.82:9002'
 }
 
 export default config;

+ 1 - 1
src/assets/css/main.css

@@ -155,7 +155,7 @@ a {
 
 ::-webkit-scrollbar {
     width: 6px;
-    height: 8px;
+    height: 6px;
     background-color: #e4e4e4;
     border-radius: 6px;
 }

+ 6 - 4
src/components/Header.vue

@@ -1,10 +1,12 @@
 <template>
   <div class="header">
     <!-- 折叠按钮 -->
-    <div> 
-      <div class="collapse-btn" @click="collapseChage">
-        <i v-if="!collapse" class="el-icon-s-fold"></i>
-        <i v-else class="el-icon-s-unfold"></i>
+    <div class="flex items-center"> 
+      <div class="collapse-btn h-[55px] flex items-center justify-center" @click="collapseChage">
+        <!-- <i v-if="!collapse" class="el-icon-s-fold"></i>
+        <i v-else class="el-icon-s-unfold"></i> -->
+        <el-icon v-if="!collapse"><Fold /></el-icon>
+        <el-icon v-else><Expand /></el-icon>
       </div>
       <div class="logo">发电能力分析平台</div>
     </div>

File diff suppressed because it is too large
+ 5 - 3
src/components/Sidebar.vue


+ 1 - 1
src/components/SubmitBtn.vue

@@ -8,5 +8,5 @@ const props = defineProps({
 </script>
 <template>
 	<!-- <div class="h-[24px] flex justify-center items-center text-white bg-[rgba(0,70,199,0.5)] px-[15px] cursor-pointer text-[14px] rounded-[13px]">{{props.desc}}</div> -->
-	<el-button size="small" type="primary">{{props.desc}}</el-button>
+	<el-button type="primary">{{props.desc}}</el-button>
 </template>

+ 1 - 1
src/components/tree.vue

@@ -12,7 +12,7 @@
 				<p v-if="node.level === 1" class="flex justify-between items-center text-[12px]"
 					:class="[props.showCheckbox ? 'w-[84%]' : 'w-[90%]']">
 					<span>{{ node.label }}</span>
-					<el-icon class="!text-[rgb(64,158,255)]" title="刷新" @click.stop="emits('refresh')">
+					<el-icon class="!text-[rgb(64,158,255)]" size="14" title="刷新" @click.stop="emits('refresh')">
 						<RefreshRight />
 					</el-icon>
 				</p>

+ 1 - 1
src/main.js

@@ -5,7 +5,7 @@ import App from './App.vue'
 import router from './router'
 import store from './store'
 import ElementPlus from 'element-plus'
-import 'element-plus/lib/theme-chalk/index.css'
+import 'element-plus/dist/index.css'
 import './assets/css/icon.css'
 import './assets/font/iconfont.css'
 import 'default-passive-events'

+ 398 - 0
src/pages/dataAnalysis/agcAnalysis/components/configStation.json

@@ -0,0 +1,398 @@
+{
+	"NSS_BT": {
+		"id": "NSS_BT",
+		"installedCapacity": 148.5,
+		"title": "牛首山第二风电场",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "NSSDQN.NX_GD_NSSF_DQ_P1_L1_001_AI1019",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "NSSDQN.NX_GD_NSSF_DQ_P1_L1_001_AI1009",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "NSSDQN.NX_GD_NSSF_DQ_P1_L1_001_AI1010",
+			"multiplier": 0.001,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "NSSFCJSFW.NX_GD_NSSF_XX_XX_XXX_XXX_CI0193",
+			"multiplier": 0.001,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "NSSDQN.NX_GD_NSSF_DQ_P1_L1_001_AI1011",
+			"multiplier": 0.1,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "NSSFGL.NX_GD_NSSF_YC_P1_L1_001_CDQ001",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	},
+	"QS_BT": {
+		"id": "QS_BT",
+		"installedCapacity": 99.0,
+		"title": "麻黄山第六风电场",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "QSDQ.NX_GD_QSF_DQ_P1_L1_001_AI1281",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "QSDQ.NX_GD_QSF_DQ_P1_L1_001_AI1282",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "QSDQ.NX_GD_QSF_DQ_P1_L1_001_AI1284",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "QSFCJSFW.NX_GD_QSF_FJ_P1_XXX_XXX_CI0192,QSFCJSFW.NX_GD_QSF_FJ_P2_XXX_XXX_CI0192",
+			"multiplier": 0.001,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "QSDQ.NX_GD_QSF_DQ_P1_L1_001_AI1285",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "QSFGL.NX_GD_QSF_YC_P1_L1_001_CDQ001",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	},
+	"XS_BT": {
+		"id": "XS_BT",
+		"installedCapacity": 99.0,
+		"title": "香山第五风电场",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "XSDQ.NX_GD_XSF_DQ_P1_L1_001_AI0411",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "XSDQ.NX_GD_XSF_DQ_P1_L1_001_AI0415",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "XSDQ.NX_GD_XSF_DQ_P1_L1_001_AI0412",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "XSFCJSFW.NX_GD_XSF_XX_XX_XXX_XXX_CI0193",
+			"multiplier": 0.001,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "XSDQ.NX_GD_XSF_DQ_P1_L1_001_AI0413",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "XSFGL.NX_GD_XSF_YC_P1_L1_001_CDQ001",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	},
+	"MHS_BT": {
+		"id": "MHS_BT",
+		"installedCapacity": 69.5,
+		"title": "麻黄山第二风电场",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "MHSDQ.NX_GD_MHSF_DQ_P1_L1_001_AI0296",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "MHSDQ.NX_GD_MHSF_DQ_P1_L1_001_AI0013",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "MHSDQ.NX_GD_MHSF_DQ_P1_L1_001_AI0294",
+			"multiplier": 0.1,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "MHSFCJSFW.NX_GD_MHSF_XX_XX_XXX_XXX_CI0193",
+			"multiplier": 0.001,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "MHSDQ.NX_GD_MHSF_DQ_P1_L1_001_AI0295",
+			"multiplier": 0.01,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "MHSFGL.NX_GD_MHSF_YC_P1_L1_001_CDQ001",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	},
+	"XH_BT": {
+		"id": "XH_BT",
+		"installedCapacity": 20.0,
+		"title": "宣和光伏电站",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "XHDQ.NX_GD_XHG_DQ_P1_L1_001_AI0204",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "XHDQ.NX_GD_XHG_DQ_P1_L1_001_AI0193",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "XHDQ.NX_GD_XHG_DQ_P1_L1_001_AI0194",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "XHGDCJSFW.NX_GD_XHG_XX_XX_XXX_XXX_CI0192",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "XHDQ.NX_GD_XHG_DQ_P1_L1_001_AI0195",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "XHGGL.NX_GD_XHG_YC_P1_L1_001_CDQ001",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	},
+	"SL_BT": {
+		"id": "SL_BT",
+		"installedCapacity": 49.5,
+		"title": "宋堡第六风电场",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "SLAGC.NX_GD_QSF_DQ_P1_L1_001_AI0052",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "SLDQ.NX_GD_QSF_DQ_P1_L1_001_AI0013",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "SLAGC.NX_GD_QSF_DQ_P1_L1_001_AI0053",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "QSFCJSFW.NX_GD_QSF_FJ_P3_XXX_XXX_CI0192",
+			"multiplier": 0.001,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "SLAGC.NX_GD_QSF_DQ_P1_L1_001_AI0054",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "SLFGL.NX_GD_QSF_YC_P1_L1_001_LCDQ01",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	},
+	"HZJ_BT": {
+		"id": "HZJ_BT",
+		"installedCapacity": 50.0,
+		"title": "海子井光伏电站",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "HZJAGC.NX_GD_HZJG_DQ_P1_L1_001_AI0016",
+			"multiplier": 0.001,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "HZJAGC.NX_GD_HZJG_DQ_P1_L1_001_AI0015",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "HZJAGC.NX_GD_HZJG_DQ_P1_L1_001_AI0021",
+			"multiplier": 0.001,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "HZJAGC.NX_GD_HZJG_DQ_P1_L1_001_AI0214",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "HZJAGC.NX_GD_HZJG_DQ_P1_L1_001_AI0022",
+			"multiplier": 0.001,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "HZJGGL.NX_GD_HZJG_YC_P1_L1_001_CDQ001",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	},
+	"XN6_BT": {
+		"id": "XN6_BT",
+		"installedCapacity": 49.5,
+		"title": "星能第六风电场",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "SBQXLDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0818",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "SBQXLDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0012",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "SBQXLDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0819",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "SBQXLDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0826",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "SBQXLDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0820",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "SBQXLDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0827",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	},
+	"N5_BT": {
+		"id": "N5_BT",
+		"installedCapacity": 149.0,
+		"title": "牛首山第五风电场",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "SBQNWDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0818",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "SBQNWDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0817",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "SBQNWDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0819",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "SBQNWDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0830",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "SBQNWDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0820",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "SBQNWDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0831",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	},
+	"DWK_BT": {
+		"id": "DWK_BT",
+		"installedCapacity": 10.0,
+		"title": "大武口光伏电站",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "DWKDQ.NX_GD_DWKG_DQ_P1_L1_001_AI0838",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "DWKGDCJSFW.NX_GD_DWKG_XX_XX_XXX_XXX_CI0192",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "DWKDQ.NX_GD_DWKG_DQ_P1_L1_001_AI0839",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "DWKGGL.NX_GD_DWKG_YC_P1_L1_001_CDQ001",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	},
+	"PL_BT": {
+		"id": "PL_BT",
+		"installedCapacity": 30.0,
+		"title": "平罗光伏电站",
+		"aiPoints": [{
+			"name": "有功设定限值",
+			"tag": "PLSJ1.NX_GD_PLG_DQ_P1_L1_001_AI0838",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "实发有功",
+			"tag": "PLSJ1.NX_GD_PLG_DQ_P1_L1_001_AI0835",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调上限",
+			"tag": "PLSJ1.NX_GD_PLG_DQ_P1_L1_001_AI0836",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "理论功率",
+			"tag": "PLGDCJSFW.NX_GD_PLG_XX_XX_XXX_XXX_CI0192",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "AGC可调下限",
+			"tag": "PLSJ1.NX_GD_PLG_DQ_P1_L1_001_AI0837",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}, {
+			"name": "预测功率",
+			"tag": "PLGGL.NX_GD_PLG_YC_P1_L1_001_CDQ0001",
+			"multiplier": 1.0,
+			"unit": "MW"
+		}]
+	}
+}

src/pages/dataAnalysis/chartTheme.json → src/pages/dataAnalysis/agcAnalysis/components/current-scatter-chart.json


+ 344 - 0
src/pages/dataAnalysis/agcAnalysis/components/current-scatter-chart.vue

@@ -0,0 +1,344 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@tools/util";
+import partten from "@tools/partten";
+import * as echarts from "echarts";
+import chartTheme from './current-scatter-chart.json'
+
+export default {
+  name: 'currentScatterChart',
+  props: {
+    // 图表宽度
+    width: {
+      type: String,
+      default: "100%",
+    },
+    // 图表高度
+    height: {
+      type: String,
+      default: "350px",
+    },
+    // 图表主标题
+    chartTitle: {
+      type: String,
+      default: "自定义图表组件",
+    },
+    // X 轴配置项
+    xAxisData: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    // Y 轴配置项
+    yAxisData: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    dataSet: {
+      type: String,
+      default: ''
+    },
+    // 图表核心数据
+    seriesData: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    // 是否显示图表图例
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 是否默认采用笔刷模式
+    brushSelected: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: [
+        "#05bb4c",
+        "#4b55ae",
+        "#fa8c16",
+        "#f8de5b",
+        "#1a93cf",
+        "#c531c7",
+        "#bd3338",
+      ],
+      theme: 'light'
+    };
+  },
+  watch: {
+    height(){
+      if(this.chart){
+          this.chart.resize()
+      }
+    }
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      const that = this;
+      echarts.registerTheme('chartTheme', chartTheme)
+      let myChart = echarts.init(document.getElementById(this.id), 'chartTheme');
+      that.chart = myChart
+      //指定图表的配置项和数据
+      const option = {
+        //标题
+        title: {
+          text: that.chartTitle,
+          right: 440,
+          top: 4,
+          textStyle: {
+            fontSize: 14,
+            color: that.theme === "dark" ? partten.getColor("grayl") : "#000",
+          },
+        },
+        // backgroundColor:
+        //   that.theme === "dark"
+        //     ? "rgba(0,0,0,0.4)"
+        //     : "rgba(255,255,255,0.5)",
+        //工具箱
+        color: [
+            "rgb(255,0,0)",
+            "#FF8700",
+            "#e6b600d9",
+            "#0098d9",
+            "#3D54BE",
+            "#005eaa",
+            "#cda819",
+            "#32a487"
+        ],
+        toolbox: {
+          show: false,
+          x: "right",
+          position: [10, 10],
+          // backgroundColor:'rgba(0,0,0,0.4)',
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            fontSize: util.vh(16),
+            color: partten.getColor("gray")
+          },
+          iconStyle: {
+            borderColor:partten.getColor("gray")
+          },
+          emphasis: {
+            iconStyle: {
+              borderColor:partten.getColor("gray")
+            },
+          },
+        },
+        tooltip: {
+          trigger: "axis",
+          axisPointer: {
+            type: "cross",
+          },
+          // backgroundColor: "rgba(0,0,0,0.4)",
+          // borderColor: partten.getColor("gray"),
+          // textStyle: {
+          //   fontSize: util.vh(16),
+          //   color: partten.getColor("gray"),
+          // },
+          // formatter(params) {
+          //   return params.value?.x
+          //     ? `${params.seriesName}<br />风速:${params.value.x}m/s<br />功率:${params.value.y}kW`
+          //     : `${params.name}`;
+          // },
+        },
+        brush: {
+          seriesIndex: [2,3],
+          yAxisIndex: 0,
+          transformable: true,
+          throttleType: "debounce",
+          throttleDelay: 1000,
+          removeOnClick: true,
+          brushType: "polygon",
+          brushMode: "multiple",
+          brushStyle: {
+            borderWidth: 1,
+            borderColor: "#ff2424",
+          },
+        },
+        dataZoom: [
+          {
+            type: "inside", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+          {
+            type: "slider", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+        ],
+        textStyle: {
+          fontSize: util.vh(16),
+          color: that.theme === "dark" ? "#fff" : "#000",
+        },
+        //图例-每一条数据的名字
+        legend: {
+          show: that.showLegend,
+          // data: [ "拟合功率", "保证功率","无用点", "有用点", "Cp值"],
+          right: 170,
+          type: 'scroll',
+          top: "5",
+          // icon: "circle",
+          itemWidth: 6,
+          inactiveColor:
+            that.theme === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color:
+              that.theme === "dark"
+                ? partten.getColor("grayl")
+                : "#000",
+            fontSize: 12,
+          },
+          
+        },
+        grid: {
+          top: 58,
+          left: 40,
+          right: 40,
+          bottom: 24,
+        },
+        //x轴
+        xAxis: [
+          {
+            name: 'm/s',
+            nameTextStyle: {
+              color: '#B3B3B3'
+            },
+            type: "value",
+            boundaryGap: false,
+            data: that.xAxisData || [],
+            min: 0,
+            max: 25,
+            interval: 1,
+            axisLabel: {
+              formatter: "{value}",
+            },
+            splitLine: {
+              show: false,
+            },
+            smooth: true,
+            textStyle: {
+              color:
+                that.theme === "dark"
+                  ? partten.getColor("gray")
+                  : "#000",
+            },
+          },
+        ],
+        //y轴没有显式设置,根据值自动生成y轴
+        yAxis: [{
+          splitLine: { show: false },
+          position: 'left',
+          min: 0,
+          name: 'kW',
+          nameTextStyle: {
+            color: '#B3B3B3'
+          }
+        }],
+        animation: true,
+        dataset: that.dataSet.length? JSON.parse(that.dataSet) : [],
+        //数据-data是最终要显示的数据
+        series: that.seriesData,
+      };
+
+      that.resize = function () {
+        myChart.resize();
+      };
+
+      window.addEventListener("resize", that.resize);
+
+      myChart.setOption(option);
+      // if (that.brushSelected) {
+      //   myChart.dispatchAction({
+      //     type: "takeGlobalCursor",
+      //     // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+      //     key: "brush",
+      //     brushOption: {
+      //       seriesIndex: [2,3],
+      //       yAxisIndex: 0,
+      //       transformable: true,
+      //       throttleType: "debounce",
+      //       throttleDelay: 1000,
+      //       removeOnClick: true,
+      //       brushType: "polygon",
+      //       brushMode: "multiple",
+      //       brushStyle: {
+      //         borderWidth: 1,
+      //         color: "rgba(255,36,36,0.2)",
+      //         borderColor: "#ff2424",
+      //       },
+      //     },
+      //   });
+      // }
+      myChart.off("brushSelected");
+      myChart.on("brushSelected", (params) => {
+        that.$emit("getSelected", params.batch || []);
+      });
+      myChart.off('click')
+      myChart.on('click', params => {
+          // if(params.componentType === 'markArea'){
+          //   myChart.dispatchAction({
+          //     type: 'brush',
+          //     areas: [
+          //       {
+          //         xAxisIndex: 0,
+          //         brushType: 'lineX',
+          //         coordRange: [params.data.coord[0][0], params.data.coord[1][0]]
+          //       },
+          //     ]
+          //   });
+          // }
+        })
+    },
+  },
+  created() {
+    this.id = "chart-" + util.newGUID();
+  },
+  mounted() {
+    // this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    // });
+  },
+  updated() {
+    console.log('update')
+    let myChart = echarts.init(document.getElementById(this.id));
+    myChart.dispose();
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 75 - 0
src/pages/dataAnalysis/agcAnalysis/components/search.vue

@@ -0,0 +1,75 @@
+<script setup name="search">
+import { onMounted, reactive, ref } from 'vue'
+import request from '@/api/axios.js'
+import SubmitBtn from '@com/SubmitBtn.vue'
+import configStationJson from './configStation.json'
+
+const queryForm = reactive({
+	station: '',
+	st: Date.now() - 30 * 24 * 60 * 60 * 1000,
+	et: Date.now(),
+	interval: 3
+})
+/**场站 */
+const stationList = ref([])
+const funGetStation = async () => {
+	// const res = await request.get("/agc/config")
+	stationList.value = Object.values(configStationJson) // configStationJson
+	if (stationList.value.length) {
+		queryForm.station = stationList.value[0].id
+	}
+}
+/**导出 */
+const emits = defineEmits(['submit'])
+const funSubmit = async () => {
+	const query = {
+		id: queryForm.station,
+		startTs: new Date(queryForm.st).getTime(),
+		endTs: new Date(queryForm.et).getTime(),
+		interval: queryForm.interval
+	}
+	switch (queryForm.interval) {
+		case 2:
+			query.interval = 60
+			break;
+		case 3:
+			query.interval = 600
+			break;
+		case 4:
+			query.interval = 900
+			break;
+	}
+	emits('submit', query)
+}
+/**created */
+funGetStation()
+</script>
+<template>
+	<div class="pl-[20px] flex items-center h-[80px] relative">
+		<div class="absolute top-[-7px] left-[20px] text-[#B3B3B3] text-[14px]">操作面板</div>
+		<el-form class="" :inline="true" :model="queryForm">
+			<el-form-item label="场站" class="!mb-0">
+				<el-select v-model="queryForm.station" class="w-[150px]">
+					<el-option v-for="item in stationList" :key="item.id" :label="item.title" :value="item.id"></el-option>
+				</el-select>
+			</el-form-item>
+			<el-form-item label="开始时间" class="!mb-0">
+				<el-date-picker type="date" class="!w-[150px]" v-model="queryForm.st"></el-date-picker>
+			</el-form-item>
+			<el-form-item label="结束时间" class="!mb-0">
+				<el-date-picker type="date" class="!w-[150px]" v-model="queryForm.et"></el-date-picker>
+			</el-form-item>
+			<el-form-item label="等间隔" class="!mb-0">
+				<el-radio-group v-model="queryForm.interval">
+					<el-radio :label="1">一秒钟</el-radio>
+					<el-radio :label="2">一分钟</el-radio>
+					<el-radio :label="3">十分钟</el-radio>
+					<el-radio :label="4">十五分钟</el-radio>
+				</el-radio-group>
+			</el-form-item>
+			<el-form-item class="!mb-0">
+				<submit-btn v-prevdbclick:5000="funSubmit" desc="执行"></submit-btn>
+			</el-form-item>
+		</el-form>
+	</div>
+</template>

+ 53 - 0
src/pages/dataAnalysis/agcAnalysis/components/table.vue

@@ -0,0 +1,53 @@
+<script setup name="table">
+import {ref, computed} from 'vue'
+const props = defineProps({
+  height: {
+    type: String,
+    default: '800px'
+  },
+  data: {
+    type: Array,
+    default: () => ([]),
+  },
+  column: {
+    type: Array,
+    default: () => ([]),
+  },
+  tableName: {
+    type: String,
+    default: '',
+  },
+  tableId: {
+    type: String,
+    default: '',
+  },
+  loading: {
+    type: Boolean,
+    default: false,
+  }
+})
+const emits = defineEmits(['export'])
+const funExport = () => {
+  emits('export')
+}
+const tableRef = ref('')
+const tableHeight =  computed(() => {
+  return tableRef.value.offsetHeight? tableRef.value.offsetHeight - 46 : 739
+})
+</script>
+<template>
+  <div ref="tableRef" class="p-[10px]"
+    :style="{ height: typeof props.height === 'string' ? props.height : props.height + 'px' }">
+    <div class="flex justify-between items-center pb-[10px]">
+      <h3>{{props.tableName}}</h3>
+      <!-- <el-button size="small" type="primary" @click="funExport" :disabled="!props.tableId">数据导出</el-button> -->
+    </div>
+    <el-table :data="props.data"
+      stripe
+      size="small" v-loading="props.loading"
+      :max-height="tableHeight"
+      :style="{ width: '100%'}">
+      <el-table-column align="center" show-overflow-tooltip v-for="item in props.column" :prop="item.prop" :label="item.label" sortable resizable :min-width="item.width? item.width : 80" />
+    </el-table>
+  </div>
+</template>

+ 177 - 0
src/pages/dataAnalysis/agcAnalysis/index.vue

@@ -0,0 +1,177 @@
+<script setup name="prepare">
+import searchCop from './components/search.vue'
+import excelCop from '@/components/excel.vue'
+import treeCop from '@/components/tree.vue'
+import tableCop from './components/table.vue'
+import { ElMessage } from 'element-plus';
+import { onMounted, ref, onActivated } from 'vue'
+import CurrentScatterChart from './components/current-scatter-chart.vue'
+import request from '@/api/axios.js'
+import {baseURL, socketURL} from '@/api/axios.js'
+/**配置参数 */
+const tableHeight = ref(window.innerHeight - 314 + 'px')
+const treeHeight = ref(window.innerHeight - 260 + 'px') //tree高度
+const excelHeight = ref(window.innerHeight - 260 + 'px') //excel高度
+/**excel 开始 */
+const excelList = ref([])
+const funExcelChange = async (obj) => { //点击excel项时
+	activeTab.value = '1'
+	tableShowId.value = obj.id
+	tableName.value = obj.name
+	tableLoading.value = true
+	const res = await request.get('/power/prepare/show', { params: { id: obj.id } })
+	if(res.code === 200){
+		tableColumn.value = res.data.title.map(o => {
+			return {
+				prop: o.key,
+				label: o.des,
+				width: o.des==='时间'? 100: 80,
+			}
+		})
+		tableData.value = res.data.data
+		tableLoading.value = false
+	}else{
+		tableLoading.value = false
+	}
+}
+/**tree 开始 */
+const treeData = ref([])
+const funRepeatMap = (arr) => {
+	return arr.map(o => {
+		if (o.children) {
+			const findIndex = o.children.findIndex(p => !!p.type)
+			if (findIndex !== -1) {
+				o.childs = o.children
+				o.children = []
+			}
+		}
+		return {
+			...o,
+			children: o.children?.length ? funRepeatMap(o.children) : []
+		}
+	})
+}
+const funGetTree = async () => {
+	const res = await request.get("/power/prepare/tree")
+	treeData.value = funRepeatMap(res.data)
+	excelList.value = []
+}
+const funCurrentChange = ({ current, currentNode }) => {
+	if (current.childs) {
+		excelList.value = current.childs.map(o => {
+			return {
+				id: o.id,
+				interval: o.interval,
+				path: o.path,
+				prepareid: o.prepareid,
+				station: o.station,
+				time: o.time,
+				type: o.type,
+				windturbine: o.windturbine,
+				name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station + '_').length)
+			}
+		})
+	} else {
+		excelList.value = []
+	}
+}
+/**table 开始 */
+const tableShowId = ref('')
+const tableName = ref('')
+const tableColumn = ref([])
+const tableLoading = ref(false)
+const tableData = ref([])
+const funExport = async () => {
+	const a = document.createElement('a')
+	a.href = baseURL + '/power/prepare/download?id=' + tableShowId.value
+	a.download = ''
+	a.click()
+}
+/**tab  */
+const activeTab = ref('1')
+/**chart Data */
+const xAxisData = ref([])
+const chartRef = ref() //chart 的ref
+const seriesData = ref([])
+const dataSet = ref('')
+const funChartSelect = async (batch) => {
+	return false
+}
+/**submit */
+const funSubmit = async (params) => {
+	const res = await request.get('/agc/deviate', { params: params })
+	if (res.code === 200) {
+		ElMessage.success(res.msg)
+		// if(res.data.sjgl?.length){
+		// 	for(const wtObj of res.data.sjgl){
+		// 		seriesData.value.push(
+		// 			{
+		// 				name: wtObj.obj.windturbine + "\n实际功率",
+		// 				type: "line",
+		// 				symbol: "line", //设定为实心点
+		// 				symbolSize: 0, //设定实心点的大小
+		// 				smooth: true, //这个是把线变成曲线
+		// 				data: wtObj.sjgl || [],
+		// 				xAxisIndex: 0,
+		// 			},
+		// 		)
+		// 		wtData.value.push(wtObj.obj)
+		// 	}
+		// }
+	}
+}
+/**created */
+// funGetTree()
+/**mounted */
+onMounted(() => {
+	tableHeight.value = window.innerHeight - 314 + 'px'
+	excelHeight.value = window.innerHeight - 260 + 'px'
+	treeHeight.value = window.innerHeight - 260 + 'px'
+	window.addEventListener('resize', () => {
+		tableHeight.value = window.innerHeight - 314 + 'px'
+		excelHeight.value = window.innerHeight - 260 + 'px'
+		treeHeight.value = window.innerHeight - 260 + 'px'
+	})
+})
+/**activated */
+onActivated(() => {
+	funGetTree()
+})
+</script>
+<template>
+	<div class="bg-white py-[10px] px-[10px] relative">
+		<search-cop class="mb-[20px] shadow rounded-[6px] shadow-blue-500" @submit="funSubmit">
+		</search-cop>
+		<div class="relative shadow rounded-[6px] shadow-blue-500 px-[10px] pt-[20px] pb-[10px]">
+			<div class="text-[14px] absolute top-[-7px] text-[#B3B3B3] left-[20px]">数据展示</div>
+			<el-row :gutter="10">
+				<el-col :span="5">
+					<tree-cop :data="treeData" :height="treeHeight" @currentChange="funCurrentChange" @refresh="funGetTree">
+					</tree-cop>
+				</el-col>
+				<el-col :span="3">
+					<excel-cop :data="excelList" :height="excelHeight" @excelChange="funExcelChange"></excel-cop>
+				</el-col>
+				<el-col :span="16">
+					<div class="px-[10px] shadow rounded-[6px] shadow-blue-500 ">
+						<el-tabs v-model="activeTab">
+							<el-tab-pane label="表格数据" name="1">
+							</el-tab-pane>
+							<el-tab-pane label="图表展示" name="2">
+							</el-tab-pane>
+							<table-cop v-show="activeTab === '1'" :data="tableData" :loading="tableLoading" :column="tableColumn"
+								:height="tableHeight" :tableId="tableShowId" :tableName="tableName"></table-cop>
+							<div v-show="activeTab === '2'"
+								:style="{ height: typeof tableHeight === 'string' ? tableHeight : tableHeight + 'px' }"
+								class="p-[10px]">
+								<CurrentScatterChart ref="chartRef" width="100%" :height="`calc( ${tableHeight} - 20px )`" :chartTitle="''"
+									:xAxisData="xAxisData" :yAxisData="{ splitLine: { show: false } }" :seriesData="seriesData"
+									:showLegend="true" :brushSelected="false" :dataSet="dataSet" @getSelected="funChartSelect" />
+							</div>
+						</el-tabs>
+					</div>
+				</el-col>
+			</el-row>
+		</div>
+	</div>
+</template>

+ 10 - 8
src/pages/dataAnalysis/combine/components/chartTheme.json

@@ -1,16 +1,15 @@
 
 {
 	"color": [
-			"#db60c8",
-			"#c12e34",
+			"#1C99FF",
+			"#FF8700",
 			"#e6b600d9",
 			"#0098d9",
-			"#465a83",
+			"#3D54BE",
 			"#005eaa",
 			"#cda819",
 			"#32a487"
 	],
-	"backgroundColor": "rgba(0,0,0,0)",
 	"textStyle": {},
 	"title": {
 			"textStyle": {
@@ -204,18 +203,18 @@
 			"axisLine": {
 					"show": true,
 					"lineStyle": {
-							"color": "#333"
+							"color": "#B3B3B3"
 					}
 			},
 			"axisTick": {
 					"show": true,
 					"lineStyle": {
-							"color": "#333"
+							"color": "#B3B3B3"
 					}
 			},
 			"axisLabel": {
 					"show": true,
-					"color": "#333"
+					"color": "#B3B3B3"
 			},
 			"splitLine": {
 					"show": true,
@@ -313,11 +312,14 @@
 					"iconStyle": {
 							"borderColor": "#4187c2"
 					}
+			},
+			"textStyle": {
+				"color": "#B3B3B3"
 			}
 	},
 	"legend": {
 			"textStyle": {
-					"color": "#333333"
+					"color": "#B3B3B3"
 			}
 	},
 	"tooltip": {

+ 10 - 2
src/pages/dataAnalysis/combine/components/current-scatter-chart.vue

@@ -6,7 +6,7 @@
 import util from "@tools/util";
 import partten from "@tools/partten";
 import * as echarts from "echarts";
-import chartTheme from './../../chartTheme.json'
+import chartTheme from './current-scatter-chart.json'
 
 export default {
   name: 'currentScatterChart',
@@ -78,12 +78,20 @@ export default {
       theme: 'light'
     };
   },
+  watch: {
+    height(){
+      if(this.chart){
+          this.chart.resize()
+      }
+    }
+  },
   methods: {
     resize() {},
     initChart() {
       const that = this;
       echarts.registerTheme('chartTheme', chartTheme)
       let myChart = echarts.init(document.getElementById(this.id), 'chartTheme');
+      that.chart = myChart
       //指定图表的配置项和数据
       const option = {
         //标题
@@ -104,7 +112,7 @@ export default {
         color: [
             "#3D54BE",
             "rgb(255,0,0)",
-            "#d3d3d3",
+            "#a1a1a1",
             "#0098d9",
             "#FF8700",
             "#005eaa",

+ 26 - 29
src/pages/dataAnalysis/combine/index.vue

@@ -13,9 +13,9 @@ import CurrentScatterChart from './components/current-scatter-chart.vue'
 // import tableRes from '@/data/table.json'
 // import areaDataRes from '@/data/areaData.json'
 /**配置参数 */
-const treeHeight = ref((window.innerHeight - 210) / 2 + 'px') //tree高度
-const excelHeight = ref((window.innerHeight - 210) / 2 + 'px') //excel高度
-const tableHeight = ref(window.innerHeight - 254 + 'px')
+const tableHeight = ref(window.innerHeight - 314 + 'px')
+const excelHeight = ref((window.innerHeight - 270) / 2 + 'px')
+const treeHeight = ref((window.innerHeight - 270) / 2 + 'px')
 /**excel 开始 */
 const excelCheckboxShow = ref(false)
 const excelType = ref('')
@@ -36,7 +36,6 @@ const funExcelChange = async (obj) => { //点击excel项时
 		llgl: [[]],
 		cpz: [[]]
 	}
-	let poiRes = null
 	let chartResponse = null
 	tableLoading.value = true
 	if (obj.type === 'process') {
@@ -47,29 +46,27 @@ const funExcelChange = async (obj) => { //点击excel项时
 		// res = tableRes
 		// chartResponse = dotRes
 		chartResponse = await request.get('/power/fitting/curve', { params: { id: obj.id, p: 1 } })
-		poiRes = await request.get('/power/fitting/curve/ratio', {params: {id: obj.id}})
-		// poiRes = areaDataRes
 	}
-	tableColumn.value = res.data.title.map(o => {
-		return {
-			prop: o.key,
-			width: o.des==='时间'? 100: 80,
-			label: o.des,
-		}
-	})
-	tableData.value = res.data.data
-	tableLoading.value = false
-
-	// markDot 
-	if(poiRes && poiRes.code=== 200){
-		markDot.pcl5 = poiRes.data.pcl5
-		markDot.pcl10 = poiRes.data.pcl10
-		markDot.pcl12 = poiRes.data.pcl12
-		markDot.pcl25 = poiRes.data.pcl25
+	if(res.code === 200){
+		tableColumn.value = res.data.title.map(o => {
+			return {
+				prop: o.key,
+				width: o.des==='时间'? 100: 80,
+				label: o.des,
+			}
+		})
+		tableData.value = res.data.data
+		tableLoading.value = false
+	}else{
+		tableLoading.value = false
 	}
 
 	if (chartResponse && chartResponse.code === 200) {
 		chartRes = chartResponse.data
+		markDot.pcl5 = chartRes.obj.pc5ratio
+		markDot.pcl10 = chartRes.obj.pc10ratio
+		markDot.pcl12 = chartRes.obj.pc12ratio
+		markDot.pcl25 = chartRes.obj.pc25ratio
 		avgObj.title = chartRes.obj.path.substring(chartRes.obj.path.indexOf(chartRes.obj.station + '_') + (chartRes.obj.station + '_').length).split('_')[0];
 		avgObj.cpavg = Number(chartRes.obj.cpavg).toFixed(2)
 		avgObj.frequency = Number(chartRes.obj.frequency).toFixed(2)
@@ -478,13 +475,13 @@ const activeTab = ref('1')
 // funGetProcessTree()
 /**mounted */
 onMounted(() => {
-	tableHeight.value = window.innerHeight - 254 + 'px'
-	excelHeight.value =(window.innerHeight - 210) / 2 + 'px'
-	treeHeight.value = (window.innerHeight - 210) / 2 + 'px'
+	tableHeight.value = window.innerHeight - 314 + 'px'
+	excelHeight.value =(window.innerHeight - 270) / 2 + 'px'
+	treeHeight.value = (window.innerHeight - 270) / 2 + 'px'
 	window.addEventListener('resize', () => {
-		tableHeight.value = window.innerHeight - 254 + 'px'
-		excelHeight.value = (window.innerHeight - 210) / 2 + 'px'
-		treeHeight.value = (window.innerHeight - 210) / 2  + 'px'
+		tableHeight.value = window.innerHeight - 314 + 'px'
+		excelHeight.value = (window.innerHeight - 270) / 2 + 'px'
+		treeHeight.value = (window.innerHeight - 270) / 2  + 'px'
 	})
 	/**test */
 	// funExcelChange({
@@ -551,7 +548,7 @@ onActivated(() => {
 							<div v-show="activeTab === '2'"
 								:style="{ height: typeof tableHeight === 'string' ? tableHeight : tableHeight + 'px' }"
 								class="p-[10px]">
-								<CurrentScatterChart ref="chartRef" width="100%" height="calc( 100% - 20px )" :chartTitle="avgObj.title+ '&nbsp;&nbsp;' +'平均Cp值:'+avgObj.cpavg+'; 静风频率:'+avgObj.frequency+'%; 曲线偏差率:'+avgObj.pcratio+'%'"
+								<CurrentScatterChart ref="chartRef" width="100%" :height="`calc( ${tableHeight} - 20px )`" :chartTitle="avgObj.title+ '&nbsp;&nbsp;' +'平均Cp值:'+avgObj.cpavg+'; 静风频率:'+avgObj.frequency+'%; 曲线偏差率:'+avgObj.pcratio+'%'"
 									:xAxisData="xAxisData" :yAxisData="{ splitLine: { show: false } }" :seriesData="seriesData"
 									:showLegend="true" :brushSelected="!isChartArea" :dataSet="dataSet" @getSelected="funChartSelect" />
 							</div>

+ 397 - 0
src/pages/dataAnalysis/lineAnalysis/components/barChart.json

@@ -0,0 +1,397 @@
+
+{
+	"color": [
+			"#db60c8",
+			"#c12e34",
+			"#e6b600d9",
+			"#0098d9",
+			"#465a83",
+			"#005eaa",
+			"#cda819",
+			"#32a487"
+	],
+	"backgroundColor": "rgba(0,0,0,0)",
+	"textStyle": {},
+	"title": {
+			"textStyle": {
+					"color": "#B3B3B3B3B3B3"
+			},
+			"subtextStyle": {
+					"color": "#aaaaaa"
+			}
+	},
+	"line": {
+			"itemStyle": {
+					"borderWidth": 1
+			},
+			"lineStyle": {
+					"width": 2
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"radar": {
+			"itemStyle": {
+					"borderWidth": 1
+			},
+			"lineStyle": {
+					"width": 2
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"bar": {
+			"itemStyle": {
+					"barBorderWidth": 0,
+					"barBorderColor": "#ccc"
+			},
+			"barMaxWidth": 50
+	},
+	"pie": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"scatter": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"boxplot": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"parallel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"sankey": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"funnel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"gauge": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"candlestick": {
+			"itemStyle": {
+					"color": "#c12e34",
+					"color0": "#2b821d",
+					"borderColor": "#c12e34",
+					"borderColor0": "#2b821d",
+					"borderWidth": 1
+			}
+	},
+	"graph": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			},
+			"lineStyle": {
+					"width": 1,
+					"color": "#aaaaaa"
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false,
+			"color": [
+					"#c12e34",
+					"#e6b600",
+					"#0098d9",
+					"#50ec39",
+					"#005eaa",
+					"#339ca8",
+					"#cda819",
+					"#32a487"
+			],
+			"label": {
+					"color": "#eeeeee"
+			}
+	},
+	"map": {
+			"itemStyle": {
+					"areaColor": "#ddd",
+					"borderColor": "#eee",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#c12e34"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "#e6b600",
+							"borderColor": "#ddd",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#c12e34"
+					}
+			}
+	},
+	"geo": {
+			"itemStyle": {
+					"areaColor": "#ddd",
+					"borderColor": "#eee",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#c12e34"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "#e6b600",
+							"borderColor": "#ddd",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#c12e34"
+					}
+			}
+	},
+	"categoryAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#B3B3B3"
+			},
+			"splitLine": {
+					"show": false,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"valueAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#B3B3B3"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"logAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#B3B3B3"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"timeAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#B3B3B3"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"toolbox": {
+			"iconStyle": {
+					"borderColor": "#06467c"
+			},
+			"emphasis": {
+					"iconStyle": {
+							"borderColor": "#4187c2"
+					}
+			}
+	},
+	"legend": {
+			"textStyle": {
+					"color": "#B3B3B3B3B3B3"
+			}
+	},
+	"tooltip": {
+			"axisPointer": {
+					"lineStyle": {
+							"color": "#cccccc",
+							"width": 1
+					},
+					"crossStyle": {
+							"color": "#cccccc",
+							"width": 1
+					}
+			}
+	},
+	"timeline": {
+			"lineStyle": {
+					"color": "#005eaa",
+					"width": 1
+			},
+			"itemStyle": {
+					"color": "#005eaa",
+					"borderWidth": 1
+			},
+			"controlStyle": {
+					"color": "#005eaa",
+					"borderColor": "#005eaa",
+					"borderWidth": 0.5
+			},
+			"checkpointStyle": {
+					"color": "#005eaa",
+					"borderColor": "#316bc2"
+			},
+			"label": {
+					"color": "#005eaa"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"color": "#005eaa"
+					},
+					"controlStyle": {
+							"color": "#005eaa",
+							"borderColor": "#005eaa",
+							"borderWidth": 0.5
+					},
+					"label": {
+							"color": "#005eaa"
+					}
+			}
+	},
+	"visualMap": {
+			"color": [
+					"#1790cf",
+					"#a2d4e6"
+			]
+	},
+	"dataZoom": {
+			"backgroundColor": "rgba(47,69,84,0)",
+			"dataBackgroundColor": "rgba(47,69,84,0.3)",
+			"fillerColor": "rgba(167,183,204,0.4)",
+			"handleColor": "#a7b7cc",
+			"handleSize": "100%",
+			"textStyle": {
+					"color": "#B3B3B3B3B3B3"
+			}
+	},
+	"markPoint": {
+			"label": {
+					"color": "#eeeeee"
+			},
+			"emphasis": {
+					"label": {
+							"color": "#eeeeee"
+					}
+			}
+	}
+}

+ 184 - 0
src/pages/dataAnalysis/lineAnalysis/components/barChart.vue

@@ -0,0 +1,184 @@
+<script setup>
+import util from "@tools/util";
+import chartTheme from './barChart.json'
+import { ref, toRaw, computed, onMounted, watch, nextTick } from 'vue';
+import * as echarts from 'echarts'
+const chartId = 'chart-' + util.newGUID(); //chartId
+const chartIns = ref(null)  //chart 实例
+const emits = defineEmits(['getSelected'])
+const props = defineProps({
+	xAxis: {
+		type: Object,
+		required: true,
+		default: () => ({})
+	},
+	yAxis: {
+		type: Array,
+		required: false
+	},
+	series: {
+		type: Array,
+		required: true
+	},
+	dataset: {
+		type: Array,
+		required: false,
+		default: () => ([])
+	},
+	height: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	width: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	title: {
+		type: String,
+		required: false
+	},
+	subtext: {
+		type: String,
+		required: false
+	},
+	brush: {
+		type: Boolean,
+		required: false,
+		default: false
+	}
+})
+
+/**定义option */
+const option = computed({
+	get() {
+		return {
+			color:[
+				"#FF8700",
+				"#0098d980",
+				"#626c91",
+				"#a0a7e6",
+				"#c4ebad",
+				"#96dee8"
+			],
+			title: {
+				text: props.title || '',
+				subtext: props.subtext || '',
+				top: 6,
+				left: '5%',
+			},
+			xAxis: props.xAxis || {},
+			yAxis: props.yAxis || {},
+			brush: {
+          seriesIndex: [1],
+          yAxisIndex: 0,
+          transformable: true,
+          throttleType: "debounce",
+          throttleDelay: 1000,
+          removeOnClick: true,
+          brushType: props.brush? "polygon" : false,
+          brushMode: "multiple",
+          brushStyle: {
+            borderWidth: 1,
+            borderColor: "#ff2424",
+          },
+        },
+			toolbox:{
+				show: props.brush,
+			},
+			tooltip: {
+				confine: true,
+				trigger: "axis",
+			},
+			dataset: props.dataset || [],
+			series: props.series || [],
+			legend: {
+				right: "120",
+				top: "5",
+				itemWidth: 6,
+			},
+			grid: {
+				top: 80,
+				left: 40,
+				right: 40,
+				bottom: 40,
+			},
+			dataZoom: [
+          {
+            type: "inside", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+          {
+            type: "slider", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+        ],
+		}
+	},
+	set(val) { }
+})
+watch(() => option, (newVal, oldVal) => {
+	if (chartIns.value) {
+		const echartIns = toRaw(chartIns.value)
+		echartIns.setOption(toRaw(newVal.value))
+	}
+}, { deep: true })
+
+watch([() => props.width, () => props.height],(newVal, oldVal) => {
+	if(chartIns.value){
+		const echartIns = toRaw(chartIns.value)
+		nextTick(() => echartIns.resize())
+	}
+})
+const funBrushChange = (flag) => {
+	const echartIns = toRaw(chartIns.value)
+	echartIns.dispatchAction({
+			type: "takeGlobalCursor",
+			// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+			key: "brush",
+			brushOption: {
+				seriesIndex: [1],
+				yAxisIndex: 0,
+				transformable: true,
+				throttleType: "debounce",
+				throttleDelay: 1000,
+				removeOnClick: true,
+				brushType: flag? "polygon" : false,
+				brushMode: "multiple",
+				brushStyle: {
+					borderWidth: 1,
+					color: "rgba(255,36,36,0.2)",
+					borderColor: "#ff2424",
+				},
+			},
+		});
+	echartIns.off("brushSelected");
+	echartIns.on("brushSelected", (params) => {
+		emits("getSelected", params.batch || []);
+	});
+}
+watch(() => props.brush, (newVal, oldVal) => funBrushChange(newVal))
+
+onMounted(() => {
+	nextTick(() => {
+		echarts.registerTheme('chartTheme', chartTheme)
+		const echartIns =	echarts.init(document.getElementById(chartId),'chartTheme') 
+		chartIns.value = echartIns
+		echartIns.setOption(option.value)
+		funBrushChange(props.brush)
+		window.addEventListener('resize', () => {
+			echartIns.resize()
+		})
+	})
+})
+</script>
+<template>
+	<div :id="chartId" :style="{ height: props.height, width: props.width }"></div>
+</template>

+ 10 - 8
src/pages/dataAnalysis/lineAnalysis/components/chartTheme.json

@@ -1,16 +1,15 @@
 
 {
 	"color": [
-			"#db60c8",
-			"#c12e34",
+			"#1C99FF",
+			"#FF8700",
 			"#e6b600d9",
 			"#0098d9",
-			"#465a83",
+			"#3D54BE",
 			"#005eaa",
 			"#cda819",
 			"#32a487"
 	],
-	"backgroundColor": "rgba(0,0,0,0)",
 	"textStyle": {},
 	"title": {
 			"textStyle": {
@@ -204,18 +203,18 @@
 			"axisLine": {
 					"show": true,
 					"lineStyle": {
-							"color": "#333"
+							"color": "#B3B3B3"
 					}
 			},
 			"axisTick": {
 					"show": true,
 					"lineStyle": {
-							"color": "#333"
+							"color": "#B3B3B3"
 					}
 			},
 			"axisLabel": {
 					"show": true,
-					"color": "#333"
+					"color": "#B3B3B3"
 			},
 			"splitLine": {
 					"show": true,
@@ -313,11 +312,14 @@
 					"iconStyle": {
 							"borderColor": "#4187c2"
 					}
+			},
+			"textStyle": {
+				"color": "#B3B3B3"
 			}
 	},
 	"legend": {
 			"textStyle": {
-					"color": "#333333"
+					"color": "#B3B3B3"
 			}
 	},
 	"tooltip": {

+ 10 - 2
src/pages/dataAnalysis/lineAnalysis/components/current-scatter-chart.vue

@@ -6,7 +6,7 @@
 import util from "@tools/util";
 import partten from "@tools/partten";
 import * as echarts from "echarts";
-import chartTheme from './../../chartTheme.json'
+import chartTheme from './current-scatter-chart.json'
 
 export default {
   name: 'currentScatterChart',
@@ -78,12 +78,20 @@ export default {
       theme: 'light'
     };
   },
+  watch: {
+    height(){
+      if(this.chart){
+          this.chart.resize()
+      }
+    }
+  },
   methods: {
     resize() {},
     initChart() {
       const that = this;
       echarts.registerTheme('chartTheme', chartTheme)
       let myChart = echarts.init(document.getElementById(this.id), 'chartTheme');
+      that.chart = myChart
       //指定图表的配置项和数据
       const option = {
         //标题
@@ -185,7 +193,7 @@ export default {
         legend: {
           show: that.showLegend,
           // data: [ "拟合功率", "保证功率","无用点", "有用点", "Cp值"],
-          right: "120",
+          right: 170,
           type: 'scroll',
           top: "5",
           // icon: "circle",

+ 132 - 85
src/pages/dataAnalysis/lineAnalysis/index.vue

@@ -1,6 +1,7 @@
 <script setup name="prepare">
 import excelCop from '@/components/excel.vue'
 import treeCop from '@/components/tree.vue'
+import barChartCop from './components/barChart.vue'
 import SubmitBtn from '@/components/SubmitBtn.vue'
 import { ref, nextTick, onActivated, onMounted, reactive } from 'vue'
 import request from '@/api/axios.js'
@@ -11,9 +12,9 @@ import CurrentScatterChart from './components/current-scatter-chart.vue'
 // import tableRes from '@/data/table.json'
 // import areaDataRes from '@/data/areaData.json'
 /**配置参数 */
-const treeHeight = ref(window.innerHeight - 120 + 'px') //tree高度
-const excelHeight = ref(window.innerHeight - 120 + 'px') //excel高度
-const tableHeight = ref(window.innerHeight - 120 + 'px')
+const treeHeight = ref(window.innerHeight - 160 + 'px') //tree高度
+const excelHeight = ref(window.innerHeight - 160 + 'px') //excel高度
+const tableHeight = ref(window.innerHeight - 160 + 'px')
 /**excel 开始 */
 const excelCheckboxShow = ref(false)
 const excelCheckIds = ref([])
@@ -93,6 +94,7 @@ const funSubmit = async () => {
 		ElMessage.error('请勾选要执行的项')
 		return false
 	}
+	wtData.value = []
 	const params = {
 		ids: excelCheckIds.value.join(',')
 	}
@@ -116,7 +118,7 @@ const funSubmit = async () => {
 			for(const wtObj of res.data.sjgl){
 				seriesData.value.push(
 					{
-						name: wtObj.wtId + "\n实际功率",
+						name: wtObj.obj.windturbine + "\n实际功率",
 						type: "line",
 						symbol: "line", //设定为实心点
 						symbolSize: 0, //设定实心点的大小
@@ -125,6 +127,7 @@ const funSubmit = async () => {
 						xAxisIndex: 0,
 					},
 				)
+				wtData.value.push(wtObj.obj)
 			}
 		}
 	}
@@ -135,77 +138,18 @@ const avgObj = reactive({ //平均cpz等
 	frequency: '',
 	pcratio: ''
 })
-const markDot = reactive({ //3-5 point点等
-	pcl5: 0,
-	pcl10: 0,
-	pcl12: 0,
-	pcl25: 0
-})
 const xAxisData = ref([])
 const chartRef = ref() //chart 的ref
 const seriesData = ref([])
 const isChartArea = ref(false) // 用来控制图表是否区域划分
 const dataSet = ref('')
 const funChartSelect = async (batch) => {
-	const wDataArr = []
-	const yDataArr = []
-	let scatterls = []
-	let scatterhs = []
-	let dataSetObj = []
-	wtData.value = []
-	if (batch?.length && dataSet.value) {
-		scatterls = batch[0].selected[2].dataIndex
-		scatterhs = batch[0].selected[3].dataIndex
-		if (scatterls?.length || scatterhs?.length) {
-			dataSetObj = JSON.parse(dataSet.value)
-			if (scatterls?.length) {
-				for (const scatterIndex of scatterls) {
-					wDataArr.push(dataSetObj[0].source[scatterIndex].k)
-				}
-			}
-			if (scatterhs?.length) {
-				for (const scatterIndex of scatterhs) {
-					yDataArr.push(dataSetObj[1].source[scatterIndex].k)
-				}
-			}
-			const wtRes = await request.get('/power/fitting/filter', { params: { yk: yDataArr.join(','), wk: wDataArr.join(',') } })
-			if (wtRes.code === 200) {
-				let id = 1
-				const tempArr = [] //用于以风机id 聚合dataArr
-				if (wtRes.data?.length) {
-					for (const data of wtRes.data) {
-						if (tempArr.length) {
-							const findIndex = tempArr.findIndex(o => o.wtId === data.wtId)
-							if (findIndex !== -1) {
-								if (!tempArr[findIndex].children) {
-									tempArr[findIndex].children = []
-								}
-								tempArr[findIndex].children.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
-								id++
-							} else {
-								tempArr.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
-								id++
-							}
-						} else {
-							tempArr.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
-							id++
-						}
-					}
-					wtDialog.value = true
-					nextTick(() => {
-						wtTab.value = 'table'
-						wtData.value = tempArr
-					})
-				}
-			}
-		}
-	}
+	return false
 }
 const funChartArea = () => {
 	if (seriesData.value?.length) {
 		// 获取数据后 展示dialog table 数据
 		wtDialog.value = true
-		wtData.value = []
 		if (!isChartArea.value) {
 			// 请求一下
 			seriesData.value[0] = {
@@ -256,7 +200,7 @@ const funChartArea = () => {
 						data: [
 							[
 								{
-									name: `3~5m 偏差率: ${markDot.pcl5}%`,
+									name: `3~5m`,
 									xAxis: 3,
 								},
 								{
@@ -265,7 +209,7 @@ const funChartArea = () => {
 							],
 							[
 								{
-									name: `5~10m 偏差率: ${markDot.pcl10}%`,
+									name: `5~10m`,
 									xAxis: 5,
 								},
 								{
@@ -274,7 +218,7 @@ const funChartArea = () => {
 							],
 							[
 								{
-									name: `10~12m 偏差率: ${markDot.pcl12}%`,
+									name: `10~12m`,
 									xAxis: 10,
 								},
 								{
@@ -283,7 +227,7 @@ const funChartArea = () => {
 							],
 							[
 								{
-									name: `12~25m 偏差率: ${markDot.pcl25}%`,
+									name: `12~25m`,
 									xAxis: 12,
 								},
 								{
@@ -304,22 +248,112 @@ const funChartArea = () => {
 		}
 	}
 }
+const funTimeArea = async () => {
+	if(seriesData.value?.length){
+		//获取数据
+		const res = await request.get('/power/fitting/time',{params: {ids: excelCheckIds.value.join(',')}})
+		console.log(res)
+		if(res.code===200){
+			barxAxis.data = []
+			barSeries.value = [{
+				name: "3~5m功率",
+				type: "bar",
+				stack: 'a',
+				data: [],
+			},{
+				name: "5~10m功率",
+				type: "bar",
+				stack: 'a',
+				data: [],
+			},{
+				name: "10~12m功率",
+				type: "bar",
+				stack: 'a',
+				data: [],
+			},{
+				name: "12~25m全功率",
+				type: "bar",
+				stack: 'a',
+				data: [],
+			},{
+				name: "不运行",
+				type: "bar",
+				stack: 'a',
+				data: [],
+			}]
+			for(const wtObj of res.data){
+				barxAxis.data.push(wtObj.wtId)
+				for(const timeKey in wtObj.time){
+					barSeries.value[timeKey].data.push((wtObj.time[timeKey]/60).toFixed(0))
+				}
+			}
+			tmDialog.value = true
+		}
+	}
+}
 /**dialog 数据 */
 const wtDialog = ref(false)
 const wtData = ref([])
-const wtTab = ref('table')
+/**tmdialog 数据 */
+const tmDialog = ref(false)
+const barxAxis = reactive({
+	type: 'category',
+	data: [],
+	splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	}
+})
+const baryAxis = ref({
+		type: 'value',
+		name: '小时',
+		splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	}
+})
+const barSeries = ref([{
+	name: "3~5m功率",
+	type: "bar",
+	stack: 'a',
+	data: [],
+},{
+	name: "5~10m功率",
+	type: "bar",
+	stack: 'a',
+	data: [],
+},{
+	name: "10~12m功率",
+	type: "bar",
+	stack: 'a',
+	data: [],
+},{
+	name: "12~25m全功率",
+	type: "bar",
+	stack: 'a',
+	data: [],
+},{
+	name: "不运行",
+	type: "bar",
+	stack: 'a',
+	data: [],
+}])
 /**created */
 // funGetTree()
 // funGetProcessTree()
 /**mounted */
 onMounted(() => {
-	tableHeight.value = window.innerHeight - 120 + 'px'
-	excelHeight.value = window.innerHeight - 120 + 'px'
-	treeHeight.value = window.innerHeight - 120 + 'px'
+	tableHeight.value = window.innerHeight - 160 + 'px'
+	excelHeight.value = window.innerHeight - 160 + 'px'
+	treeHeight.value = window.innerHeight - 160 + 'px'
 	window.addEventListener('resize', () => {
-		tableHeight.value = window.innerHeight - 120 + 'px'
-		excelHeight.value = window.innerHeight - 120 + 'px'
-		treeHeight.value = window.innerHeight - 120 + 'px'
+		tableHeight.value = window.innerHeight - 160 + 'px'
+		excelHeight.value = window.innerHeight - 160 + 'px'
+		treeHeight.value = window.innerHeight - 160 + 'px'
 	})
 	/**test */
 	// funExcelChange({
@@ -334,36 +368,39 @@ onActivated(() => {
 })
 </script>
 <template>
-  <div class="bg-white py-[10px] px-[10px]">
+  <div class="bg-white py-[10px] px-[10px] s-dialog-body">
+		<el-dialog draggable width="1000px" v-model="tmDialog" title="时间占比">
+			<bar-chart-cop height="700px" width="100%" :xAxis="barxAxis" :yAxis="baryAxis" :series="barSeries"></bar-chart-cop>
+		</el-dialog>
     <el-dialog draggable v-model="wtDialog" title="曲线偏差率">
 			<el-table :data="wtData" row-key="id" :max-height="550">
-				<el-table-column property="wtId" align="center" label="风机" />
+				<el-table-column property="windturbine" align="center" label="风机" />
 				<el-table-column
-					property="speed"
+					property="pc5ratio"
 					sortable
 					align="center"
 					label="3~5m"
 				/>
 				<el-table-column
-					property="power"
+					property="pc10ratio"
 					sortable
 					align="center"
 					label="5~10m"
 				/>
 				<el-table-column
-					property="rr"
+					property="pc12ratio"
 					sortable
 					align="center"
 					label="10~12m"
 				/>
 				<el-table-column
-					property="filter"
+					property="pc25ratio"
 					sortable
 					align="center"
 					label="12~25m"
 				/>
 				<el-table-column
-					property="filter"
+					property="pcratio"
 					sortable
 					align="center"
 					label="3~25m"
@@ -408,10 +445,15 @@ onActivated(() => {
         <el-col :span="16">
           <div class="px-[10px] shadow rounded-[6px] shadow-blue-500">
             <SubmitBtn
-              class="absolute right-[16px] top-[6px] z-10"
+              class="absolute right-[106px] top-[6px] z-10"
               desc="区域划分"
               @click="funChartArea"
             ></SubmitBtn>
+						<SubmitBtn
+              class="absolute right-[16px] top-[6px] z-10"
+              desc="时间占比"
+              @click="funTimeArea"
+            ></SubmitBtn>
             <div
               :style="{
                 height:
@@ -424,7 +466,7 @@ onActivated(() => {
               <CurrentScatterChart
                 ref="chartRef"
                 width="100%"
-                height="calc( 100% - 20px )"
+                :height="`calc( ${tableHeight} - 40px )`"
                 chartTitle=""
                 :xAxisData="xAxisData"
                 :yAxisData="{ splitLine: { show: false } }"
@@ -440,4 +482,9 @@ onActivated(() => {
       </el-row>
     </div>
   </div>
-</template>
+</template>
+<style scoped>
+.s-dialog-body /deep/ .el-dialog__body{
+	padding: 0px 20px;
+}
+</style>

+ 47 - 30
src/pages/dataAnalysis/rateAnalysis/components/chart.vue

@@ -1,7 +1,7 @@
 <script setup>
 import util from "@tools/util";
-import chartTheme from './../chartTheme.json'
-import { ref, toRaw, computed, onMounted, watch } from 'vue';
+import chartTheme from './../rateAnalysis.json'
+import { ref, toRaw, computed, onMounted, watch, nextTick } from 'vue';
 import * as echarts from 'echarts'
 const chartId = 'chart-' + util.newGUID(); //chartId
 const chartIns = ref(null)  //chart 实例
@@ -33,9 +33,14 @@ const props = defineProps({
 		type: String,
 		required: false
 	},
-	isRadar: {  //是否显示雷达图
+	// 是否为dialog中单表
+	isDiaAlone: {
+		type: Boolean,
+		default: false
+	},
+	// 是否含雷达图
+	isRadar: {
 		type: Boolean,
-		required: false,
 		default: false
 	}
 })
@@ -43,39 +48,42 @@ const props = defineProps({
 /**定义option */
 const option = computed({
 	get() {
+		let radar = null
+		if(props.isRadar && props.xAxis?.data?.length){
+			radar = {
+				radius: '70%',
+				center: ['60%','50%'],
+				indicator: props.xAxis.data.map(o => {
+					return {
+						text: '',
+						max: 1000
+					}
+				}),
+				splitArea: {
+					show: false
+				},
+				splitLine: {
+					show: false
+				}
+			}
+		}
 		return {
 			title: {
 				text: props.title || '',
 				subtext: props.subtext || '',
 				top: 10,
-				left: 30,
+				left: props.isDiaAlone? '22%' : '5%',
 			},
 			angleAxis: props.xAxis || {},
 			radiusAxis: {},
-			radar: props.isRadar?  [  //雷达图设定区域
-				{
-					indicator: props.xAxis.data.map(o => {
-						return {
-							name: o
-						}
-					}) || [],
-					center: ['60%','50%'],
-					radius: '70%',
-					splitLine: {
-						show: false,
-					},
-					splitArea: {
-						show: false
-					}
-				},
-			]: {},
 			polar: {
 				radius: '70%',
 				center: ['60%','50%']
 			},
+			radar: radar,
 			tooltip: {
 				formatter: (params) => {
-					return params.componentSubType==='radar'? `${params.name}` : `${params.seriesName}m<br/>${params.value>1? '频次:'+ params.value: ''}`
+					return params.componentSubType==='radar'? `${params.marker}${params.seriesName}` : `${params.marker}${params.seriesName}m<br/>${params.value>1? '频次:'+ params.value: ''}`
 				},
 				confine: true
 			},
@@ -83,7 +91,7 @@ const option = computed({
 			legend: {
 				show: true,
 				orient: 'vertical',
-				left: 30,
+				left: props.isDiaAlone? '22%' : '5%',
 				itemWidth: 16,
 				itemHeight: 10,
 				textStyle: {
@@ -103,13 +111,22 @@ watch(() => option, (newVal, oldVal) => {
 	}
 }, { deep: true })
 
+watch([() => props.width, () => props.height],(newVal, oldVal) => {
+	if(chartIns.value){
+		const echartIns = toRaw(chartIns.value)
+		nextTick(() => echartIns.resize())
+	}
+})
+
 onMounted(() => {
-	echarts.registerTheme('chartTheme', chartTheme)
-	const echartIns =	echarts.init(document.getElementById(chartId),'chartTheme') 
-	chartIns.value = echartIns
-	echartIns.setOption(option.value)
-	window.addEventListener('resize', () => {
-		echartIns.resize()
+	nextTick(() => {
+		echarts.registerTheme('chartTheme', chartTheme)
+		const echartIns =	echarts.init(document.getElementById(chartId),'chartTheme') 
+		chartIns.value = echartIns
+		echartIns.setOption(option.value)
+		window.addEventListener('resize', () => {
+			echartIns.resize()
+		})
 	})
 })
 </script>

+ 17 - 11
src/pages/dataAnalysis/rateAnalysis/components/lineChart.vue

@@ -1,6 +1,6 @@
 <script setup>
 import util from "@tools/util";
-import chartTheme from './../chartTheme.json'
+import chartTheme from './../rateAnalysis.json'
 import { ref, toRaw, computed, onMounted, watch, nextTick } from 'vue';
 import * as echarts from 'echarts'
 const chartId = 'chart-' + util.newGUID(); //chartId
@@ -66,7 +66,7 @@ const option = computed({
 				text: props.title || '',
 				subtext: props.subtext || '',
 				top: 6,
-				left: 30,
+				left: '5%',
 			},
 			xAxis: props.xAxis || {},
 			yAxis: props.yAxis || {},
@@ -128,14 +128,18 @@ const option = computed({
 })
 watch(() => option, (newVal, oldVal) => {
 	if (chartIns.value) {
-		console.log(newVal)
 		const echartIns = toRaw(chartIns.value)
 		echartIns.setOption(toRaw(newVal.value))
 	}
 }, { deep: true })
+watch([() => props.width, () => props.height],(newVal, oldVal) => {
+	if(chartIns.value){
+		const echartIns = toRaw(chartIns.value)
+		nextTick(() => echartIns.resize())
+	}
+})
 const funBrushChange = (flag) => {
 	const echartIns = toRaw(chartIns.value)
-		console.log(echartIns)
 	echartIns.dispatchAction({
 			type: "takeGlobalCursor",
 			// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
@@ -164,13 +168,15 @@ const funBrushChange = (flag) => {
 watch(() => props.brush, (newVal, oldVal) => funBrushChange(newVal))
 
 onMounted(() => {
-	echarts.registerTheme('chartTheme', chartTheme)
-	const echartIns =	echarts.init(document.getElementById(chartId),'chartTheme') 
-	chartIns.value = echartIns
-	echartIns.setOption(option.value)
-	funBrushChange(props.brush)
-	window.addEventListener('resize', () => {
-		echartIns.resize()
+	nextTick(() => {
+		echarts.registerTheme('chartTheme', chartTheme)
+		const echartIns =	echarts.init(document.getElementById(chartId),'chartTheme') 
+		chartIns.value = echartIns
+		echartIns.setOption(option.value)
+		funBrushChange(props.brush)
+		window.addEventListener('resize', () => {
+			echartIns.resize()
+		})
 	})
 })
 </script>

+ 29 - 23
src/pages/dataAnalysis/rateAnalysis/components/scatterSingleChart.vue

@@ -1,6 +1,6 @@
 <script setup name="scatterSingleChart">
 import util from "@tools/util";
-import chartTheme from './../chartTheme.json'
+import chartTheme from './../rateAnalysis.json'
 import { ref, toRaw, computed, onMounted, watch, nextTick } from 'vue';
 import * as echarts from 'echarts'
 const chartId = 'chart-' + util.newGUID(); //chartId
@@ -49,28 +49,27 @@ const option = computed({
 		return {
 			tooltip: {
 				position: 'top',
-				formatter: function (params) {
-					return (
-						params.value[2] +
-						' commits in ' +
-						params.value[0] +
-						' of ' +
-						params.value[1]
-					);
-				}
+				// formatter: function (params) {
+				// 	return (
+				// 		params.value[2] +
+				// 		' commits in ' +
+				// 		params.value[0] +
+				// 		' of ' +
+				// 		params.value[1]
+				// 	);
+				// }
 			},
 			title: {
 				text: props.title || '',
 				subtext: props.subtext || '',
 				top: 6,
-				left: 30,
+				left: '5%',
 			},
 			grid: {
-				top: 40,
-				left: 2,
-				bottom: 10,
-				right: 20,
-				containLabel: true
+				top: 80,
+				left: 40,
+				right: 40,
+				bottom: 40,
 			},
 			xAxis: props.xAxis || [],
 			//  {
@@ -117,14 +116,21 @@ watch(() => option, (newVal, oldVal) => {
 		echartIns.setOption(toRaw(newVal.value))
 	}
 }, { deep: true })
-
+watch([() => props.width, () => props.height],(newVal, oldVal) => {
+	if(chartIns.value){
+		const echartIns = toRaw(chartIns.value)
+		nextTick(() => echartIns.resize())
+	}
+})
 onMounted(() => {
-	echarts.registerTheme('chartTheme', chartTheme)
-	const echartIns = echarts.init(document.getElementById(chartId), 'chartTheme')
-	chartIns.value = echartIns
-	echartIns.setOption(option.value)
-	window.addEventListener('resize', () => {
-		echartIns.resize()
+	nextTick(() => {
+		echarts.registerTheme('chartTheme', chartTheme)
+		const echartIns = echarts.init(document.getElementById(chartId), 'chartTheme')
+		chartIns.value = echartIns
+		echartIns.setOption(option.value)
+		window.addEventListener('resize', () => {
+			echartIns.resize()
+		})
 	})
 })
 </script>

File diff suppressed because it is too large
+ 137 - 95
src/pages/dataAnalysis/rateAnalysis/index.vue


+ 393 - 0
src/pages/dataAnalysis/rateAnalysis/rateAnalysis.json

@@ -0,0 +1,393 @@
+
+{
+	"color": [
+			"#3fb1e3",
+			"#6be6c1",
+			"#626c91",
+			"#a0a7e6",
+			"#c4ebad",
+			"#96dee8"
+	],
+	"backgroundColor": "rgba(252,252,252,0)",
+	"textStyle": {},
+	"title": {
+			"textStyle": {
+					"color": "#000"
+			},
+			"subtextStyle": {
+					"color": "#000"
+			}
+	},
+	"line": {
+			"itemStyle": {
+					"borderWidth": "2"
+			},
+			"lineStyle": {
+					"width": "2"
+			},
+			"symbolSize": "8",
+			"symbol": "emptyCircle",
+			"smooth": true
+	},
+	"radar": {
+			"itemStyle": {
+					"borderWidth": "2"
+			},
+			"lineStyle": {
+					"width": "2"
+			},
+			"symbolSize": "8",
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"bar": {
+			"itemStyle": {
+					"barBorderWidth": 0,
+					"barBorderColor": "#ccc"
+			}
+	},
+	"pie": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"scatter": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"boxplot": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"parallel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"sankey": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"funnel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"gauge": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"candlestick": {
+			"itemStyle": {
+					"color": "#e6a0d2",
+					"color0": "transparent",
+					"borderColor": "#e6a0d2",
+					"borderColor0": "#3fb1e3",
+					"borderWidth": "2"
+			}
+	},
+	"graph": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			},
+			"lineStyle": {
+					"width": "1",
+					"color": "#cccccc"
+			},
+			"symbolSize": "8",
+			"symbol": "emptyCircle",
+			"smooth": false,
+			"color": [
+					"#3fb1e3",
+					"#6be6c1",
+					"#626c91",
+					"#a0a7e6",
+					"#c4ebad",
+					"#96dee8"
+			],
+			"label": {
+					"color": "#ffffff"
+			}
+	},
+	"map": {
+			"itemStyle": {
+					"areaColor": "#eeeeee",
+					"borderColor": "#aaaaaa",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#ffffff"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "rgba(63,177,227,0.25)",
+							"borderColor": "#3fb1e3",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#3fb1e3"
+					}
+			}
+	},
+	"geo": {
+			"itemStyle": {
+					"areaColor": "#eeeeee",
+					"borderColor": "#aaaaaa",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#ffffff"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "rgba(63,177,227,0.25)",
+							"borderColor": "#3fb1e3",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#3fb1e3"
+					}
+			}
+	},
+	"categoryAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#b3b3b3"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#b3b3b3"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#b3b3b3"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#b3b3b3"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"valueAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#b3b3b3"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#b3b3b3"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#b3b3b3",
+					"fontSize": 10
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#b3b3b3"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"logAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#cccccc"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#999999"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#eeeeee"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"timeAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#cccccc"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#999999"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#eeeeee"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"toolbox": {
+			"iconStyle": {
+					"borderColor": "#999999"
+			},
+			"emphasis": {
+					"iconStyle": {
+							"borderColor": "#666666"
+					}
+			}
+	},
+	"legend": {
+			"textStyle": {
+					"color": "#999999"
+			}
+	},
+	"tooltip": {
+			"axisPointer": {
+					"lineStyle": {
+							"color": "#cccccc",
+							"width": 1
+					},
+					"crossStyle": {
+							"color": "#cccccc",
+							"width": 1
+					}
+			}
+	},
+	"timeline": {
+			"lineStyle": {
+					"color": "#626c91",
+					"width": 1
+			},
+			"itemStyle": {
+					"color": "#626c91",
+					"borderWidth": 1
+			},
+			"controlStyle": {
+					"color": "#626c91",
+					"borderColor": "#626c91",
+					"borderWidth": 0.5
+			},
+			"checkpointStyle": {
+					"color": "#3fb1e3",
+					"borderColor": "#3fb1e3"
+			},
+			"label": {
+					"color": "#626c91"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"color": "#626c91"
+					},
+					"controlStyle": {
+							"color": "#626c91",
+							"borderColor": "#626c91",
+							"borderWidth": 0.5
+					},
+					"label": {
+							"color": "#626c91"
+					}
+			}
+	},
+	"visualMap": {
+			"color": [
+					"#2a99c9",
+					"#afe8ff"
+			]
+	},
+	"dataZoom": {
+			"backgroundColor": "rgba(255,255,255,0)",
+			"dataBackgroundColor": "rgba(222,222,222,1)",
+			"fillerColor": "rgba(114,230,212,0.25)",
+			"handleColor": "#cccccc",
+			"handleSize": "100%",
+			"textStyle": {
+					"color": "#999999"
+			}
+	},
+	"markPoint": {
+			"label": {
+					"color": "#ffffff"
+			},
+			"emphasis": {
+					"label": {
+							"color": "#ffffff"
+					}
+			}
+	}
+}

+ 397 - 0
src/pages/dataAnalysis/tempAnalysis/components/barChart.json

@@ -0,0 +1,397 @@
+
+{
+	"color": [
+			"#db60c8",
+			"#c12e34",
+			"#e6b600d9",
+			"#0098d9",
+			"#465a83",
+			"#005eaa",
+			"#cda819",
+			"#32a487"
+	],
+	"backgroundColor": "rgba(0,0,0,0)",
+	"textStyle": {},
+	"title": {
+			"textStyle": {
+					"color": "#B3B3B3B3B3B3"
+			},
+			"subtextStyle": {
+					"color": "#aaaaaa"
+			}
+	},
+	"line": {
+			"itemStyle": {
+					"borderWidth": 1
+			},
+			"lineStyle": {
+					"width": 2
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"radar": {
+			"itemStyle": {
+					"borderWidth": 1
+			},
+			"lineStyle": {
+					"width": 2
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"bar": {
+			"itemStyle": {
+					"barBorderWidth": 0,
+					"barBorderColor": "#ccc"
+			},
+			"barMaxWidth": 50
+	},
+	"pie": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"scatter": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"boxplot": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"parallel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"sankey": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"funnel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"gauge": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"candlestick": {
+			"itemStyle": {
+					"color": "#c12e34",
+					"color0": "#2b821d",
+					"borderColor": "#c12e34",
+					"borderColor0": "#2b821d",
+					"borderWidth": 1
+			}
+	},
+	"graph": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			},
+			"lineStyle": {
+					"width": 1,
+					"color": "#aaaaaa"
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false,
+			"color": [
+					"#c12e34",
+					"#e6b600",
+					"#0098d9",
+					"#50ec39",
+					"#005eaa",
+					"#339ca8",
+					"#cda819",
+					"#32a487"
+			],
+			"label": {
+					"color": "#eeeeee"
+			}
+	},
+	"map": {
+			"itemStyle": {
+					"areaColor": "#ddd",
+					"borderColor": "#eee",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#c12e34"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "#e6b600",
+							"borderColor": "#ddd",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#c12e34"
+					}
+			}
+	},
+	"geo": {
+			"itemStyle": {
+					"areaColor": "#ddd",
+					"borderColor": "#eee",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#c12e34"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "#e6b600",
+							"borderColor": "#ddd",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#c12e34"
+					}
+			}
+	},
+	"categoryAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#B3B3B3"
+			},
+			"splitLine": {
+					"show": false,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"valueAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#B3B3B3"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"logAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#B3B3B3"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"timeAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#B3B3B3"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#B3B3B3"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"toolbox": {
+			"iconStyle": {
+					"borderColor": "#06467c"
+			},
+			"emphasis": {
+					"iconStyle": {
+							"borderColor": "#4187c2"
+					}
+			}
+	},
+	"legend": {
+			"textStyle": {
+					"color": "#B3B3B3B3B3B3"
+			}
+	},
+	"tooltip": {
+			"axisPointer": {
+					"lineStyle": {
+							"color": "#cccccc",
+							"width": 1
+					},
+					"crossStyle": {
+							"color": "#cccccc",
+							"width": 1
+					}
+			}
+	},
+	"timeline": {
+			"lineStyle": {
+					"color": "#005eaa",
+					"width": 1
+			},
+			"itemStyle": {
+					"color": "#005eaa",
+					"borderWidth": 1
+			},
+			"controlStyle": {
+					"color": "#005eaa",
+					"borderColor": "#005eaa",
+					"borderWidth": 0.5
+			},
+			"checkpointStyle": {
+					"color": "#005eaa",
+					"borderColor": "#316bc2"
+			},
+			"label": {
+					"color": "#005eaa"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"color": "#005eaa"
+					},
+					"controlStyle": {
+							"color": "#005eaa",
+							"borderColor": "#005eaa",
+							"borderWidth": 0.5
+					},
+					"label": {
+							"color": "#005eaa"
+					}
+			}
+	},
+	"visualMap": {
+			"color": [
+					"#1790cf",
+					"#a2d4e6"
+			]
+	},
+	"dataZoom": {
+			"backgroundColor": "rgba(47,69,84,0)",
+			"dataBackgroundColor": "rgba(47,69,84,0.3)",
+			"fillerColor": "rgba(167,183,204,0.4)",
+			"handleColor": "#a7b7cc",
+			"handleSize": "100%",
+			"textStyle": {
+					"color": "#B3B3B3B3B3B3"
+			}
+	},
+	"markPoint": {
+			"label": {
+					"color": "#eeeeee"
+			},
+			"emphasis": {
+					"label": {
+							"color": "#eeeeee"
+					}
+			}
+	}
+}

+ 184 - 0
src/pages/dataAnalysis/tempAnalysis/components/barChart.vue

@@ -0,0 +1,184 @@
+<script setup>
+import util from "@tools/util";
+import chartTheme from './barChart.json'
+import { ref, toRaw, computed, onMounted, watch, nextTick } from 'vue';
+import * as echarts from 'echarts'
+const chartId = 'chart-' + util.newGUID(); //chartId
+const chartIns = ref(null)  //chart 实例
+const emits = defineEmits(['getSelected'])
+const props = defineProps({
+	xAxis: {
+		type: Object,
+		required: true,
+		default: () => ({})
+	},
+	yAxis: {
+		type: Array,
+		required: false
+	},
+	series: {
+		type: Array,
+		required: true
+	},
+	dataset: {
+		type: Array,
+		required: false,
+		default: () => ([])
+	},
+	height: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	width: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	title: {
+		type: String,
+		required: false
+	},
+	subtext: {
+		type: String,
+		required: false
+	},
+	brush: {
+		type: Boolean,
+		required: false,
+		default: false
+	}
+})
+
+/**定义option */
+const option = computed({
+	get() {
+		return {
+			color:[
+				"#FF8700",
+				"#0098d980",
+				"#626c91",
+				"#a0a7e6",
+				"#c4ebad",
+				"#96dee8"
+			],
+			title: {
+				text: props.title || '',
+				subtext: props.subtext || '',
+				top: 6,
+				left: '5%',
+			},
+			xAxis: props.xAxis || {},
+			yAxis: props.yAxis || {},
+			brush: {
+          seriesIndex: [1],
+          yAxisIndex: 0,
+          transformable: true,
+          throttleType: "debounce",
+          throttleDelay: 1000,
+          removeOnClick: true,
+          brushType: props.brush? "polygon" : false,
+          brushMode: "multiple",
+          brushStyle: {
+            borderWidth: 1,
+            borderColor: "#ff2424",
+          },
+        },
+			toolbox:{
+				show: props.brush,
+			},
+			tooltip: {
+				confine: true,
+				trigger: "axis",
+			},
+			dataset: props.dataset || [],
+			series: props.series || [],
+			legend: {
+				right: "120",
+				top: "5",
+				itemWidth: 6,
+			},
+			grid: {
+				top: 80,
+				left: 40,
+				right: 40,
+				bottom: 40,
+			},
+			dataZoom: [
+          {
+            type: "inside", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+          {
+            type: "slider", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+        ],
+		}
+	},
+	set(val) { }
+})
+watch(() => option, (newVal, oldVal) => {
+	if (chartIns.value) {
+		const echartIns = toRaw(chartIns.value)
+		echartIns.setOption(toRaw(newVal.value))
+	}
+}, { deep: true })
+
+watch([() => props.width, () => props.height],(newVal, oldVal) => {
+	if(chartIns.value){
+		const echartIns = toRaw(chartIns.value)
+		nextTick(() => echartIns.resize())
+	}
+})
+const funBrushChange = (flag) => {
+	const echartIns = toRaw(chartIns.value)
+	echartIns.dispatchAction({
+			type: "takeGlobalCursor",
+			// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+			key: "brush",
+			brushOption: {
+				seriesIndex: [1],
+				yAxisIndex: 0,
+				transformable: true,
+				throttleType: "debounce",
+				throttleDelay: 1000,
+				removeOnClick: true,
+				brushType: flag? "polygon" : false,
+				brushMode: "multiple",
+				brushStyle: {
+					borderWidth: 1,
+					color: "rgba(255,36,36,0.2)",
+					borderColor: "#ff2424",
+				},
+			},
+		});
+	echartIns.off("brushSelected");
+	echartIns.on("brushSelected", (params) => {
+		emits("getSelected", params.batch || []);
+	});
+}
+watch(() => props.brush, (newVal, oldVal) => funBrushChange(newVal))
+
+onMounted(() => {
+	nextTick(() => {
+		echarts.registerTheme('chartTheme', chartTheme)
+		const echartIns =	echarts.init(document.getElementById(chartId),'chartTheme') 
+		chartIns.value = echartIns
+		echartIns.setOption(option.value)
+		funBrushChange(props.brush)
+		window.addEventListener('resize', () => {
+			echartIns.resize()
+		})
+	})
+})
+</script>
+<template>
+	<div :id="chartId" :style="{ height: props.height, width: props.width }"></div>
+</template>

+ 185 - 0
src/pages/dataAnalysis/tempAnalysis/components/current-scatter-chart.vue

@@ -0,0 +1,185 @@
+<script setup>
+import util from "@tools/util";
+import chartTheme from './../rateAnalysis.json'
+import { ref, toRaw, computed, onMounted, watch, nextTick } from 'vue';
+import * as echarts from 'echarts'
+const chartId = 'chart-' + util.newGUID(); //chartId
+const chartIns = ref(null)  //chart 实例
+const emits = defineEmits(['getSelected'])
+const props = defineProps({
+	xAxis: {
+		type: Object,
+		required: true,
+		default: () => ({})
+	},
+	yAxis: {
+		type: Array,
+		required: false
+	},
+	series: {
+		type: Array,
+		required: true
+	},
+	dataset: {
+		type: Array,
+		required: false,
+		default: () => ([])
+	},
+	height: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	width: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	title: {
+		type: String,
+		required: false
+	},
+	subtext: {
+		type: String,
+		required: false
+	},
+	brush: {
+		type: Boolean,
+		required: false,
+		default: false
+	}
+})
+
+/**定义option */
+const option = computed({
+	get() {
+		return {
+			color:[
+				"#FF8700",
+				"#0098d980",
+				"#626c91",
+				"#a0a7e6",
+				"#c4ebad",
+				"#96dee8"
+			],
+			title: {
+				text: props.title || '',
+				subtext: props.subtext || '',
+				top: 6,
+				left: '5%',
+			},
+			xAxis: props.xAxis || {},
+			yAxis: props.yAxis || {},
+			brush: {
+          seriesIndex: [1],
+          yAxisIndex: 0,
+          transformable: true,
+          throttleType: "debounce",
+          throttleDelay: 1000,
+          removeOnClick: true,
+          brushType: props.brush? "polygon" : false,
+          brushMode: "multiple",
+          brushStyle: {
+            borderWidth: 1,
+            borderColor: "#ff2424",
+          },
+        },
+			toolbox:{
+				show: props.brush,
+			},
+			tooltip: {
+				confine: true,
+				axisPointer: {
+            type: "cross",
+          },
+			},
+			dataset: props.dataset || [],
+			series: props.series || [],
+			legend: {
+				right: "120",
+				top: "5",
+				itemWidth: 6,
+			},
+			grid: {
+				top: 80,
+				left: 40,
+				right: 40,
+				bottom: 40,
+			},
+			dataZoom: [
+          {
+            type: "inside", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+          {
+            type: "slider", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+        ],
+		}
+	},
+	set(val) { }
+})
+watch(() => option, (newVal, oldVal) => {
+	if (chartIns.value) {
+		const echartIns = toRaw(chartIns.value)
+		echartIns.setOption(toRaw(newVal.value))
+	}
+}, { deep: true })
+watch([() => props.width, () => props.height],(newVal, oldVal) => {
+	if(chartIns.value){
+		const echartIns = toRaw(chartIns.value)
+		nextTick(() => echartIns.resize())
+	}
+})
+const funBrushChange = (flag) => {
+	const echartIns = toRaw(chartIns.value)
+	echartIns.dispatchAction({
+			type: "takeGlobalCursor",
+			// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+			key: "brush",
+			brushOption: {
+				seriesIndex: [1],
+				yAxisIndex: 0,
+				transformable: true,
+				throttleType: "debounce",
+				throttleDelay: 1000,
+				removeOnClick: true,
+				brushType: flag? "polygon" : false,
+				brushMode: "multiple",
+				brushStyle: {
+					borderWidth: 1,
+					color: "rgba(255,36,36,0.2)",
+					borderColor: "#ff2424",
+				},
+			},
+		});
+	echartIns.off("brushSelected");
+	echartIns.on("brushSelected", (params) => {
+		emits("getSelected", params.batch || []);
+	});
+}
+watch(() => props.brush, (newVal, oldVal) => funBrushChange(newVal))
+
+onMounted(() => {
+	nextTick(() => {
+		echarts.registerTheme('chartTheme', chartTheme)
+		const echartIns =	echarts.init(document.getElementById(chartId),'chartTheme') 
+		chartIns.value = echartIns
+		echartIns.setOption(option.value)
+		funBrushChange(props.brush)
+		window.addEventListener('resize', () => {
+			echartIns.resize()
+		})
+	})
+})
+</script>
+<template>
+	<div :id="chartId" :style="{ height: props.height, width: props.width }"></div>
+</template>

+ 185 - 0
src/pages/dataAnalysis/tempAnalysis/components/lineChart.vue

@@ -0,0 +1,185 @@
+<script setup>
+import util from "@tools/util";
+import chartTheme from './../rateAnalysis.json'
+import { ref, toRaw, computed, onMounted, watch, nextTick } from 'vue';
+import * as echarts from 'echarts'
+const chartId = 'chart-' + util.newGUID(); //chartId
+const chartIns = ref(null)  //chart 实例
+const emits = defineEmits(['getSelected'])
+const props = defineProps({
+	xAxis: {
+		type: Object,
+		required: true,
+		default: () => ({})
+	},
+	yAxis: {
+		type: Array,
+		required: false
+	},
+	series: {
+		type: Array,
+		required: true
+	},
+	dataset: {
+		type: Array,
+		required: false,
+		default: () => ([])
+	},
+	height: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	width: {
+		type: String,
+		required: false,
+		default: '500px'
+	},
+	title: {
+		type: String,
+		required: false
+	},
+	subtext: {
+		type: String,
+		required: false
+	},
+	brush: {
+		type: Boolean,
+		required: false,
+		default: false
+	}
+})
+
+/**定义option */
+const option = computed({
+	get() {
+		return {
+			color:[
+				"#FF8700",
+				"#0098d980",
+				"#626c91",
+				"#a0a7e6",
+				"#c4ebad",
+				"#96dee8"
+			],
+			title: {
+				text: props.title || '',
+				subtext: props.subtext || '',
+				top: 6,
+				left: '5%',
+			},
+			xAxis: props.xAxis || {},
+			yAxis: props.yAxis || {},
+			brush: {
+          seriesIndex: [1],
+          yAxisIndex: 0,
+          transformable: true,
+          throttleType: "debounce",
+          throttleDelay: 1000,
+          removeOnClick: true,
+          brushType: props.brush? "polygon" : false,
+          brushMode: "multiple",
+          brushStyle: {
+            borderWidth: 1,
+            borderColor: "#ff2424",
+          },
+        },
+			toolbox:{
+				show: props.brush,
+			},
+			tooltip: {
+				confine: true,
+				axisPointer: {
+            type: "cross",
+          },
+			},
+			dataset: props.dataset || [],
+			series: props.series || [],
+			legend: {
+				right: "120",
+				top: "5",
+				itemWidth: 6,
+			},
+			grid: {
+				top: 80,
+				left: 40,
+				right: 40,
+				bottom: 40,
+			},
+			dataZoom: [
+          {
+            type: "inside", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+          {
+            type: "slider", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+        ],
+		}
+	},
+	set(val) { }
+})
+watch(() => option, (newVal, oldVal) => {
+	if (chartIns.value) {
+		const echartIns = toRaw(chartIns.value)
+		echartIns.setOption(toRaw(newVal.value))
+	}
+}, { deep: true })
+watch([() => props.width, () => props.height],(newVal, oldVal) => {
+	if(chartIns.value){
+		const echartIns = toRaw(chartIns.value)
+		nextTick(() => echartIns.resize())
+	}
+})
+const funBrushChange = (flag) => {
+	const echartIns = toRaw(chartIns.value)
+	echartIns.dispatchAction({
+			type: "takeGlobalCursor",
+			// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+			key: "brush",
+			brushOption: {
+				seriesIndex: [1],
+				yAxisIndex: 0,
+				transformable: true,
+				throttleType: "debounce",
+				throttleDelay: 1000,
+				removeOnClick: true,
+				brushType: flag? "polygon" : false,
+				brushMode: "multiple",
+				brushStyle: {
+					borderWidth: 1,
+					color: "rgba(255,36,36,0.2)",
+					borderColor: "#ff2424",
+				},
+			},
+		});
+	echartIns.off("brushSelected");
+	echartIns.on("brushSelected", (params) => {
+		emits("getSelected", params.batch || []);
+	});
+}
+watch(() => props.brush, (newVal, oldVal) => funBrushChange(newVal))
+
+onMounted(() => {
+	nextTick(() => {
+		echarts.registerTheme('chartTheme', chartTheme)
+		const echartIns =	echarts.init(document.getElementById(chartId),'chartTheme') 
+		chartIns.value = echartIns
+		echartIns.setOption(option.value)
+		funBrushChange(props.brush)
+		window.addEventListener('resize', () => {
+			echartIns.resize()
+		})
+	})
+})
+</script>
+<template>
+	<div :id="chartId" :style="{ height: props.height, width: props.width }"></div>
+</template>

+ 29 - 0
src/pages/dataAnalysis/tempAnalysis/components/search.vue

@@ -0,0 +1,29 @@
+<script setup name="search">
+import SubmitBtn from '@com/SubmitBtn.vue'
+import { onMounted, reactive, ref } from 'vue'
+
+const queryForm = reactive({
+	mode: 0
+})
+/**执行 */
+const emits = defineEmits(['submit'])
+const funSubmit = async () => {
+	emits('submit', queryForm)
+}
+</script>
+<template>
+	<div class="pl-[20px] flex items-center h-[80px] relative">
+		<div class="absolute top-[-7px] left-[20px] text-[#B3B3B3] text-[14px]">操作面板</div>
+		<el-form class="whitespace-nowrap" :inline="true" :model="queryForm">
+			<el-form-item label="合并方式" class="!mb-0">
+				<el-select v-model="queryForm.mode">
+					<el-option :value="0" label="多表单台"></el-option>
+					<el-option :value="1" label="单表多台"></el-option>
+				</el-select>
+			</el-form-item>
+			<el-form-item class="!mb-0">
+				<submit-btn v-prevdbclick:5000="funSubmit" desc="执行"></submit-btn>
+			</el-form-item>
+		</el-form>
+	</div>
+</template>

+ 594 - 0
src/pages/dataAnalysis/tempAnalysis/index.vue

@@ -0,0 +1,594 @@
+<script setup name="rateAnalysis">
+import excelCop from '@/components/excel.vue'
+import treeCop from '@/components/tree.vue'
+import barChartCop from './components/barChart.vue'
+import lineChartCop from './components/lineChart.vue'
+import CurrentScatterChartCop from './components/current-scatter-chart.vue'
+import SubmitBtn from '../../../components/SubmitBtn.vue'
+// import { ElMessage } from 'element-plus';
+import { onMounted, ref, onActivated, shallowRef, reactive, nextTick } from 'vue'
+import request from '@/api/axios.js'
+import tools from '@tools/htmlToPdf.js'
+// import flowerRes from '@/data/flower.json'
+// import lineChartRes from '@/data/lineNew.json'
+/**配置参数 */
+const treeHeight = ref(window.innerHeight - 150 + 'px') //tree高度
+const excelHeight = ref(window.innerHeight - 150 + 'px') //excel高度
+const tableHeight = ref(window.innerHeight - 150 + 'px')
+/**excel 开始 */
+const excelCheckIds = ref([])
+const excelList = ref([])
+//点击excel项时
+const funExcelChange = async (obj) => { 
+	excelCheckIds.value = [obj.id] //当为单选展示风机图表时
+	chartExcelList.value = excelList.value.map(o=> {
+		return {
+			...o,
+			name: o.windturbine
+		}
+	})  // 选中excel当前项时, excel列表赋值给dialog 下拉框
+	queryForm.checkIds = excelList.value.map(o => o.id)
+	checkAll.value = true
+	funSubmit()
+}
+const funExcelCheckChange = ({ checkArr, data }) => {
+	excelCheckIds.value = checkArr
+}
+/**tree 开始 */
+const treeData = ref([])
+const actTreeNode = ref(null)
+const funRepeatMap = (arr) => {
+	return arr.map(o => {
+		if (o.children) {
+			const findIndex = o.children.findIndex(p => !!p.type)
+			if (findIndex !== -1) {
+				o.childs = o.children
+				o.children = []
+				if(!actTreeNode.value){
+					actTreeNode.value = o
+				}
+			}
+		}
+		return {
+			...o,
+			children: o.children?.length ? funRepeatMap(o.children) : []
+		}
+	})
+}
+const funGetTree = async () => {
+	const res = await request.get("/power/process/tree")
+	actTreeNode.value = null
+	excelList.value = []
+	treeData.value = funRepeatMap(res.data)
+	if(actTreeNode.value){
+		funCurrentChange({current: actTreeNode.value, currentNode: null})
+		funExcelChange({id: actTreeNode.value.childs[0].id})
+	}
+}
+const funTreeCheckChange = ({ current, checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys }) => {  //tree change  -> excel change
+	funCurrentChange({ current, currentNode: '' })
+	const checkIds = []
+	if (checkedNodes.length) {
+		for (const node of checkedNodes) {
+			if (node.childs && node.childs.length) {
+				for (const child of node.childs) {
+					checkIds.push(child.id)
+				}
+			}
+		}
+	}
+	excelCheckIds.value = checkIds
+}
+const funCurrentChange = ({ current, currentNode }) => {
+	if (current.childs) {
+		excelList.value = current.childs.map(o => {
+			return {
+				id: o.id,
+				interval: o.interval,
+				path: o.path,
+				prepareid: o.prepareid,
+				station: o.station,
+				time: o.time,
+				type: o.type,
+				windturbine: o.windturbine,
+				name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station + '_').length)
+			}
+		})
+	} else {
+		excelList.value = []
+	}
+}
+/**chart */
+let chartId = 1
+/**submit */
+const funSubmit = async () => {
+	const tempRes = await request.get('/temperature/rated/power', {
+		params: {
+			ids: excelCheckIds.value.join(','),
+		}
+	})
+	const lineRes = await request.get('/wind/deviation/ratio', {
+		params: {
+			ids: excelCheckIds.value.join(','),
+			mode: 0
+		}
+	})
+	// const rosesRes = flowerRes
+	// const lineRes = lineChartRes
+	if (tempRes.code === 200) {
+		if (tempRes.data?.length) {
+			console.log(tempRes.data)
+			// for (const chart of rosesRes.data) {
+			// 	barSeries[0].data = chart.roses?.length ?chart.roses[0]: []
+			// 	chartId++
+			// }
+		}
+	}
+	// if(lineRes.code === 200){
+	// 	if(lineRes.data?.length){
+	// 		lineDataSet.value[0].source = lineRes.data[0].scatter.map(o => {
+	// 			return [o.x+'', o.y]
+	// 		})
+	// 		lineSeries.value = [{
+	// 			name: "对风频次",
+	// 			type: "line",
+	// 			symbol: "line", //设定为实心点
+	// 			symbolSize: 0, //设定实心点的大小
+	// 			smooth: true, //这个是把线变成曲线
+	// 			data: lineRes.data[0].count,
+	// 			yAxisIndex: 1,
+	// 		},
+	// 		{
+	// 			type: 'effectScatter',
+	// 			showEffectOn: "emphasis",
+				
+	// 			rippleEffect: {
+	// 				scale: 1
+	// 			},
+	// 			legendHoverLink: false,
+	// 			name: '数据散点',
+	// 			symbolSize: 5,
+	// 			datasetIndex: 0,
+	// 			encode: {
+	// 				x: 'x',
+	// 				y: 'y'
+	// 			},
+	// 			yAxisIndex: 0,
+	// 		}]
+	// 	}
+	// }
+}
+/**lineChart */
+const linexAxis = ref({
+	type: 'category',
+	data: new Array(101).fill(-50).map((o,index) => Number((o + index).toFixed(1))),
+	splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	}
+})
+const lineyAxis = ref([
+	{
+		type: 'value',
+		name: 'm/s',
+		splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	}
+	},{
+		type: 'value',
+		splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	}
+	}
+])
+const lineSeries = ref([])
+const lineDataSet = ref([
+	{
+		source: []
+	}
+])
+// 圈选散点触发函数
+const funChartSelect = async (batch) => {
+	const wDataArr = []
+	const yDataArr = []
+	let scatterls = []
+	let dataSetObj = []
+	wtData.value = []
+	if (batch?.length && actCopList.value[0]?.dataset) {
+		scatterls = batch[0].selected[1].dataIndex
+		if (scatterls?.length) {
+			dataSetObj = JSON.parse(actCopList.value[0].dataset)
+			if (scatterls?.length) {
+				for (const scatterIndex of scatterls) {
+					wDataArr.push(dataSetObj[0].source[scatterIndex].k)
+				}
+			}
+			const wtRes = await request.get('/power/fitting/filter', { params: { yk: yDataArr.join(','), wk: wDataArr.join(',') } })
+			if (wtRes.code === 200) {
+				let id = 1
+				const tempArr = [] //用于以风机id 聚合dataArr
+				if (wtRes.data?.length) {
+					for (const data of wtRes.data) {
+						if (tempArr.length) {
+							const findIndex = tempArr.findIndex(o => o.wtId === data.wtId)
+							if (findIndex !== -1) {
+								if (!tempArr[findIndex].children) {
+									tempArr[findIndex].children = []
+								}
+								tempArr[findIndex].children.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
+								id++
+							} else {
+								tempArr.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
+								id++
+							}
+						} else {
+							tempArr.push({ ...data, id: id, filter: data.filter === 0 ? '是' : '否' })
+							id++
+						}
+					}
+					wtDialog.value = true
+					nextTick(() => {
+						wtTab.value = 'table'
+						wtData.value = tempArr
+					})
+				}
+			}
+		}
+	}
+}
+/**barChart */
+const barxAxis = reactive({
+	type: 'category',
+	data: ['N','', 'N-E','', 'E','', 'S-E','', 'S','', 'S-W','', 'W','', 'W-N',''],
+	splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	}
+})
+const baryAxis = ref({
+		type: 'value',
+		name: '小时',
+		splitLine: {
+		show: false
+	},
+	axisTick: {
+		show: true
+	}
+})
+const barSeries = reactive([{
+	name: "3~5m功率",
+	type: "bar",
+	stack: 'a',
+	data: [],
+}])
+/**dialog 数据 */
+const wtDialog = ref(false)
+const wtData = ref([])
+const wtTab = ref('table')
+/**dialog */
+const dialog = ref(false)
+const actChartName = ref('')
+const actDiaTitle = ref('')
+const diaPanelRef = ref()
+const exportLoading = ref(false)
+const actCopList = ref([
+	// {
+	// 	xAxis: [],
+	// 	subtext: '',
+	// 	title: '',
+	// 	isRadar: false,
+	// 	series: [],
+	// 	yAxis: [],
+	// 	dataset: []
+	// }
+])
+// 作为actCopList的备份 在actCopList赋值多个时 同时赋值, 在dialog弹出时清空. 作用: 在actCopList变化时, 重新赋值原始数据
+const actCopListBak = ref([]) 
+const checkAll = ref(true)
+const queryForm = reactive({
+	checkIds: []
+})
+const funCheckAll = () => {
+	checkAll.value = !checkAll.value
+	if(checkAll.value){
+		queryForm.checkIds = chartExcelList.value.map(o => o.id)
+	}else{
+		queryForm.checkIds = []
+	}
+}
+const chartExcelList = ref([]) //dialog 下拉项
+const funActCop = (obj, type) => {
+	switch(type){
+		case 'barChartCop':
+			actChartName.value = 'barChartCop'
+			obj.actCop = shallowRef(barChartCop)
+			actDiaTitle.value = '风速风向玫瑰图'
+			break
+		case 'lineChartCop':
+			actChartName.value = 'lineChartCop'
+			obj.actCop = shallowRef(lineChartCop)
+			actDiaTitle.value = '对风偏差分析图'
+			break
+		case 'CurrentScatterChartCop':
+			actChartName.value = 'CurrentScatterChartCop'
+			obj.actCop = shallowRef(CurrentScatterChartCop)
+			actDiaTitle.value = '静态偏航对风分析图'
+			break
+	}
+	obj.isBrush = type === 'lineChartCop' ? true :false
+	obj.id = chartId
+	chartId ++
+	dialog.value = true
+	actCopListBak.value = []
+	nextTick(() => {
+		actCopList.value = [obj]
+	})
+}
+const funDiaSubmit = async () => {
+	let url = ''
+	switch(actChartName.value){
+		case 'barChartCop':
+			url = '/wind/roses'
+			break
+		case 'lineChartCop':
+			url = '/wind/deviation/ratio'
+			break
+		case 'CurrentScatterChartCop':
+			url = '' //暂无接口
+			break
+	}
+	if(url){
+		const res = await request.get(url, {
+			params: {
+				ids: queryForm.checkIds.join(','),
+				mode: 0
+			}
+		})
+		console.log(res)
+		if(res.code===200){
+			actCopList.value = []
+			actCopListBak.value = [] //清空备份
+			if(res.data?.length){
+				for(const chart of res.data){
+
+					if(actChartName.value==='barChartCop'){
+						actCopList.value.push({
+							id: chartId,
+							isBrush: false,
+							actCop: shallowRef(barChartCop),
+							title: chart.wt,
+							subtext: '风速风向玫瑰图',
+							xAxis: {
+								type: 'category',
+								boundaryGap: false,
+								data: ['N','', 'N-E','', 'E','', 'S-E','', 'S','', 'S-W','', 'W','', 'W-N',''],
+								splitLine: {
+									show: true
+								},
+							},
+							series: chart.roses?.length ?chart.roses[0]: []
+						})
+						chartId++
+					}
+					if(actChartName.value === 'lineChartCop'){
+						actCopList.value.push({
+							id: chartId,
+							isBrush: false,
+							actCop: shallowRef(lineChartCop),
+							title: chart.wtId,
+							subtext: '对风偏差分析图',
+							xAxis: {
+								type: 'category',
+								data: new Array(101).fill(-50).map((o,index) => Number((o + index).toFixed(1))),
+								splitLine: {
+									show: false
+								},
+								axisTick: {
+									show: true
+								}
+							},
+							yAxis: [
+								{
+									type: 'value',
+									name: 'm/s',
+									splitLine: {
+									show: false
+								},
+								axisTick: {
+									show: true
+								}
+								},{
+									type: 'value',
+									splitLine: {
+									show: false
+								},
+								axisTick: {
+									show: true
+								}
+								}
+							],
+							dataset: [{
+								source: chart.scatter.map(o => {
+									return [o.x+'', o.y]
+								})
+							}],
+							series: [{
+								name: "对风频次",
+								type: "line",
+								symbol: "line", //设定为实心点
+								symbolSize: 0, //设定实心点的大小
+								smooth: true, //这个是把线变成曲线
+								data: chart.count,
+								yAxisIndex: 1,
+							},
+							{
+								type: 'effectScatter',
+								showEffectOn: "emphasis",
+								
+								rippleEffect: {
+									scale: 1
+								},
+								legendHoverLink: false,
+								name: '数据散点',
+								symbolSize: 5,
+								datasetIndex: 0,
+								encode: {
+									x: 'x',
+									y: 'y'
+								},
+								yAxisIndex: 0,
+							}]
+
+						})
+						chartId++
+					}
+				}
+				actCopListBak.value = actCopList.value
+			}
+		}
+	}
+}
+const funDiaExport = () => {
+	exportLoading.value = true
+	tools.scrollToPDF(diaPanelRef.value, actDiaTitle.value, () => {
+		exportLoading.value = false
+	})
+}
+const funDbClick = (obj) => {
+	if(actCopListBak.value.length > 1){ //判断大于1时, 才有双击放大功能
+		if(actCopList.value.length === 1){
+			actCopList.value = actCopListBak.value
+		}else{
+			actCopList.value = [obj]
+		}
+	}
+}
+/**created */
+// funGetTree()
+/**activated */
+onMounted(() => {
+	//test
+	// funSubmit()
+	//
+	tableHeight.value = window.innerHeight - 150 + 'px'
+	excelHeight.value =(window.innerHeight - 150) + 'px'
+	treeHeight.value = (window.innerHeight - 150) + 'px'
+	window.addEventListener('resize', () => {
+		tableHeight.value = window.innerHeight - 150 + 'px'
+		excelHeight.value = (window.innerHeight - 150) + 'px'
+		treeHeight.value = (window.innerHeight - 150)  + 'px'
+	})
+})
+onActivated(() => {
+	funGetTree()
+})
+</script>
+<template>
+	<div class="bg-white py-[10px] px-[10px] relative s-dialog-body">
+		<!-- <search-cop class="mb-[20px]  shadow rounded-[6px] shadow-blue-500" @submit="funSubmit">
+		</search-cop> -->
+		<el-dialog v-model="wtDialog" draggable title="风机功率点位">
+			<el-tabs v-model="wtTab">
+				<el-tab-pane label="数据" name="table">
+					<el-table :data="wtData" row-key="id" :max-height="550">
+						<el-table-column property="wtId" align="center" label="风机" />
+						<el-table-column property="time" sortable :width="160" align="center" label="时间" />
+						<el-table-column property="speed" sortable align="center" label="风速(m/s)" />
+						<el-table-column property="power" sortable align="center" label="功率(kw)" />
+						<el-table-column property="rr" sortable align="center" label="转速" />
+						<el-table-column property="filter" sortable align="center" label="是否有用点" />
+					</el-table>
+				</el-tab-pane>
+				<el-tab-pane label="故障" name="problem" disabled>
+				</el-tab-pane>
+				<el-tab-pane label="预警" name="warning" disabled>
+				</el-tab-pane>
+			</el-tabs>
+		</el-dialog>
+		<el-dialog draggable width="80%" v-model="dialog" :title="actDiaTitle">
+			<el-form class="whitespace-nowrap" :inline="true" :model="queryForm">
+				<el-form-item label="" class="!mb-0">
+					<el-select v-model="queryForm.checkIds" clearable @clear="checkAll = false" collapse-tags multiple>
+						<el-option label="全选" :class="{'selected': checkAll}" @click="funCheckAll"></el-option>
+						<el-option v-for="item in chartExcelList" :key="item.id" :value="item.id" :label="item.name"></el-option>
+					</el-select>
+				</el-form-item>
+				<el-form-item class="!mb-0">
+					<submit-btn desc="查询" @click="funDiaSubmit"></submit-btn>
+					<submit-btn desc="导出" @click="funDiaExport"></submit-btn>
+				</el-form-item>
+			</el-form>
+			<div v-loading="exportLoading">
+				<div ref="diaPanelRef" class="flex flex-wrap justify-center items-center h-[650px] overflow-y-auto overflow-x-hidden">
+					<component :is="item.actCop" :width="actCopList.length > 1 ? '50%' : '100%'" height="100%" v-for="item in actCopList"
+						:key="item.id" :xAxis="item.xAxis" :subtext="item.subtext" :title="item.title"
+						:series="item.series" :isDiaAlone="(actCopList.length === 1)" @dblclick="funDbClick(item)" :yAxis="item.yAxis" :dataset="item.dataset" :brush="item.isBrush" @getSelected="funChartSelect"></component>
+				</div>
+			</div>
+		</el-dialog>
+		<div class="relative shadow rounded-[6px] shadow-blue-500 px-[10px] pt-[10px] pb-[10px]">
+			<div class="text-[14px] absolute top-[-7px] text-[#B3B3B3] left-[20px]">数据展示</div>
+			<el-row :gutter="10">
+				<el-col :span="5">
+					<tree-cop :data="treeData" @checkChange="funTreeCheckChange" :show-checkbox="false" :height="treeHeight"
+						@currentChange="funCurrentChange" @refresh="funGetTree">
+					</tree-cop>
+				</el-col>
+				<el-col :span="3">
+					<excel-cop :checkIds="excelCheckIds" :showCheckbox="false" :data="excelList" :height="excelHeight"
+						@excelChange="funExcelChange" @checkChange="funExcelCheckChange"></excel-cop>
+				</el-col>
+				<el-col :span="16">
+					<div :style="{ height: tableHeight }"
+						class="flex flex-wrap justify-center items-center overflow-x-hidden overflow-y-auto ">
+						<div class="mb-[10px] mr-[10px] w-[49%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500">
+							<!-- <el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18"
+								@click="funActCop({xAxis:barxAxis, yAxis:baryAxis, series: barSeries}, 'barChartCop')">
+								<ZoomIn />
+							</el-icon> -->
+							<bar-chart-cop width="100%" height="100%" :xAxis="barxAxis" :yAxis="baryAxis" :series="barSeries"></bar-chart-cop>
+						</div>
+						<div class="mb-[10px] w-[49%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500">
+							<!-- <el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18"
+								@click="funActCop({xAxis:barxAxis, yAxis:baryAxis, series: barSeries}, 'barChartCop')">
+								<ZoomIn />
+							</el-icon> -->
+							<bar-chart-cop width="100%" height="100%" :xAxis="barxAxis" :yAxis="baryAxis" :series="barSeries"></bar-chart-cop>
+						</div>
+						<div class="mr-[10px] w-[49%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500" v-if="!!lineSeries.length">
+							<!-- <el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18"
+								@click="funActCop({ xAxis: linexAxis, yAxis: lineyAxis, series: lineSeries, dataset: lineDataSet }, 'lineChartCop')">
+								<ZoomIn />
+							</el-icon> -->
+							<line-chart-cop class="" height="100%" width="100%" :xAxis="linexAxis" :yAxis="lineyAxis"
+								:series="lineSeries" subtext="对风偏差分析图" :dataset="lineDataSet"></line-chart-cop>
+						</div>
+						<div class="w-[49%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500" v-if="!!lineSeries.length">
+							<!-- <el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18"
+								@click="funActCop({ xAxis: xAxisData, yAxis: { splitLine: { show: false } }, series: seriesData, dataSet: dataSet }, 'CurrentScatterChartCop')">
+								<ZoomIn />
+							</el-icon> -->
+							<current-scatter-chart-cop class="" height="100%" width="100%" :xAxis="linexAxis" :yAxis="lineyAxis"
+								:series="lineSeries" subtext="对风偏差分析图" :dataset="lineDataSet"></current-scatter-chart-cop>
+						</div>
+					</div>
+				</el-col>
+			</el-row>
+		</div>
+	</div>
+</template>
+<style scoped>
+.s-dialog-body /deep/ .el-dialog__body{
+	padding: 0px 20px;
+}
+</style>

+ 2 - 2
src/pages/dataAnalysis/rateAnalysis/chartTheme.json

@@ -12,10 +12,10 @@
 	"textStyle": {},
 	"title": {
 			"textStyle": {
-					"color": "#b3b3b3"
+					"color": "#000"
 			},
 			"subtextStyle": {
-					"color": "#b3b3b3"
+					"color": "#000"
 			}
 	},
 	"line": {

+ 14 - 3
src/pages/dataFilter/prepare/components/search.vue

@@ -28,11 +28,21 @@ const funStationChange = (stationId) => {
 	}
 }
 /**风机 */
+const checkAll = ref(true)
 const windList = ref([])
 const funGetWind = async (stationId) => {
 	const res = await request.get("/base/windturbine", {params: { stationId }})
 	windList.value = res.data
 	queryForm.wtIds = res.data.map(o => o.id)
+	checkAll.value = true
+}
+const funCheckAll = () => {
+	checkAll.value = !checkAll.value
+	if(checkAll.value){
+		queryForm.wtIds = windList.value.map(o => o.id)
+	}else{
+		queryForm.wtIds = []
+	}
 }
 /**导出 */
 const emits = defineEmits(['submit'])
@@ -63,14 +73,15 @@ funGetStation()
 <template>
 	<div class="pl-[20px] flex items-center h-[80px] relative">
 		<div class="absolute top-[-7px] left-[20px] text-[#B3B3B3] text-[14px]">操作面板</div>
-		<el-form class="whitespace-nowrap" :inline="true" :model="queryForm">
+		<el-form class="" :inline="true" :model="queryForm">
 			<el-form-item label="场站" class="!mb-0">
 				<el-select v-model="queryForm.station" class="w-[150px]" @change="funStationChange">
 					<el-option v-for="item in stationList" :key="item.id" :label="item.name" :value="item.id"></el-option>
 				</el-select>
 			</el-form-item>
 			<el-form-item label="风机" class="!mb-0">
-				<el-select multiple clearable class="w-[150px]" v-model="queryForm.wtIds" collapse-tags>
+				<el-select multiple clearable class="w-[150px]" v-model="queryForm.wtIds" @clear="checkAll = false" collapse-tags>
+					<el-option label="全选" :class="{'selected': checkAll}" @click="funCheckAll"></el-option>
 					<el-option v-for="item in windList" :key="item.id" :label="item.name" :value="item.id"></el-option>
 				</el-select>
 			</el-form-item>
@@ -80,7 +91,7 @@ funGetStation()
 			<el-form-item label="结束时间" class="!mb-0">
 				<el-date-picker type="date" class="!w-[150px]" v-model="queryForm.et"></el-date-picker>
 			</el-form-item>
-			<el-form-item label="等间隔" class="!mb-0 h-[40px]">
+			<el-form-item label="等间隔" class="!mb-0">
 				<el-radio-group v-model="queryForm.interval">
 					<el-radio :label="1">一秒钟</el-radio>
 					<el-radio :label="2">一分钟</el-radio>

+ 22 - 18
src/pages/dataFilter/prepare/index.vue

@@ -8,9 +8,9 @@ import { onMounted, ref, onActivated } from 'vue'
 import request from '@/api/axios.js'
 import {baseURL, socketURL} from '@/api/axios.js'
 /**配置参数 */
-const treeHeight = ref(window.innerHeight - 200 + 'px') //tree高度
-const excelHeight = ref(window.innerHeight - 200 + 'px') //excel高度
-const tableHeight = ref(window.innerHeight - 200 + 'px')
+const treeHeight = ref(window.innerHeight - 260 + 'px') //tree高度
+const excelHeight = ref(window.innerHeight - 260 + 'px') //excel高度
+const tableHeight = ref(window.innerHeight - 260 + 'px')
 /**excel 开始 */
 const excelList = ref([])
 const funExcelChange = async (obj) => { //点击excel项时
@@ -18,15 +18,19 @@ const funExcelChange = async (obj) => { //点击excel项时
 	tableName.value = obj.name
 	tableLoading.value = true
 	const res = await request.get('/power/prepare/show', { params: { id: obj.id } })
-	tableColumn.value = res.data.title.map(o => {
-		return {
-			prop: o.key,
-			label: o.des,
-			width: o.des==='时间'? 100: 80,
-		}
-	})
-	tableData.value = res.data.data
-	tableLoading.value = false
+	if(res.code === 200){
+		tableColumn.value = res.data.title.map(o => {
+			return {
+				prop: o.key,
+				label: o.des,
+				width: o.des==='时间'? 100: 80,
+			}
+		})
+		tableData.value = res.data.data
+		tableLoading.value = false
+	}else{
+		tableLoading.value = false
+	}
 }
 /**tree 开始 */
 const treeData = ref([])
@@ -111,13 +115,13 @@ const funSubmit = async (params) => {
 funWebSocket()
 /**mounted */
 onMounted(() => {
-	tableHeight.value = window.innerHeight - 200 + 'px'
-	excelHeight.value = window.innerHeight - 200 + 'px'
-	treeHeight.value = window.innerHeight - 200 + 'px'
+	tableHeight.value = window.innerHeight - 260 + 'px'
+	excelHeight.value = window.innerHeight - 260 + 'px'
+	treeHeight.value = window.innerHeight - 260 + 'px'
 	window.addEventListener('resize', () => {
-		tableHeight.value = window.innerHeight - 200 + 'px'
-		excelHeight.value = window.innerHeight - 200 + 'px'
-		treeHeight.value = window.innerHeight - 200 + 'px'
+		tableHeight.value = window.innerHeight - 260 + 'px'
+		excelHeight.value = window.innerHeight - 260 + 'px'
+		treeHeight.value = window.innerHeight - 260 + 'px'
 	})
 })
 /**activated */

+ 22 - 18
src/pages/dataFilter/process/index.vue

@@ -8,9 +8,9 @@ import request from '@/api/axios.js'
 import {baseURL} from '@/api/axios.js'
 import { ElMessage } from 'element-plus'
 /**配置参数 */
-const treeHeight = ref((window.innerHeight - 210) / 2  + 'px') //tree高度
-const excelHeight = ref(window.innerHeight - 200 + 'px') //excel高度
-const tableHeight = ref(window.innerHeight - 200 + 'px')
+const treeHeight = ref((window.innerHeight - 270) / 2  + 'px') //tree高度
+const excelHeight = ref(window.innerHeight - 260 + 'px') //excel高度
+const tableHeight = ref(window.innerHeight - 260 + 'px')
 /**excel 开始 */
 const excelCheckboxShow = ref(false)
 const excelCheckIds = ref([])
@@ -25,15 +25,19 @@ const funExcelChange = async (obj) => { //点击excel项时
 	} else if (obj.type === 'process') {
 		res = await request.get('/power/process/show', { params: { id: obj.id } })
 	}
-	tableColumn.value = res.data.title.map(o => {
-		return {
-			prop: o.key,
-			label: o.des,
-			width: o.des==='时间'? 100: 80,
-		}
-	})
-	tableData.value = res.data.data
-	tableLoading.value = false
+	if(res.code === 200){
+		tableColumn.value = res.data.title.map(o => {
+			return {
+				prop: o.key,
+				label: o.des,
+				width: o.des==='时间'? 100: 80,
+			}
+		})
+		tableData.value = res.data.data
+		tableLoading.value = false
+	}else{
+		tableLoading.value = false
+	}
 }
 const funExcelCheckChange = ({ checkArr, data }) => {   //bug 
 	excelCheckIds.value = checkArr
@@ -157,13 +161,13 @@ const funSubmit = async (query) => {
 // funGetProcessTree()
 /**mounted */
 onMounted(() => {
-	tableHeight.value = window.innerHeight - 200 + 'px'
-	excelHeight.value = window.innerHeight - 200 + 'px'
-	treeHeight.value = (window.innerHeight - 210) / 2 + 'px'
+	tableHeight.value = window.innerHeight - 260 + 'px'
+	excelHeight.value = window.innerHeight - 260 + 'px'
+	treeHeight.value = (window.innerHeight - 270) / 2 + 'px'
 	window.addEventListener('resize', () => {
-		tableHeight.value = window.innerHeight - 200 + 'px'
-		excelHeight.value = window.innerHeight - 200 + 'px'
-		treeHeight.value = (window.innerHeight - 210) / 2  + 'px'
+		tableHeight.value = window.innerHeight - 260 + 'px'
+		excelHeight.value = window.innerHeight - 260 + 'px'
+		treeHeight.value = (window.innerHeight - 270) / 2  + 'px'
 	})
 })
 /**activated */

+ 25 - 1
src/router/index.js

@@ -16,7 +16,7 @@ const routes = [{
             name: 'dataFilter',
             redirect: '/dataFilter/prepare',
             meta: {
-                title: '曲线分析',
+                title: '数据准备',
             },
             component: () =>
                 import(
@@ -98,6 +98,30 @@ const routes = [{
                             '../pages/dataAnalysis/lineAnalysis/index.vue'
                         ),
                 },
+                {
+                    icon: 'el-icon-s-home',
+                    path: '/dataAnalysis/tempAnalysis',
+                    name: 'dataAnalysistempAnalysis',
+                    meta: {
+                        title: '温度曲线分析',
+                    },
+                    component: () =>
+                        import(
+                            '../pages/dataAnalysis/tempAnalysis/index.vue'
+                        ),
+                },
+                {
+                    icon: 'el-icon-s-home',
+                    path: '/dataAnalysis/agcAnalysis',
+                    name: 'dataAnalysisAgcAnalysis',
+                    meta: {
+                        title: '外部曲线分析',
+                    },
+                    component: () =>
+                        import(
+                            '../pages/dataAnalysis/agcAnalysis/index.vue'
+                        ),
+                },
             ]
         },
     ],

+ 53 - 1
src/tools/htmlToPdf.js

@@ -93,7 +93,59 @@ function downloadPDF(ele, pdfName) {
 
 }
 
+const scrollToPDF = (ele, pdfName, call = () => {}) => {
+    let scrollHeight = ele.scrollHeight
+    let offsetHeight = ele.offsetHeight
+    ele.scrollTo(0,0)
+    const pdf = new JsPDF('', 'pt', 'a4');
+    const funRepeat = (y, yCount, callback = () => {}) => {
+        html2canvas(ele, {
+            width: ele.offsetWidth,
+            height: offsetHeight,
+            allowTaint: false,
+            useCORS: true,
+        }).then(canvas => {
+            // 592.28 841.89
+            const ratio = 592.28 / canvas.width  //获取宽度占比
+            const pageHeight = canvas.height * ratio //获取canvas 画到pdf的高度
+            const pageData = canvas.toDataURL('image/jpeg', ratio);
+            let position = pageHeight * yCount //定位
+            let addPos = 0
+            if(position>0){
+                while(position > 841.89){  // top - 分页大小 = 当前元素到当前页顶部距离
+                    position -= 841.89
+                }
+                if(position + pageHeight > 841.89){  // 到顶部距离 + 当前元素高度 > 页面高度 则进行填充下一页
+                    pdf.addPage()
+                    addPos = 0  // 填充下一页后, 设置当前元素填充位置为 新页的top为0
+                }else{
+                    if(position<pageHeight){  //如果剩余position小于一个pageHeight 则addPos等于pageHeight
+                        addPos = pageHeight
+                    }else{
+                        addPos = position
+                    }
+                }
+            }
+            pdf.addImage(pageData, 'JPEG', 0, addPos, 592.28, pageHeight)
+            y += offsetHeight
+            yCount += 1  //循环 数量
+            ele.scrollTo(0, y);
+            if (y < scrollHeight) {
+                funRepeat(y,yCount,callback)
+            } else {
+                callback()
+            }
+        })
+    }
+    funRepeat(0, 0, () => {
+        pdf.save(pdfName)
+        ele.scrollTo(0,0)
+        call()
+    })
+}
+
 
 export default {
-    downloadPDF
+    scrollToPDF, //对滚动元素截图导出pdf
+    downloadPDF //对非滚动元素截图适配pdf
 }

+ 117 - 44
yarn.lock

@@ -37,16 +37,16 @@
     "@babel/helper-validator-identifier" "^7.14.0"
     "to-fast-properties" "^2.0.0"
 
-"@element-plus/icons-vue@^2.0.10":
+"@ctrl/tinycolor@^3.4.1":
+  "integrity" "sha512-tlJpwF40DEQcfR/QF+wNMVyGMaO9FQp6Z1Wahj4Gk3CJQYHwA2xVG7iKDFdW6zuxZY9XWOpGcfNCTsX4McOsOg=="
+  "resolved" "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.5.0.tgz"
+  "version" "3.5.0"
+
+"@element-plus/icons-vue@^2.0.10", "@element-plus/icons-vue@^2.0.6":
   "integrity" "sha512-ygEZ1mwPjcPo/OulhzLE7mtDrQBWI8vZzEWSNB2W/RNCRjoQGwbaK4N8lV4rid7Ts4qvySU3njMN7YCiSlSaTQ=="
   "resolved" "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.0.10.tgz"
   "version" "2.0.10"
 
-"@element-plus/icons@^0.0.11":
-  "integrity" "sha512-iKQXSxXu131Ai+I9Ymtcof9WId7kaXvB1+WRfAfpQCW7UiAMYgdNDqb/u0hgTo2Yq3MwC4MWJnNuTBEpG8r7+A=="
-  "resolved" "https://registry.npmjs.org/@element-plus/icons/-/icons-0.0.11.tgz"
-  "version" "0.0.11"
-
 "@emmetio/abbreviation@^2.2.3":
   "integrity" "sha512-87pltuCPt99aL+y9xS6GPZ+Wmmyhll2WXH73gG/xpGcQ84DRnptBsI2r0BeIQ0EB/SQTOe2ANPqFqj3Rj5FOGA=="
   "resolved" "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.2.3.tgz"
@@ -81,6 +81,18 @@
     "minimatch" "^3.1.2"
     "strip-json-comments" "^3.1.1"
 
+"@floating-ui/core@^1.0.3":
+  "integrity" "sha512-27FDAEVHrAEQI1UV+7FIjZrFK862gBoAG0USoPMU7RoBCmaTDt6bnKVW/J2uPnOPI6TWqiWGtS7RFN+tN/k+vQ=="
+  "resolved" "https://registry.npmjs.org/@floating-ui/core/-/core-1.0.3.tgz"
+  "version" "1.0.3"
+
+"@floating-ui/dom@^1.0.1":
+  "integrity" "sha512-uUm1xYQ0xdmFLhtetKgjK9AtF4INwDVwuJZvpK19ENHg1wYn7T0w9phYyCL5+HEpgJtX4ZYG6HJkDbtd2yP6cg=="
+  "resolved" "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.8.tgz"
+  "version" "1.0.8"
+  dependencies:
+    "@floating-ui/core" "^1.0.3"
+
 "@hapi/hoek@^9.0.0":
   "integrity" "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
   "resolved" "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz"
@@ -152,10 +164,10 @@
   dependencies:
     "pako" "^1.0.10"
 
-"@popperjs/core@^2.4.4":
-  "integrity" "sha1-rep7aVPLs0ZRdmsFSEaOdDxqI1M="
-  "resolved" "https://registry.npm.taobao.org/@popperjs/core/download/@popperjs/core-2.9.2.tgz?cache=0&sync_timestamp=1617290098226&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40popperjs%2Fcore%2Fdownload%2F%40popperjs%2Fcore-2.9.2.tgz"
-  "version" "2.9.2"
+"@popperjs/core@npm:@sxzz/popperjs-es@^2.11.7":
+  "integrity" "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
+  "resolved" "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz"
+  "version" "2.11.7"
 
 "@rollup/pluginutils@^4.1.0":
   "integrity" "sha1-Dcxhx4DjkldVT+t/dyB9zsoTyDg="
@@ -227,6 +239,18 @@
   "resolved" "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz"
   "version" "7.0.11"
 
+"@types/lodash-es@*", "@types/lodash-es@^4.17.6":
+  "integrity" "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg=="
+  "resolved" "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.6.tgz"
+  "version" "4.17.6"
+  dependencies:
+    "@types/lodash" "*"
+
+"@types/lodash@*", "@types/lodash@^4.14.182":
+  "integrity" "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ=="
+  "resolved" "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz"
+  "version" "4.14.191"
+
 "@types/mini-css-extract-plugin@^0.9.1":
   "integrity" "sha1-1L3eUZcyb8oDnUGPS92gPcdNxFE="
   "resolved" "https://registry.nlark.com/@types/mini-css-extract-plugin/download/@types/mini-css-extract-plugin-0.9.1.tgz?cache=0&sync_timestamp=1621241867700&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fmini-css-extract-plugin%2Fdownload%2F%40types%2Fmini-css-extract-plugin-0.9.1.tgz"
@@ -244,6 +268,11 @@
   "resolved" "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz"
   "version" "3.4.0"
 
+"@types/web-bluetooth@^0.0.16":
+  "integrity" "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
+  "resolved" "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz"
+  "version" "0.0.16"
+
 "@types/webpack@*":
   "integrity" "sha1-eN3gYhLwONd+VBFs/mnoiuntLAM="
   "resolved" "https://registry.nlark.com/@types/webpack/download/@types/webpack-5.28.0.tgz?cache=0&sync_timestamp=1621533733988&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fwebpack%2Fdownload%2F%40types%2Fwebpack-5.28.0.tgz"
@@ -487,6 +516,28 @@
   "resolved" "https://registry.npmjs.org/@vue/shared/-/shared-3.2.39.tgz"
   "version" "3.2.39"
 
+"@vueuse/core@^9.1.0":
+  "integrity" "sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A=="
+  "resolved" "https://registry.npmjs.org/@vueuse/core/-/core-9.6.0.tgz"
+  "version" "9.6.0"
+  dependencies:
+    "@types/web-bluetooth" "^0.0.16"
+    "@vueuse/metadata" "9.6.0"
+    "@vueuse/shared" "9.6.0"
+    "vue-demi" "*"
+
+"@vueuse/metadata@9.6.0":
+  "integrity" "sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w=="
+  "resolved" "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.6.0.tgz"
+  "version" "9.6.0"
+
+"@vueuse/shared@9.6.0":
+  "integrity" "sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ=="
+  "resolved" "https://registry.npmjs.org/@vueuse/shared/-/shared-9.6.0.tgz"
+  "version" "9.6.0"
+  dependencies:
+    "vue-demi" "*"
+
 "@webassemblyjs/ast@1.11.0":
   "integrity" "sha1-papnnv3J5RcHpCBxOdpXkgVVlh8="
   "resolved" "https://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.11.0.tgz"
@@ -767,10 +818,10 @@
   "resolved" "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
   "version" "1.0.0"
 
-"async-validator@^3.4.0":
-  "integrity" "sha1-aOhmqWgk6LJpT/eoMcGiXETV5QA="
-  "resolved" "https://registry.nlark.com/async-validator/download/async-validator-3.5.2.tgz"
-  "version" "3.5.2"
+"async-validator@^4.2.5":
+  "integrity" "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
+  "resolved" "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz"
+  "version" "4.2.5"
 
 "asynckit@^0.4.0":
   "integrity" "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
@@ -1192,7 +1243,7 @@
   dependencies:
     "assert-plus" "^1.0.0"
 
-"dayjs@^1.10.7", "dayjs@1.x":
+"dayjs@^1.10.7", "dayjs@^1.11.3":
   "integrity" "sha512-Zj/lPM5hOvQ1Bf7uAvewDaUcsJoI6JmNqmHhHl3nyumwe0XHwt8sWdOVAPACJzCebL8gQCi+K49w7iKWnGwX9g=="
   "resolved" "https://registry.npmjs.org/dayjs/-/dayjs-1.11.4.tgz"
   "version" "1.11.4"
@@ -1319,19 +1370,26 @@
   "resolved" "https://registry.nlark.com/electron-to-chromium/download/electron-to-chromium-1.3.739.tgz?cache=0&sync_timestamp=1621994584976&other_urls=https%3A%2F%2Fregistry.nlark.com%2Felectron-to-chromium%2Fdownload%2Felectron-to-chromium-1.3.739.tgz"
   "version" "1.3.739"
 
-"element-plus@^1.0.2-beta.71":
-  "integrity" "sha512-tlfbRORIav8gJcIpjZI5F6aJIVHIaDuGO6/vKu43lgYq4JS2JPNRTjvrSE2p4f5xLfaFNfOWjCS3sybXLfMg8g=="
-  "resolved" "https://registry.npmjs.org/element-plus/-/element-plus-1.0.2-beta.71.tgz"
-  "version" "1.0.2-beta.71"
-  dependencies:
-    "@element-plus/icons" "^0.0.11"
-    "@popperjs/core" "^2.4.4"
-    "async-validator" "^3.4.0"
-    "dayjs" "1.x"
-    "lodash" "^4.17.20"
-    "mitt" "^2.1.0"
-    "normalize-wheel" "^1.0.1"
-    "resize-observer-polyfill" "^1.5.1"
+"element-plus@^2.2.26":
+  "integrity" "sha512-O/rdY5m9DkclpVg8r3GynyqCunm7MxSR142xSsjrZA77bi7bcwA3SIy6SPEDqHi5R4KqgkGYgKSp4Q4e3irbYg=="
+  "resolved" "https://registry.npmjs.org/element-plus/-/element-plus-2.2.26.tgz"
+  "version" "2.2.26"
+  dependencies:
+    "@ctrl/tinycolor" "^3.4.1"
+    "@element-plus/icons-vue" "^2.0.6"
+    "@floating-ui/dom" "^1.0.1"
+    "@popperjs/core" "npm:@sxzz/popperjs-es@^2.11.7"
+    "@types/lodash" "^4.14.182"
+    "@types/lodash-es" "^4.17.6"
+    "@vueuse/core" "^9.1.0"
+    "async-validator" "^4.2.5"
+    "dayjs" "^1.11.3"
+    "escape-html" "^1.0.3"
+    "lodash" "^4.17.21"
+    "lodash-es" "^4.17.21"
+    "lodash-unified" "^1.0.2"
+    "memoize-one" "^6.0.0"
+    "normalize-wheel-es" "^1.2.0"
 
 "emmet@^2.3.0":
   "integrity" "sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A=="
@@ -1405,6 +1463,11 @@
   "resolved" "https://registry.nlark.com/escalade/download/escalade-3.1.1.tgz"
   "version" "3.1.1"
 
+"escape-html@^1.0.3":
+  "integrity" "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+  "resolved" "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
+  "version" "1.0.3"
+
 "escape-string-regexp@^4.0.0":
   "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
   "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
@@ -2217,12 +2280,22 @@
   dependencies:
     "p-locate" "^5.0.0"
 
+"lodash-es@*", "lodash-es@^4.17.21":
+  "integrity" "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+  "resolved" "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz"
+  "version" "4.17.21"
+
+"lodash-unified@^1.0.2":
+  "integrity" "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ=="
+  "resolved" "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz"
+  "version" "1.0.3"
+
 "lodash.merge@^4.6.2":
   "integrity" "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
   "resolved" "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
   "version" "4.6.2"
 
-"lodash@^4.17.20", "lodash@^4.17.21":
+"lodash@*", "lodash@^4.17.20", "lodash@^4.17.21":
   "integrity" "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw="
   "resolved" "https://registry.nlark.com/lodash/download/lodash-4.17.21.tgz"
   "version" "4.17.21"
@@ -2262,6 +2335,11 @@
   dependencies:
     "sourcemap-codec" "^1.4.8"
 
+"memoize-one@^6.0.0":
+  "integrity" "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+  "resolved" "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz"
+  "version" "6.0.0"
+
 "merge-source-map@^1.1.0":
   "integrity" "sha1-L93n5gIJOfcJBqaPLXrmheTIxkY="
   "resolved" "https://registry.npm.taobao.org/merge-source-map/download/merge-source-map-1.1.0.tgz"
@@ -2318,11 +2396,6 @@
   "resolved" "https://registry.nlark.com/minimist/download/minimist-1.2.5.tgz?cache=0&sync_timestamp=1618847017774&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fminimist%2Fdownload%2Fminimist-1.2.5.tgz"
   "version" "1.2.5"
 
-"mitt@^2.1.0":
-  "integrity" "sha1-90BXfCMXbGIFsSGylzUU6t4bIjA="
-  "resolved" "https://registry.npm.taobao.org/mitt/download/mitt-2.1.0.tgz"
-  "version" "2.1.0"
-
 "moment@^2.29.1":
   "integrity" "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
   "resolved" "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz"
@@ -2381,10 +2454,10 @@
   "resolved" "https://registry.npm.taobao.org/normalize-path/download/normalize-path-3.0.0.tgz"
   "version" "3.0.0"
 
-"normalize-wheel@^1.0.1":
-  "integrity" "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
-  "resolved" "https://registry.npm.taobao.org/normalize-wheel/download/normalize-wheel-1.0.1.tgz"
-  "version" "1.0.1"
+"normalize-wheel-es@^1.2.0":
+  "integrity" "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
+  "resolved" "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz"
+  "version" "1.2.0"
 
 "nwmatcher@>= 1.3.7 < 2.0.0":
   "integrity" "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ=="
@@ -2768,11 +2841,6 @@
     "tunnel-agent" "^0.6.0"
     "uuid" "^3.3.2"
 
-"resize-observer-polyfill@^1.5.1":
-  "integrity" "sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ="
-  "resolved" "https://registry.npm.taobao.org/resize-observer-polyfill/download/resize-observer-polyfill-1.5.1.tgz"
-  "version" "1.5.1"
-
 "resolve-from@^4.0.0":
   "integrity" "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
   "resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
@@ -3441,6 +3509,11 @@
   dependencies:
     "cropperjs" "^1.5.6"
 
+"vue-demi@*":
+  "integrity" "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A=="
+  "resolved" "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz"
+  "version" "0.13.11"
+
 "vue-loader-v16@^16.0.0-beta.5.4":
   "integrity" "sha1-j7z4fcacmXns13etuk6KDn/ZWn4="
   "resolved" "https://registry.npm.taobao.org/vue-loader-v16/download/vue-loader-v16-16.0.0-beta.5.4.tgz"
@@ -3467,7 +3540,7 @@
   dependencies:
     "vscode-vue-languageservice" "^0.27.0"
 
-"vue@^3.0.0", "vue@^3.0.2", "vue@^3.2.0", "vue@^3.2.6", "vue@>=3.0.0", "vue@2 || 3", "vue@3.1.x", "vue@3.2.39":
+"vue@^3.0.0", "vue@^3.0.0-0 || ^2.6.0", "vue@^3.0.2", "vue@^3.2.0", "vue@^3.2.6", "vue@>=3.0.0", "vue@2 || 3", "vue@3.2.39":
   "integrity" "sha512-tRkguhRTw9NmIPXhzk21YFBqXHT2t+6C6wPOgQ50fcFVWnPdetmRqbmySRHznrYjX2E47u0cGlKGcxKZJ38R/g=="
   "resolved" "https://registry.npmjs.org/vue/-/vue-3.2.39.tgz"
   "version" "3.2.39"