瀏覽代碼

first commit

蒋珅 1 年之前
當前提交
f78be6fb8c
共有 100 個文件被更改,包括 47346 次插入0 次删除
  1. 9 0
      .gitignore
  2. 21 0
      LICENSE
  3. 4 0
      README.md
  4. 17 0
      index.html
  5. 二進制
      node_modules.rar
  6. 10257 0
      package-lock.json
  7. 77 0
      package.json
  8. 二進制
      public/favicon.ico
  9. 37 0
      public/static/config/modeConfig.js
  10. 88 0
      src/App.vue
  11. 744 0
      src/api/api.js
  12. 97 0
      src/api/axios.js
  13. 178 0
      src/api/axios2.js
  14. 13 0
      src/api/config.js
  15. 28 0
      src/assets/css/color-dark.css
  16. 4 0
      src/assets/css/icon.css
  17. 169 0
      src/assets/css/main.css
  18. 179 0
      src/assets/excel/Blob.js
  19. 140 0
      src/assets/excel/Export2Excel.js
  20. 46 0
      src/assets/font/iconfont.css
  21. 二進制
      src/assets/font/iconfont.ttf
  22. 二進制
      src/assets/font/iconfont.woff
  23. 二進制
      src/assets/font/iconfont.woff2
  24. 二進制
      src/assets/img/bg.png
  25. 二進制
      src/assets/img/default.jpg
  26. 二進制
      src/assets/img/icon-excel.png
  27. 二進制
      src/assets/img/img.jpg
  28. 二進制
      src/assets/img/login-bg.jpg
  29. 二進制
      src/assets/img/login-wrap-icon.png
  30. 67 0
      src/assets/js/dialogDrag.js
  31. 192 0
      src/components/Header.vue
  32. 70 0
      src/components/Sidebar.vue
  33. 16 0
      src/components/SubmitBtn.vue
  34. 174 0
      src/components/Tags.vue
  35. 172 0
      src/components/chart/bar/horizontal-bar-chart.vue
  36. 267 0
      src/components/chart/bar/hover-bar-chart.vue
  37. 416 0
      src/components/chart/bar/list-bar-chart.vue
  38. 340 0
      src/components/chart/bar/list-bar-chart2.vue
  39. 406 0
      src/components/chart/bar/multiple-bar-chart.vue
  40. 369 0
      src/components/chart/bar/multiple-hover-bar-chart.vue
  41. 204 0
      src/components/chart/bar/percent-bar-2.vue
  42. 199 0
      src/components/chart/bar/percent-bar-3.vue
  43. 211 0
      src/components/chart/bar/percent-bar.vue
  44. 408 0
      src/components/chart/bar/single-bar-chart.vue
  45. 320 0
      src/components/chart/bar/thermometer.vue
  46. 372 0
      src/components/chart/combination/area-bar-chart.vue
  47. 484 0
      src/components/chart/combination/area-line-chart-2.vue
  48. 480 0
      src/components/chart/combination/area-line-chart.vue
  49. 355 0
      src/components/chart/combination/bar-line-chart.vue
  50. 253 0
      src/components/chart/combination/health-bar-line-chart.vue
  51. 437 0
      src/components/chart/combination/multiple-bar-line-chart.vue
  52. 804 0
      src/components/chart/combination/scatter-line-chart.vue
  53. 247 0
      src/components/chart/combination/vertival-bar-line-chart.vue
  54. 301 0
      src/components/chart/line/arrow-dash-line-chart.vue
  55. 304 0
      src/components/chart/line/arrow-line-chart.vue
  56. 317 0
      src/components/chart/line/double-line-chart.vue
  57. 289 0
      src/components/chart/line/double-line-chartold.vue
  58. 481 0
      src/components/chart/line/img-line-chart.vue
  59. 332 0
      src/components/chart/line/marker-line-chart.vue
  60. 265 0
      src/components/chart/line/multi-arrow-line-chart.vue
  61. 470 0
      src/components/chart/line/multiple-line-chart.vue
  62. 550 0
      src/components/chart/line/multiple-y-line-chart-normal.vue
  63. 373 0
      src/components/chart/line/multiple-y-line-chart.vue
  64. 307 0
      src/components/chart/line/normal-line-chart.vue
  65. 391 0
      src/components/chart/line/simple-line-chart.vue
  66. 312 0
      src/components/chart/line/stright-line-chart.vue
  67. 185 0
      src/components/chart/line/table-line-chart.vue
  68. 201 0
      src/components/chart/line/weather-line-chart.vue
  69. 333 0
      src/components/chart/line/zoom-line-chart.vue
  70. 238 0
      src/components/chart/other/Dashboard.vue
  71. 171 0
      src/components/chart/other/Dashboard2.vue
  72. 194 0
      src/components/chart/other/thermometer-chart.vue
  73. 197 0
      src/components/chart/other/thermometer-v-chart.vue
  74. 392 0
      src/components/chart/pie/dash-pie-chart.vue
  75. 248 0
      src/components/chart/pie/dual-pie-chart.vue
  76. 134 0
      src/components/chart/pie/normal-pie-chart.vue
  77. 132 0
      src/components/chart/pie/percent-pie-chart.vue
  78. 291 0
      src/components/chart/pie/radar-pie-chart.vue
  79. 387 0
      src/components/chart/radar/direction-radar-chart.vue
  80. 445 0
      src/components/chart/radar/normal-radar-chart.vue
  81. 409 0
      src/components/chart/radar/radar-chart.vue
  82. 344 0
      src/components/chart/scatter/current-scatter-chart.vue
  83. 462 0
      src/components/chart/scatter/normal-scatter-chart.vue
  84. 44 0
      src/components/excel.vue
  85. 239 0
      src/components/tree.vue
  86. 20 0
      src/components/vpro-materials/basic-container/BasicContainer.vue
  87. 3 0
      src/components/vpro-materials/basic-container/index.js
  88. 3 0
      src/components/vpro-materials/vpro-form/index.js
  89. 1004 0
      src/components/vpro-materials/vpro-form/vProForm.vue
  90. 3 0
      src/components/vpro-materials/vpro-table/index.js
  91. 628 0
      src/components/vpro-materials/vpro-table/vProTable.vue
  92. 471 0
      src/components/warningCom/multiple-y-line-chart-normal.vue
  93. 50 0
      src/components/warningCom/panel3.vue
  94. 288 0
      src/components/warningCom/table3.vue
  95. 10 0
      src/data/areaData.json
  96. 1 0
      src/data/dot.json
  97. 33 0
      src/data/flower.json
  98. 14211 0
      src/data/lineNew.json
  99. 1512 0
      src/data/table.json
  100. 0 0
      src/helper/README.md

+ 9 - 0
.gitignore

@@ -0,0 +1,9 @@
+.DS_Store
+node_modules/
+.vscode
+dist
+dist_electron
+dist.zip
+dist.rar
+yarn.lock
+components.d.ts

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Ryzen
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 4 - 0
README.md

@@ -0,0 +1,4 @@
+# node环境要求 18+
+# 启动 npm run dev
+# 打包 npm run build
+# api地址配置位于 src/api/config.js

+ 17 - 0
index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8" />
+    <link rel="icon" href="/favicon.ico" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>电场数据表</title>
+    <script src="./static/config/modeConfig.js"></script>
+</head>
+
+<body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+</body>
+
+</html>

二進制
node_modules.rar


文件差異過大導致無法顯示
+ 10257 - 0
package-lock.json


+ 77 - 0
package.json

@@ -0,0 +1,77 @@
+{
+  "name": "intelligent-early-warning",
+  "author": "GYEE_ZM",
+  "version": "1.0.0",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "serve": "vite preview"
+  },
+  "dependencies": {
+    "@amap/amap-jsapi-loader": "^1.0.1",
+    "@element-plus/icons-vue": "^2.0.10",
+    "@stomp/stompjs": "^6.1.2",
+    "@vue/runtime-core": "^3.2.33",
+    "@vue/shared": "^3.2.33",
+    "axios": "^0.21.1",
+    "codemirror-editor-vue3": "^2.1.3",
+    "dayjs": "^1.10.7",
+    "default-passive-events": "^2.0.0",
+    "echarts": "^5.2.2",
+    "element-plus": "^2.2.26",
+    "file-saver": "^2.0.5",
+    "html2canvas": "^1.0.0-rc.7",
+    "jsencrypt": "^3.2.1",
+    "json-bigint": "^1.0.0",
+    "jspdf": "^2.3.1",
+    "moment": "^2.29.1",
+    "q": "^1.5.1",
+    "screenfull": "^6.0.0",
+    "sql-formatter": "^2.3.3",
+    "stompjs": "^2.3.3",
+    "vue": "^3.2.6",
+    "vue-cropperjs": "^5.0.0",
+    "vue-loader-v16": "^16.0.0-beta.5.4",
+    "vue-router": "^4.0.8",
+    "vue3-simple-html2pdf": "^0.0.6",
+    "vuex": "~4.0.0",
+    "xlsx": "^0.17.4"
+  },
+  "devDependencies": {
+    "@typescript-eslint/eslint-plugin": "^5.20.0",
+    "@typescript-eslint/parser": "^5.20.0",
+    "@vitejs/plugin-vue": "^1.2.2",
+    "@vue/compiler-sfc": "^3.0.5",
+    "sass": "^1.34.1",
+    "sass-loader": "^12.0.0",
+    "script-loader": "^0.7.2",
+    "typescript": "^4.6.3",
+    "unplugin-vue-components": "^0.22.9",
+    "vite": "^2.3.4",
+    "vite-plugin-style-import": "^0.10.1",
+    "vite-plugin-windicss": "^1.8.8",
+    "vue-tsc": "^0.2.2",
+    "wait-on": "^6.0.0",
+    "windicss": "^3.5.6"
+  },
+  "build": {
+    "appId": "com.my-website.my-app",
+    "productName": "intelligent-early-warning",
+    "copyright": "Copyright  2021 ${author}",
+    "mac": {
+      "category": "public.app-category.utilities"
+    },
+    "nsis": {
+      "oneClick": false,
+      "allowToChangeInstallationDirectory": true
+    },
+    "files": [
+      "dist/**/*",
+      "electron/**/*"
+    ],
+    "directories": {
+      "buildResources": "assets",
+      "output": "dist_electron"
+    }
+  }
+}

二進制
public/favicon.ico


+ 37 - 0
public/static/config/modeConfig.js

@@ -0,0 +1,37 @@
+// 本地联调开关
+const localTest = false;
+
+// 服务器地址
+let baseURL = "/current/" // 正式环境
+
+// websocket 服务器地址
+let websocketUrl = null;
+
+// 3D 地球瓦片路径
+let tilesUrl = null;
+// 3D 地球最大支持放大到多少级
+const tilesMaxLevel = 18;
+
+// 适配器地址
+// const adapterUrl = "http://10.155.32.4:8011/";
+
+// 切换模块时是否提示当前模块名称(用于对内介绍项目时便捷显示模块名称)
+const showModuleName = 0;
+
+// if (localTest) {
+//     baseURL = "http://192.168.10.8:9002/" // 联机调试 
+// } else {
+//     baseURL = "http://10.155.32.14:9002/" // 正式环境
+    
+// }
+
+websocketUrl = (baseURL.replace(/http:\/\/|https:\/\//g, "")) + "gyee-websocket";
+
+window.__MODE__ = {
+    baseURL,
+    websocketUrl,
+    // adapterUrl,
+    tilesUrl,
+    tilesMaxLevel,
+    showModuleName
+};

+ 88 - 0
src/App.vue

@@ -0,0 +1,88 @@
+<template>
+  <router-view />
+</template>
+
+<script lang="ts" setup>
+// import dotList from './data.json'
+const res = {
+  data: {
+    chineseName: "管理员",
+    enabled: 0,
+    id: '715588739656581120',
+    identity: 'admin',
+    userName: 'admin',
+  }
+}
+sessionStorage.setItem("ms_username", res.data.userName);
+sessionStorage.setItem("ms_chinesename", res.data.chineseName);
+sessionStorage.setItem("ms_id", res.data.id);
+sessionStorage.setItem("token", res.token);
+sessionStorage.setItem("identity", res.data.identity);
+// const pointX = 0.01
+// const pointY = 0.1
+// const dotRes = []
+// for (const dotValue of dotList) {
+//   const xPage = Math.floor((dotValue.s) / pointX)
+//   const minX = xPage * pointX
+//   const yPage = Math.floor((dotValue.p) / pointY)
+//   const minY = yPage * pointY
+//   const res = {
+//     s: minX + (pointX / 2),
+//     p: minY + (pointY / 2)
+//   }
+//   if (dotRes.length) {
+//     const findIndex = dotRes.findIndex(o => o.s === res.s && o.p === res.p)
+//     if (findIndex != -1) {
+//       dotRes[findIndex].children.push(dotValue)
+//     } else {
+//       dotRes.push({
+//         ...res,
+//         children: [dotValue]
+//       })
+//     }
+//   } else {
+//     dotRes.push({
+//       ...res,
+//       children: [dotValue]
+//     })
+//   }
+// }
+</script>
+
+<style>
+@import "./assets/css/main.css";
+@import "./assets/css/color-dark.css";
+</style>
+
+<style lang="scss">
+.query {
+  display: flex;
+  font-size: 12px;
+  font-family: Arial, "SourceHanSans", "Microsoft YaHei", sans-serif;
+
+  &.mg-b-8 {
+    margin-bottom: 0.741vh;
+  }
+
+  .query-items {
+    display: flex;
+    flex: 0 0 auto;
+
+    .query-item {
+      display: flex;
+      flex: 0 0 auto;
+      margin: 0 1.4815vh;
+      justify-content: flex-start;
+      align-items: center;
+      flex-wrap: nowrap;
+
+      .lable {
+        flex: 0 0 auto;
+        margin-right: 1.4815vh;
+        line-height: 33px;
+        color: #333;
+      }
+    }
+  }
+}
+</style>

+ 744 - 0
src/api/api.js

@@ -0,0 +1,744 @@
+// import request from './axios.js'
+
+// //获取服务端公钥
+// export const getPublickey = query => {
+//     return request({
+//         url: 'info/publickey',
+//     });
+// }
+// // login
+// export const loginRequest = params => {
+//     return request.post("user/login", params);
+// };
+// //register
+// export const registerRequest = params => {
+//     return request.post("user/registers", params);
+// };
+// // ----------------------------------------user------------------------------------------------
+// export const getUserList = () => {
+//     return request.get(`user/getall`);
+// }
+// export const editRequest = params => {
+//     return request.post("user/edituser", params);
+// };
+// export const deleteUser = data => {
+//     return request.delete(`user/${data}`);
+// }
+// // ----------------------------------------user------------------------------------------------
+
+
+// //获取所有风场
+// export const fetchStationList = () => {
+//     return request({
+//         url: 'info/station',
+//         method: 'get'
+//     });
+// };
+// //获取所有风场光伏
+// export const fetchStationListAll = () => {
+//     return request({
+//         url: 'info/station',
+//         method: 'get'
+//     });
+// };
+// //根据风场id获取所有风机
+// export const fetchWindturbineList = query => {
+//     return request({
+//         url: 'info/windturbine',
+//         method: 'get',
+//         params: {
+//             stationId: query
+//         }
+//     });
+// };
+// // ----------------------------------------安全生产- 报警记录------------------------------------------------
+// //查询历史报警
+// export const alarm_history = (params) => {
+//     return request({
+//         url: `alarm/history/page2`,
+//         params: params
+//     });
+// }
+// //查报警
+// export const alarm_snap = (params) => {
+//     return request({
+//         url: `alarm/snap`,
+//         params: params
+//     });
+// }
+// // ----------------------------------------安全生产- 实时报警------------------------------------------------
+
+// //实时故障 最高级
+// export const alarm_fault_recent = (params) => {
+//     return request({
+//         url: `fault/recent`,
+//         params: params,
+//         showLoading: {
+//             statu: false
+//         }
+//     });
+// }
+// //实时故障 第一次请求
+// export const alarm_fault_top = (params) => {
+//     return request({
+//         url: `fault/snap/top`,
+//         params: params
+//     });
+// }
+// //底下的实时报警 
+// export const alarm_snap_top = (params) => {
+//     return request({
+//         url: `alarm/snap/top`,
+//         params: params,
+//         showLoading: {
+//             statu: false
+//         },
+//         timeout: 1000
+
+//     });
+// }
+
+
+// // ----------------------------------------安全生产- 实时数据查询------------------------------------------------
+
+// // get 实时data
+// export const getAdapterLatest = (stationId, AIlist) => {
+//     return request({
+//         url: `ts/latest?uniformCodes=${AIlist}&thingId=${stationId}&thingType=windturbine`,
+//         baseURL: '/adapter/',
+//         showLoading: {
+//             statu: false,
+//         },
+//         timeout: 1000
+//     });
+// }
+// // get 历史数据
+// export const getAdapterHistory = (stationId, AIpoint, startTs, endTs) => {
+//     return request({
+//         url: `ts/history/raw?uniformCode=${AIpoint}&thingId=${stationId}&thingType=windturbine&startTs=${startTs}&endTs=${endTs}`,
+//         baseURL: '/adapter/'
+//     });
+// }
+// // get 历史数据
+// export const getAdapterHistorysnap = (stationId, AIpoint, startTs, endTs, interval) => {
+//     return request({
+//         url: `ts/history/snap?uniformCode=${AIpoint}&thingId=${stationId}&thingType=windturbine&startTs=${startTs}&endTs=${endTs}&interval=${interval}`,
+//         baseURL: '/adapter/'
+//     });
+// }
+// // 批量导出
+// export const AdapterHistoryExport = (activeAI, activeWT, startTs, endTs) => {
+//     return request({
+//         url: `ts/history/raw?uniformCode=${activeAI}&thingId=${activeWT}&thingType=windturbine&startTs=${startTs}&endTs=${endTs}`,
+//         baseURL: '/adapter/'
+//     });
+// }
+// // ----------------------------------------基础数据- 设备管理------------------------------------------------
+// //查询全部设备型号接口
+// export const device_list = () => {
+//     return request.get(`device/model/list`);
+// }
+// //获取结构tree
+// export function tree(params) {
+//     return request({
+//         url: 'device/structure/tree/windturbine',
+//         method: 'get',
+//     });
+// }
+// //根据结构获取测点
+// export function point(code, pagenum, pagesize) {
+//     return request.get(`device/metrics/page?pagenum=${pagenum}&pagesize=${pagesize}&deviceId=windturbine&structureCode=${code}`);
+// }
+// //测点新增
+// export function metrics(params) {
+//     return request.post(`device/metrics/single`, params);
+// }
+// //测点删除
+// export function delmetrics(params) {
+//     return request.delete(`device/metrics/single/delete/${params}`);
+// }
+// //测点导入
+
+
+// //tree新增 添加一个设备结构节点
+// export function treeAdd(params) {
+//     return request.post(`device/structure`, params);
+// }
+// //tree删除 tree删除一个设备结构节点
+// export function treeDel(params) {
+//     return request.delete(`device/structure/delete/${params}`);
+// }
+
+
+// // 故障模式
+// // get All
+// export const faultmode_windturbine = () => {
+//     return request.get(`device/faultmode/windturbine`);
+// }
+// // 根据 structurecode get
+// export const faultmode_structurecode = params => {
+//     return request.get(`device/faultmode/windturbine/${params}`);
+// }
+// // 根据 id delete
+// export const faultmode_delete = params => {
+//     return request.delete(`device/faultmode/delete/${params}`);
+// }
+
+// // 新增 修改
+// export const faultmode_add_edit = data => {
+//     return request.post(`device/faultmode`, data);
+// }
+
+// // ----------------------------------------end 基础数据- 风机管理------------------------------------------------
+
+
+// // ---------------------------------------- 报警配置- 自定义预警------------------------------------------------
+// export function custombj_fetchTableData(params) {
+//     return request.get(`alertrule2/page/`, {
+//         params: params
+//     });
+// }
+// // 获取机型
+// export function equipmentmodel_list(params) {
+//     return request.get(`windpowerstation?id=${params}`);
+// }
+// // 获取机型new
+// export function getTestingpointDI() {
+//     return request.get(`testingpointDI/model`);
+// }
+// // 获取规则
+// export function alertrule2_list() {
+//     return request.get(`alertrule2/list/`);
+// }
+// //根据structcode获取AI.DI测点
+// export const fetchAIDIPointList = (deviceId, structcode, stationId, windturbineId, pageNum, pageSize) => {
+//     return request({
+//         url: 'info/point',
+//         method: 'get',
+//         params: {
+//             deviceId: deviceId,
+//             structcode: structcode,
+//             stationId: stationId,
+//             windturbineId: windturbineId,
+//             pageNum,
+//             pageSize,
+//         }
+//     });
+// };
+
+// //根据场站编号,风机型号获取AI测点
+// export const fetchAIPointList = (stationId, modelId) => {
+//     return request({
+//         url: 'info/testing_point_ai',
+//         method: 'get',
+//         params: {
+//             stationId: stationId,
+//             modelId: modelId
+//         }
+//     });
+// };
+// //根据场站编号,风机型号获取DI测点
+// export const fetchDIPointList = (stationId, modelId) => {
+//     return request({
+//         url: 'info/testing_point_di',
+//         method: 'get',
+//         params: {
+//             stationId: stationId,
+//             modelId: modelId
+//         }
+//     });
+// };
+// //根据场站编号,风机型号获取DI测点new
+// export const getDIPointList = (minModel) => {
+//     return request({
+//         url: 'testingpointDI/point',
+//         method: 'get',
+//         params: {
+//             minModel
+//         }
+//     });
+// };
+// //根据场站编号,获取电气DI测点
+// export const fetchElectricDIPointList = (stationId) => {
+//     return request({
+//         url: 'info/electrical_point_di',
+//         method: 'get',
+//         params: {
+//             stationId: stationId
+//         }
+//     });
+// };
+// //根据电气测点,获取测点信息
+// export const fetchElectricDIPointByPointId = (pointId) => {
+//     return request({
+//         url: 'info/electrical_point_di/byId',
+//         method: 'get',
+//         params: {
+//             pointId: pointId
+//         }
+//     });
+// };
+
+// //获取风机关联部件列表
+// export const fetchRelatePart = () => {
+//     return request({
+//         url: 'info/windturbine_parts',
+//         method: 'get',
+//     });
+// };
+// //根据风场编号获取电气AI测点
+// export const fetch_electrical_point_ai = (stationId) => {
+//     return request({
+//         url: 'info/electrical_point_ai',
+//         method: 'get',
+//         params: {
+//             stationId: stationId
+//         }
+//     });
+// };
+// //根据风场编号获取电气DI测点
+// export const fetch_electrical_point_di = (stationId) => {
+//     return request({
+//         url: 'info/electrical_point_di',
+//         method: 'get',
+//         params: {
+//             stationId: stationId
+//         }
+//     });
+// };
+// //获取报警类型
+// export const fetchWarningType = () => {
+//     return request({
+//         url: 'info/warning_type',
+//         method: 'get',
+//     });
+// };
+// //获取报警种类
+// export const fetchWarningClassify = () => {
+//     return request({
+//         url: 'info/warning_classify',
+//         method: 'get',
+//     });
+// };
+// export const custombj_batchImport = list => {
+//     return request.post("alertrule2/save-batch", list);
+// };
+// export const custombj_postSave = form => {
+//     return request.post("alertrule2/save", form)
+// };
+
+// //******************************end****************************************//
+
+
+// //******************************升压站报警API************************************//
+
+// export const scadabj_fetchTableData = query => {
+//     return request({
+//         url: 'scadabj/page',
+//         method: 'get',
+//         params: query,
+//         timeout: 20000,
+//     });
+// };
+// export const scadabj_postSave = objData => {
+//     return request.post("scadabj/save", objData);
+// };
+// export const scadabj_batchImport = list => {
+//     return request.post("scadabj/save-batch", list);
+// };
+// //********************************************end********************************//\
+
+// //********************************************报警记录日志********************************//\
+// export const fetchruleventLogs = (pagenum, pagesize, ruleName, ruleType) => {
+//     return request({
+//         url: 'rulevent/page',
+//         method: 'get',
+//         params: {
+//             pagenum,
+//             pagesize,
+//             ruleName,
+//             ruleType
+//         }
+//     });
+// };
+
+// //********************************************end********************************//\
+
+// //******************************风机报警API************************************//
+// export const windturbinebj_fetchTableData = query => {
+//     return request({
+//         url: 'warning2/page',
+//         method: 'get',
+//         params: query,
+//         timeout: 20000,
+//     });
+// };
+// export const windturbinebj_postSave = form => {
+//     return request.post('warning2/save', form);
+// };
+// export const windturbinebj_batchImport = list => {
+//     return request.post("warning2/save-batch", list);
+// };
+
+// export const fetchLeaf = () => {
+//     return request({
+//         url: 'warning2/page',
+//         method: 'get',
+//         params: {
+//             pagenum: 1,
+//             pagesize: 10000,
+//             isLeaf: 0,
+//         }
+//     });
+// };
+
+
+// //根据风机型号获取DI测点统一编码相关数据 testingpointdi2
+// export const getDIPointByModelId = query => {
+//     return request({
+//         url: 'info/testing_point_di',
+//         method: 'get',
+//         params: query
+//     });
+// };
+
+// //******************************end*******************************************// 
+// //******************************预警统计*******************************************//
+// export const statistics_querymap = params => {
+//     return request.get(`alarm/count/querymap2`, { params: params })
+// };
+// export const statistics_querybyname = params => {
+//     return request.get('alarm/count/querybyname2', { params: params })
+// };
+// export const statistics_lineandproject = params => {
+//     return request.get('alarm/count/lineandproject2', { params: params })
+// };
+// //******************************end*******************************************//
+
+// //******************************预警分析*******************************************//
+// export const warning_query_new = params => {
+//     return request.get(`alarm/count/query/new2`, { params: params })
+// };
+// export const warning_detail = params => {
+//     return request({
+//         url: `analysis/detail`,
+//         params: params,
+//         timeout: 60000
+
+//     });
+// };
+// // export const statistics_lineandproject = params => {
+// //     return request.get('alarm/count/lineandproject', { params: params })
+// // };
+
+
+// //******************************end*******************************************//
+
+
+// //*****************************诊断报告*******************************************//
+// export const earlywarnscore_list = params => {
+//     return request.get(`earlywarnscore/list`, { params: params })
+// };
+// export const warning_query_new3 = params => {
+//     return request.get(`alarm/count/query/new3`, { params: params })
+// };
+// //******************************end*******************************************//
+
+// //*****************************故障诊断*******************************************//
+
+// // 获取配置
+// export const getConfig = () => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/serverparam/list`,
+//         timeout: 60000
+//     });
+// };
+
+// // 获取配置详情
+// export const getConfigDetails = params => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/hostparam/${params}`,
+//         timeout: 60000
+//     });
+// };
+
+// // 获取表数组
+// export const getSQLTable = () => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/diagnose/tables`,
+//         timeout: 60000
+//     });
+// };
+
+// // 使用原始数据获取列 
+// export const getColumnsno = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/diagnosepoint/list/`,
+//         params,
+//         timeout: 60000
+//     });
+// };
+
+// // 执行 SQL
+// export const executeSQLno = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/diagnose/data`,
+//         params,
+//         timeout: 60000
+//     });
+// };
+
+// // 获取表格数据 SQL
+// export const executeSQL = (data) => {
+//     return request({
+//         method: "post",
+//         baseURL: '/current/',
+//         url: `api/diagnose/pointdata`,
+//         data,
+//         timeout: 120000
+//     });
+// };
+// export const executeSQLpredict = (data) => {
+//     return request({
+//         method: "post",
+//         baseURL: '/current/',
+//         url: `api/predict/pointdata`,
+//         data,
+//         timeout: 120000
+//     });
+// };
+
+// // 不使用原始数据获取列 
+// export const getColumns = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/diagnose/colmuns`,
+//         params,
+//         timeout: 120000
+//     });
+// };
+
+
+
+// // 开始训练
+// export const train = data => {
+//     return request({
+//         method: "post",
+//         baseURL: '/current/',
+//         url: `api/diagnose/trainfile`,
+//         data,
+//         timeout: 120000
+//     });
+// };
+// export const trainpredict = data => {
+//     return request({
+//         method: "post",
+//         baseURL: '/current/',
+//         url: `api/predict/trainfile`,
+//         data,
+//         timeout: 120000
+//     });
+// };
+
+// // 获取训练进度
+// export const getProgress = () => {
+//     return request({
+//         baseURL: '/current/',
+//         url: `api/diagnose/gettrainInfo`,
+//         timeout: 100000,
+//         showLoading: {
+//             statu: false
+//         }
+//     });
+// };
+
+// // 预测
+// export const forecastData = (data) => {
+//     return request({
+//         method: "post",
+//         baseURL: '/current/',
+//         url: `api/diagnose/forecasts`,
+//         data,
+//         timeout: 120000
+//     });
+// };
+
+// // 获取预测模型
+// export const getModel = () => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/diagnose/getHistory`,
+//         timeout: 120000
+//     });
+// };
+
+// // 获取所有场站
+// export const getstationAll = () => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `basic/station/all`,
+//         timeout: 120000
+//     });
+// };
+
+// // 获取所有风机
+// export const getWindturbineAll = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `basic/windturbine/all`,
+//         params,
+//     });
+// };
+
+// // 保存模型
+// export const updateModel = (data) => {
+//     return request({
+//         method: "post",
+//         baseURL: '/current/',
+//         url: `/api/history/editHistory`,
+//         data,
+//         timeout: 120000
+//     });
+// };
+// export const saveModel = (data) => {
+//     return request({
+//         method: "post",
+//         baseURL: '/current/',
+//         url: `/api/history/addHistory`,
+//         data,
+//         timeout: 120000
+//     });
+// };
+// //******************************end*******************************************//
+
+// //*****************************模型管理*******************************************//
+// // 获取模型历史
+// export const getModelHistoryList = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/history/getHistoryList`,
+//         params
+//     });
+// };
+// // 获取模型详情
+// export const getModeldetail = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/diagnosereport/info`,
+//         params
+//     });
+// };
+// // 删除模型管理
+// export const removeHistoryModel = (params) => {
+//     return request({
+//         method: "post",
+//         baseURL: '/current/',
+//         url: `api/history/removeHistory`,
+//         params
+//     });
+// };
+// //******************************end*******************************************//
+
+// //*****************************实时故障诊断*******************************************//
+
+// // 获取实时故障诊断表格数据
+// export const getInstantDiagnosticTableData = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `case/faultalg/list`,
+//         params,
+//         showLoading: {
+//             statu: false
+//         }
+//     });
+// };
+
+// // 获取故障时的报警信息
+// export const getFaultWarningInfo = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/warning/info`,
+//         params
+//     });
+// };
+
+// // 获取诊断报告数据
+// export const getAllReportMsg = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/diagnosereport/item`,
+//         params
+//     });
+// }
+
+// // 获取故障类型
+// export const getFaultType = () => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `know/fault/type/all`,
+//     });
+// };
+
+// // 确认故障
+// export const confirmFault = (data) => {
+//     return request({
+//         method: "post",
+//         baseURL: '/current/',
+//         url: `case/faultalg/confirm`,
+//         data,
+//         timeout: 120000
+//     });
+// }
+
+// // 获取离线故障诊断表格数据
+// export const getOfflineTableData = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/diagnosefault/offline`,
+//         params
+//     });
+// };
+
+// // 获取离线启用的模型
+// export const getOfflineHistoryList = (params) => {
+//     return request({
+//         method: "get",
+//         baseURL: '/current/',
+//         url: `api/history/getHistoryList`,
+//         params
+//     });
+// };
+
+// // 离线诊断
+// export const offlineDiagnoseFault = (data) => {
+//     return request({
+//         method: "post",
+//         baseURL: '/current/',
+//         url: `/api/diagnosefault/offlinediagnose`,
+//         data,
+//         timeout: 120000
+//     });
+// };
+
+//******************************end*******************************************//

+ 97 - 0
src/api/axios.js

@@ -0,0 +1,97 @@
+
+import axios from 'axios';
+import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
+import { nextTick } from "vue";
+import {baseURL, socketURL} from './config.js';
+import JSONBIG from 'json-bigint';
+// 配置新建一个 axios 实例
+var loading = null;
+const service = axios.create({
+    baseURL: baseURL,
+    timeout: 30000,
+    withCredentials: false,
+    headers: { 'Content-Type': 'application/json' },
+    transformResponse: [
+        function (data) {
+            const json = JSONBIG({
+                storeAsString: true
+            });
+            const res = json.parse(data);
+            return res;
+        }
+    ],
+    showLoading: {
+        statu: true,
+        text: '加载中...'
+    }
+});
+
+// 添加请求拦截器
+service.interceptors.request.use(
+    (config) => {
+        if (config.showLoading.statu) {
+            loading = ElLoading.service({
+                lock: true,
+                text: config.showLoading.text,
+                spinner: 'el-icon-loading',
+                background: 'rgba(0, 0, 0, 0.3)'
+            });
+        }
+        // 在发送请求之前做些什么 token
+        // let token = sessionStorage.getItem('token')
+        // if (token) {
+        //     config.headers.common['token'] = token;
+        // }
+        config.headers.common['Authorization'] = 'Basic cm9vdDp0YW9zZGF0YQ=='
+        return config
+    },
+    (error) => {
+        // 对请求错误做些什么
+        return Promise.reject(error);
+    }
+);
+
+// 添加响应拦截器
+service.interceptors.response.use(
+    (response) => {
+        // 对响应数据做点什么
+        nextTick(async () => {
+            loading && await loading.close()
+        })
+        const res = response.data;
+        console.warn(res);
+        if (response.status === 401 || response.status === 4001 || response.status == 521) {
+            sessionStorage.clear(); // 清除浏览器全部临时缓存
+            window.location.href = '/'; // 去登录页
+            ElMessage.error(res.msg)
+        } else {
+            if(response.status === 200 && res.code &&  res.code !== 200){
+                ElMessage.error(res.msg)
+            }
+            return response.data;
+        }
+    },
+    (error) => {
+        nextTick(async () => {
+            loading && await loading.close()
+        })
+        // 对响应错误做点什么
+        if (error.message.indexOf('timeout') != -1) {
+            // ElMessage.error('网络超时');
+        } else if (error.message == 'Network Error') {
+            // ElMessage.error('网络连接错误');
+
+        } else {
+            if (error.response.data) ElMessage.error(error.response.statusText);
+            // else ElMessage.error('接口路径找不到');
+        }
+        return Promise.reject(error);
+    }
+);
+
+// 导出 axios 实例
+export default service;
+export {
+    baseURL,
+    socketURL
+}

+ 178 - 0
src/api/axios2.js

@@ -0,0 +1,178 @@
+// 引入axios
+import axios from 'axios';
+import BASE from '@tools/basicTool.js';
+
+axios.defaults.withCredentials = true;
+
+/**
+ * 通用请求函数
+ * @param {Object} options 详细配置项,使用方法与所有配置项说明如下:
+
+  this.API.requestData({
+    isMust: true, // 请求是否携带 token ,默认为 true ,可缺省 
+    showLoading: false, // 请求是否显示加载中遮罩层,默认 false ,可缺省
+    method: "GET", // 请求方式,默认为 GET ,可缺省
+    baseURL: "http://192.168.10.23:8082/", // 请求服务器地址 + 端口,可缺省
+    subUrl: "api/repassword", // 请求接口地址,必传项
+    timeout: 3000, // 请求超时时间,默认 3s ,可缺省
+    body: { id: "151", name: "张三" }, // 请求体所携带的 Body ,如果后端要求 Body 传参的话需要携带此参数,且请求方式需为 POST
+    data: { name: "admin", pasword: "123456" }, // 请求所携带参数,默认为空,可缺省
+    success (res) {
+      // 请求成功的回调
+    },
+    fail (error) {
+      // 请求失败的回调
+    }
+  });
+
+ */
+export function requestData(options) {
+  return new Promise((resolve, reject) => {
+
+    if (options.showLoading) {
+      BASE.showLoading();
+    }
+
+    // 包装请求头
+    let headers = options.headers || {
+      'Content-Type': 'application/x-www-form-urlencoded',
+      'Access-Control-Allow-Origin': '*',
+      'Access-Control-Allow-Credentials': 'true'
+    };
+
+    // 请求是否携带 token
+    const isMust = (options.isMust == true || options.isMust == false) ? options.isMust : true;
+    if (isMust) headers.authToken = localStorage.getItem('authToken');
+
+    // 创建请求实例
+    const XHRReq = axios.create({
+      headers,
+      withCredentials: true,
+      crossDomain: true,
+      baseURL: options.baseURL || window.__MODE__.baseURL || '/api/',
+      timeout: options.timeout || 30000, // 请求超时时间 - 3s
+    });
+
+    // 请求拦截器
+    XHRReq.interceptors.request.use((config) => {
+      return config;
+    }, (err) => {
+      return Promise.reject(err);
+    });
+
+    // 统一格式包装请求参数
+    let params = new URLSearchParams();
+    for (let key in (options.data || {})) {
+      params.append(key, options.data[key]);
+    }
+
+    // 发起请求
+    XHRReq({
+      url: options.subUrl,
+      method: options.method || 'GET',
+      params,
+    }).then(response => {
+      if (options.showLoading) {
+        BASE.closeLoading();
+      }
+      if (response.data.code === 2002) { // 用户类请求错误code (账号密码错误、用户锁定、token过期等)
+
+        localStorage.removeItem('authToken');
+        BASE.showMsg({
+          msg: (response.data && response.data.msg) || ("请求出错[" + response.data.code + "]")
+        });
+
+        // window.location.reload();
+        // window.__STATICVUE__.$router.replace('/login');
+
+      } else if (response.data.code === 200 || response.data.length >= 0 || response.data.records) { // 请求成功 code
+
+        options.success && options.success(response.data);
+        resolve(response);
+
+      } else { // 其他code
+        if (options.showLoading) {
+          BASE.closeLoading();
+        }
+        BASE.showMsg({
+          msg: (response.data.msg) || ("请求出错[" + response.data.code + "]")
+        });
+
+      }
+    }).catch(error => {
+
+      if (options.showLoading) {
+        BASE.closeLoading();
+      }
+
+      options.fail && options.fail(error);
+      reject(error);
+
+    });
+  });
+}
+
+
+/**
+ * 原生 axios 请求方法
+ * @param {Object} options 请求配置项,调用方法:
+  this.API.get({
+    showLoading: false, // 请求是否显示加载中遮罩层,默认 false ,可缺省
+    baseURL: "http://192.168.10.23:8082/", // 请求服务器地址 + 端口,可缺省
+    subUrl: "api/repassword", // 请求接口地址,必传项
+    success (res) {
+      // 请求成功的回调
+    },
+  });
+ */
+
+export function requestPost(options) {
+  return new Promise((resolve, reject) => {
+    if (options.showLoading) {
+      BASE.showLoading();
+    }
+    axios({
+      method: options.method || "POST",
+      url: (options.baseURL || window.__MODE__.baseURL) + options.subUrl, 
+      timeout: options.timeout || 30000, // 请求超时时间 - 3s,
+      data: options.data,
+      header: {
+        "Content-Type": "application/json",
+        'Access-Control-Allow-Origin': '*',
+        'Access-Control-Allow-Credentials': 'true'
+      },
+    }).then((response) => {
+      if (options.showLoading) {
+        BASE.closeLoading();
+      }
+      if (response.data.code === 2002) { // 用户类请求错误code (账号密码错误、用户锁定、token过期等)
+  
+        localStorage.removeItem('authToken');
+        BASE.showMsg({
+          msg: (response.data && response.data.msg) || ("请求出错[" + response.data.code + "]")
+        });window.__STATICVUE__.$router.replace('/login');
+  
+      } else if (response.data.code === 200 || response.data.length >= 0 || response.data.records) { // 请求成功 code
+        options.success && options.success(response.data);
+        resolve(response);
+  
+      } else { // 其他code
+        BASE.closeLoading();
+        BASE.showMsg({
+          msg: (response.data && response.data.msg) || ("请求出错[" + response.data.code + "]")
+        });
+      }
+    }).catch(error => {
+      if (options.showLoading) {
+        BASE.closeLoading();
+      }
+      options.fail && options.fail(error);
+      reject(error);
+    });
+  })
+}
+
+export default {
+  requestData,
+  requestPost,
+}

+ 13 - 0
src/api/config.js

@@ -0,0 +1,13 @@
+
+
+const config = {
+    baseURL: 'http://192.168.1.67:8021',
+    // baseURL: 'http://192.168.10.24:8021',
+    baseURL1: 'http://192.168.1.67:8133',
+}
+
+
+export default config;
+
+export const baseURL = config.baseURL
+export const socketURL = config.socketURL

+ 28 - 0
src/assets/css/color-dark.css

@@ -0,0 +1,28 @@
+.header {
+	background-color: #242f42;
+}
+.login-wrap {
+	background: #324157;
+}
+.plugins-tips {
+	background: #eef1f6;
+}
+.plugins-tips a {
+	color: #20a0ff;
+}
+.el-upload--text em {
+	color: #20a0ff;
+}
+.pure-button {
+	background: #20a0ff;
+}
+.tags-li.active {
+	border: 1px solid #409eff;
+	background-color: #409eff;
+}
+.message-title {
+	color: #20a0ff;
+}
+.collapse-btn:hover {
+	background: rgb(40, 52, 70);
+}

+ 4 - 0
src/assets/css/icon.css

@@ -0,0 +1,4 @@
+[class*=' el-icon-lx'],
+[class^='el-icon-lx'] {
+	font-family: lx-iconfont !important;
+}

+ 169 - 0
src/assets/css/main.css

@@ -0,0 +1,169 @@
+* {
+    margin: 0;
+    padding: 0;
+}
+
+html,
+body,
+#app,
+.wrapper {
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+}
+
+body {
+    font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
+}
+
+a {
+    text-decoration: none;
+}
+
+.content-box {
+    position: absolute;
+    left: 250px;
+    right: 0;
+    top: 55px;
+    bottom: 0;
+    padding-bottom: 30px;
+    -webkit-transition: left 0.3s ease-in-out;
+    transition: left 0.3s ease-in-out;
+    background: #f0f0f0;
+}
+
+.content {
+    width: auto;
+    height: 100%;
+    padding: 5px;
+    overflow-y: auto;
+    overflow-x: hidden;
+    box-sizing: border-box;
+}
+
+.content-collapse {
+    left: 65px;
+}
+
+.container {
+    padding: 10px;
+    background: #fff;
+    border: 1px solid #ddd;
+    border-radius: 5px;
+}
+
+.crumbs {
+    margin: 10px 0;
+}
+
+.el-table th {
+    background-color: #f5f7fa !important;
+}
+
+.pagination {
+    margin: 20px 0;
+    text-align: right;
+}
+
+.plugins-tips {
+    padding: 20px 10px;
+    margin-bottom: 20px;
+}
+
+.el-button+.el-tooltip {
+    margin-left: 10px;
+}
+
+.el-table tr:hover {
+    background: #f6faff;
+}
+
+.mgb20 {
+    margin-bottom: 20px;
+}
+
+.move-enter-active,
+.move-leave-active {
+    transition: opacity 0.1s ease;
+}
+
+.move-enter-from,
+.move-leave-to {
+    opacity: 0;
+}
+
+
+/*BaseForm*/
+
+.form-box {
+    width: 600px;
+}
+
+.form-box .line {
+    text-align: center;
+}
+
+.el-time-panel__content::after,
+.el-time-panel__content::before {
+    margin-top: -7px;
+}
+
+.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) {
+    padding-bottom: 0;
+}
+
+
+/*Upload*/
+
+.pure-button {
+    width: 150px;
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+    color: #fff;
+    border-radius: 3px;
+}
+
+.g-core-image-corp-container .info-aside {
+    height: 45px;
+}
+
+
+/*VueEditor*/
+
+.ql-container {
+    min-height: 400px;
+}
+
+.ql-snow .ql-tooltip {
+    transform: translateX(117.5px) translateY(10px) !important;
+}
+
+.editor-btn {
+    margin-top: 20px;
+}
+
+
+/*markdown*/
+
+.v-note-wrapper .v-note-panel {
+    min-height: 500px;
+}
+
+
+/* //滚动条的宽度 */
+
+::-webkit-scrollbar {
+    width: 6px;
+    height: 6px;
+    background-color: #e4e4e4;
+    border-radius: 6px;
+}
+
+
+/* //滚动条的滑块 */
+
+::-webkit-scrollbar-thumb {
+    background-color: #a9aaad;
+    border-radius: 6px;
+}

+ 179 - 0
src/assets/excel/Blob.js

@@ -0,0 +1,179 @@
+/* eslint-disable */
+/* Blob.js
+ * A Blob implementation.
+ * 2014-05-27
+ *
+ * By Eli Grey, http://eligrey.com
+ * By Devin Samarin, https://github.com/eboyjr
+ * License: X11/MIT
+ *   See LICENSE.md
+ */
+
+/*global self, unescape */
+/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
+ plusplus: true */
+
+/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
+
+(function (view) {
+    "use strict";
+
+    view.URL = view.URL || view.webkitURL;
+
+    if (view.Blob && view.URL) {
+        try {
+            new Blob;
+            return;
+        } catch (e) {}
+    }
+
+    // Internally we use a BlobBuilder implementation to base Blob off of
+    // in order to support older browsers that only have BlobBuilder
+    var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
+            var
+                get_class = function(object) {
+                    return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
+                }
+                , FakeBlobBuilder = function BlobBuilder() {
+                    this.data = [];
+                }
+                , FakeBlob = function Blob(data, type, encoding) {
+                    this.data = data;
+                    this.size = data.length;
+                    this.type = type;
+                    this.encoding = encoding;
+                }
+                , FBB_proto = FakeBlobBuilder.prototype
+                , FB_proto = FakeBlob.prototype
+                , FileReaderSync = view.FileReaderSync
+                , FileException = function(type) {
+                    this.code = this[this.name = type];
+                }
+                , file_ex_codes = (
+                    "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
+                    + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
+                ).split(" ")
+                , file_ex_code = file_ex_codes.length
+                , real_URL = view.URL || view.webkitURL || view
+                , real_create_object_URL = real_URL.createObjectURL
+                , real_revoke_object_URL = real_URL.revokeObjectURL
+                , URL = real_URL
+                , btoa = view.btoa
+                , atob = view.atob
+
+                , ArrayBuffer = view.ArrayBuffer
+                , Uint8Array = view.Uint8Array
+                ;
+            FakeBlob.fake = FB_proto.fake = true;
+            while (file_ex_code--) {
+                FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
+            }
+            if (!real_URL.createObjectURL) {
+                URL = view.URL = {};
+            }
+            URL.createObjectURL = function(blob) {
+                var
+                    type = blob.type
+                    , data_URI_header
+                    ;
+                if (type === null) {
+                    type = "application/octet-stream";
+                }
+                if (blob instanceof FakeBlob) {
+                    data_URI_header = "data:" + type;
+                    if (blob.encoding === "base64") {
+                        return data_URI_header + ";base64," + blob.data;
+                    } else if (blob.encoding === "URI") {
+                        return data_URI_header + "," + decodeURIComponent(blob.data);
+                    } if (btoa) {
+                        return data_URI_header + ";base64," + btoa(blob.data);
+                    } else {
+                        return data_URI_header + "," + encodeURIComponent(blob.data);
+                    }
+                } else if (real_create_object_URL) {
+                    return real_create_object_URL.call(real_URL, blob);
+                }
+            };
+            URL.revokeObjectURL = function(object_URL) {
+                if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
+                    real_revoke_object_URL.call(real_URL, object_URL);
+                }
+            };
+            FBB_proto.append = function(data/*, endings*/) {
+                var bb = this.data;
+                // decode data to a binary string
+                if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
+                    var
+                        str = ""
+                        , buf = new Uint8Array(data)
+                        , i = 0
+                        , buf_len = buf.length
+                        ;
+                    for (; i < buf_len; i++) {
+                        str += String.fromCharCode(buf[i]);
+                    }
+                    bb.push(str);
+                } else if (get_class(data) === "Blob" || get_class(data) === "File") {
+                    if (FileReaderSync) {
+                        var fr = new FileReaderSync;
+                        bb.push(fr.readAsBinaryString(data));
+                    } else {
+                        // async FileReader won't work as BlobBuilder is sync
+                        throw new FileException("NOT_READABLE_ERR");
+                    }
+                } else if (data instanceof FakeBlob) {
+                    if (data.encoding === "base64" && atob) {
+                        bb.push(atob(data.data));
+                    } else if (data.encoding === "URI") {
+                        bb.push(decodeURIComponent(data.data));
+                    } else if (data.encoding === "raw") {
+                        bb.push(data.data);
+                    }
+                } else {
+                    if (typeof data !== "string") {
+                        data += ""; // convert unsupported types to strings
+                    }
+                    // decode UTF-16 to binary string
+                    bb.push(unescape(encodeURIComponent(data)));
+                }
+            };
+            FBB_proto.getBlob = function(type) {
+                if (!arguments.length) {
+                    type = null;
+                }
+                return new FakeBlob(this.data.join(""), type, "raw");
+            };
+            FBB_proto.toString = function() {
+                return "[object BlobBuilder]";
+            };
+            FB_proto.slice = function(start, end, type) {
+                var args = arguments.length;
+                if (args < 3) {
+                    type = null;
+                }
+                return new FakeBlob(
+                    this.data.slice(start, args > 1 ? end : this.data.length)
+                    , type
+                    , this.encoding
+                );
+            };
+            FB_proto.toString = function() {
+                return "[object Blob]";
+            };
+            FB_proto.close = function() {
+                this.size = this.data.length = 0;
+            };
+            return FakeBlobBuilder;
+        }(view));
+
+    view.Blob = function Blob(blobParts, options) {
+        var type = options ? (options.type || "") : "";
+        var builder = new BlobBuilder();
+        if (blobParts) {
+            for (var i = 0, len = blobParts.length; i < len; i++) {
+                builder.append(blobParts[i]);
+            }
+        }
+        return builder.getBlob(type);
+    };
+}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));

+ 140 - 0
src/assets/excel/Export2Excel.js

@@ -0,0 +1,140 @@
+/* eslint-disable */
+import ('file-saver');
+import ('./Blob.js');
+import XLSX from 'xlsx';
+
+function generateArray(table) {
+    var out = [];
+    var rows = table.querySelectorAll('tr');
+    var ranges = [];
+    for (var R = 0; R < rows.length; ++R) {
+        var outRow = [];
+        var row = rows[R];
+        var columns = row.querySelectorAll('td');
+        for (var C = 0; C < columns.length; ++C) {
+            var cell = columns[C];
+            var colspan = cell.getAttribute('colspan');
+            var rowspan = cell.getAttribute('rowspan');
+            var cellValue = cell.innerText;
+            if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
+
+            //Skip ranges
+            ranges.forEach(function(range) {
+                if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
+                    for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
+                }
+            });
+
+            //Handle Row Span
+            if (rowspan || colspan) {
+                rowspan = rowspan || 1;
+                colspan = colspan || 1;
+                ranges.push({ s: { r: R, c: outRow.length }, e: { r: R + rowspan - 1, c: outRow.length + colspan - 1 } });
+            };
+
+            //Handle Value
+            outRow.push(cellValue !== "" ? cellValue : null);
+
+            //Handle Colspan
+            if (colspan)
+                for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
+        }
+        out.push(outRow);
+    }
+    return [out, ranges];
+};
+
+function datenum(v, date1904) {
+    if (date1904) v += 1462;
+    var epoch = Date.parse(v);
+    return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
+}
+
+function sheet_from_array_of_arrays(data, opts) {
+    var ws = {};
+    var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } };
+    for (var R = 0; R != data.length; ++R) {
+        for (var C = 0; C != data[R].length; ++C) {
+            if (range.s.r > R) range.s.r = R;
+            if (range.s.c > C) range.s.c = C;
+            if (range.e.r < R) range.e.r = R;
+            if (range.e.c < C) range.e.c = C;
+            var cell = { v: data[R][C] };
+            if (cell.v == null) continue;
+            var cell_ref = XLSX.utils.encode_cell({ c: C, r: R });
+
+            if (typeof cell.v === 'number') cell.t = 'n';
+            else if (typeof cell.v === 'boolean') cell.t = 'b';
+            else if (cell.v instanceof Date) {
+                cell.t = 'n';
+                cell.z = XLSX.SSF._table[14];
+                cell.v = datenum(cell.v);
+            } else cell.t = 's';
+
+            ws[cell_ref] = cell;
+        }
+    }
+    if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
+    return ws;
+}
+
+function Workbook() {
+    if (!(this instanceof Workbook)) return new Workbook();
+    this.SheetNames = [];
+    this.Sheets = {};
+}
+
+function s2ab(s) {
+    var buf = new ArrayBuffer(s.length);
+    var view = new Uint8Array(buf);
+    for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
+    return buf;
+}
+
+export function export_table_to_excel(id) {
+    var theTable = document.getElementById(id);
+    var oo = generateArray(theTable);
+    var ranges = oo[1];
+
+    /* original data */
+    var data = oo[0];
+    var ws_name = "SheetJS";
+
+    var wb = new Workbook(),
+        ws = sheet_from_array_of_arrays(data);
+
+    /* add ranges to worksheet */
+    // ws['!cols'] = ['apple', 'banan'];
+    ws['!merges'] = ranges;
+
+    /* add worksheet to workbook */
+    wb.SheetNames.push(ws_name);
+    wb.Sheets[ws_name] = ws;
+
+    var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' });
+
+    saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), "test.xlsx")
+}
+
+function formatJson(jsonData) {
+}
+export function export_json_to_excel(th, jsonData, defaultTitle) {
+
+    /* original data */
+
+    var data = jsonData;
+    data.unshift(th);
+    var ws_name = "SheetJS";
+
+    var wb = new Workbook(),
+        ws = sheet_from_array_of_arrays(data);
+
+
+    /* add worksheet to workbook */
+    wb.SheetNames.push(ws_name);
+    wb.Sheets[ws_name] = ws;
+
+    var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' });
+    var title = defaultTitle || '列表'
+    saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), title + ".xlsx")
+}

+ 46 - 0
src/assets/font/iconfont.css

@@ -0,0 +1,46 @@
+@font-face {
+    font-family: "iconfont";
+    /* Project id 2906628 */
+    src: url('iconfont.woff2?t=1640660196056') format('woff2'), url('iconfont.woff?t=1640660196056') format('woff'), url('iconfont.ttf?t=1640660196056') format('truetype');
+}
+
+.iconfont {
+    font-family: "iconfont" !important;
+    font-size: 16px;
+    margin-left: 4px;
+    font-style: normal;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+}
+
+.iconIOTtubiao_huabanfuben:before {
+    content: "\e61a";
+}
+
+.iconzidingyi:before {
+    content: "\e61e";
+}
+
+.iconxitongcaidan:before {
+    content: "\e696";
+}
+
+.iconnibianqi:before {
+    content: "\e72c";
+}
+
+.iconbaojingpeizhi:before {
+    content: "\e67d";
+}
+
+.iconguzhangzhenduan:before {
+    content: "\e601";
+}
+
+.iconfengji:before {
+    content: "\e606";
+}
+
+.iconjichushuju:before {
+    content: "\e7d3";
+}

二進制
src/assets/font/iconfont.ttf


二進制
src/assets/font/iconfont.woff


二進制
src/assets/font/iconfont.woff2


二進制
src/assets/img/bg.png


二進制
src/assets/img/default.jpg


二進制
src/assets/img/icon-excel.png


二進制
src/assets/img/img.jpg


二進制
src/assets/img/login-bg.jpg


二進制
src/assets/img/login-wrap-icon.png


+ 67 - 0
src/assets/js/dialogDrag.js

@@ -0,0 +1,67 @@
+const dialogDrag = (app) => {
+    app.directive('dialogdrag', {
+        // 渲染完毕
+        mounted(el) {
+            // 可视窗口的宽度
+            const clientWidth = document.documentElement.clientWidth
+                // 可视窗口的高度
+            const clientHeight = document.documentElement.clientHeight
+                // 记录坐标
+            let domset = {
+                x: clientWidth / 4, // 默认width 50%
+                y: clientHeight * 15 / 100 // 根据 15vh 计算
+            }
+
+            // 弹窗的容器
+            const domDrag = el.firstElementChild.firstElementChild
+                // 重新设置上、左距离
+            domDrag.style.marginTop = domset.y + 'px'
+            domDrag.style.marginLeft = domset.x + 'px'
+
+            // 记录拖拽开始的光标坐标,0 表示没有拖拽
+            let start = { x: 0, y: 0 }
+                // 移动中记录偏移量
+            let move = { x: 0, y: 0 }
+
+            // 鼠标按下,开始拖拽
+            document.onmousedown = (e) => {
+                // 判断对话框是否重新打开
+                if (domDrag.style.marginTop === '15vh') {
+                    // 重新打开,设置 domset.y  top
+                    domset.y = clientHeight * 15 / 100
+                }
+                start.x = e.clientX
+                start.y = e.clientY
+                domDrag.style.cursor = 'move' // 改变光标形状
+            }
+
+            // 鼠标移动,实时跟踪
+            document.onmousemove = (e) => {
+                    if (start.x === 0) { // 不是拖拽状态
+                        return
+                    }
+                    move.x = e.clientX - start.x
+                    move.y = e.clientY - start.y
+
+                    // 初始位置 + 拖拽距离
+                    domDrag.style.marginLeft = (domset.x + move.x) + 'px'
+                    domDrag.style.marginTop = (domset.y + move.y) + 'px'
+                }
+                // 鼠标抬起,结束拖拽
+            document.onmouseup = (e) => {
+                move.x = e.clientX - start.x
+                move.y = e.clientY - start.y
+
+                // 记录新坐标,作为下次拖拽的初始位置
+                domset.x += move.x
+                domset.y += move.y
+                domDrag.style.cursor = '' // 恢复光标形状
+                domDrag.style.marginLeft = domset.x + 'px'
+                domDrag.style.marginTop = domset.y + 'px'
+                    // 结束拖拽
+                start.x = 0
+            }
+        }
+    })
+}
+export default dialogDrag

+ 192 - 0
src/components/Header.vue

@@ -0,0 +1,192 @@
+<template>
+  <div class="header">
+    <!-- 折叠按钮 -->
+    <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>
+    <div class="header-right">
+      <div class="header-user-con">
+        <div class="user-name">
+    
+          <span class="el-dropdown-link">
+            所有风场总发电量:日发电量  :    {{zdlmap.rfdl}}     万KWh
+
+          </span>
+           <span class="el-dropdown-link">
+            月发电量 :      {{zdlmap.yfdl}}     万KWh
+
+          </span>
+           <span class="el-dropdown-link">
+            年发电量 :   {{zdlmap.nfdl}}    万KWh  
+
+          </span>
+        </div>
+        <!-- <el-dropdown class="user-name" trigger="click" @command="handleCommand">
+          <span class="el-dropdown-link">
+            {{ username }}
+            <i class="el-icon-caret-bottom"></i>
+          </span>
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item command="editpassword"
+                >修改密码</el-dropdown-item
+              >
+              <el-dropdown-item command="loginout">退出登录</el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown> -->
+        <!-- <i
+          class="el-icon-full-screen"
+          style="margin-left: 30px"
+          @click="toggleFullScreen"
+        ></i> -->
+        <span class="nb">
+           <el-button type="primary"><a href="http://10.155.32.4:8070/zhfx/#/others">返回</a></el-button>
+        </span>
+      </div>
+    </div>
+  </div>
+ 
+</template>
+
+<script setup >
+import { ElMessage } from "element-plus";
+import { onMounted,computed, ref, onActivated, reactive } from "vue";
+import request from "@/api/axios.js";
+import { useStore } from "vuex";
+import { baseURL, socketURL } from "@/api/axios.js";
+const store = useStore();
+
+
+const zdlmap=ref({})
+const nbhh = async () => {
+  const res = await request.get("/meterinfoAll?id=-1",);
+  console.log('头',res);
+  zdlmap.value={
+     rfdl:res.data.zdlmap.rfdl.toFixed(2),
+     yfdl:res.data.zdlmap.yfdl.toFixed(2),
+     nfdl:res.data.zdlmap.nfdl.toFixed(2)
+  }
+};
+
+const collapse = computed(() => store.state.collapse);
+// 侧边栏折叠
+const collapseChage = () => {
+  // console.log('123');
+  // store.commit("hadndleCollapse", true);
+  store.commit("hadndleCollapse", !collapse.value);
+};
+// 全屏
+const toggleFullScreen = () => {
+  if (screenfull.isEnabled) {
+    screenfull.toggle();
+  }
+};
+const timerId=setInterval(() => {
+  nbhh();
+  console.log("刷新");
+}, 3600000);
+
+onMounted(() => {
+ 
+  if (document.body.clientWidth < 1500) {
+    store.commit("hadndleCollapse", true);
+  }
+   nbhh()
+  
+});
+</script>
+<style scoped>
+.header {
+  position: relative;
+  box-sizing: border-box;
+  width: 100%;
+  height: 55px;
+  font-size: 22px;
+  color: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+.collapse-btn {
+  float: left;
+  padding: 0 21px;
+  cursor: pointer;
+  line-height: 70px;
+}
+.header .logo {
+  float: left;
+  width: 250px;
+  line-height: 70px;
+}
+.header-right {
+  float: right;
+  padding-right: 30px;
+   align-items: center;
+   width: 100%;
+}
+.nb{
+ 
+  margin-left: 600px;
+}
+.header-user-con {
+  display: flex;
+  height: 70px;
+  align-items: center;
+}
+.btn-fullscreen {
+  transform: rotate(45deg);
+  margin-right: 5px;
+  font-size: 24px;
+}
+.btn-bell,
+.btn-fullscreen {
+  position: relative;
+  width: 30px;
+  height: 30px;
+  text-align: center;
+  border-radius: 15px;
+  cursor: pointer;
+}
+.btn-bell-badge {
+  position: absolute;
+  right: 0;
+  top: -2px;
+  width: 8px;
+  height: 8px;
+  border-radius: 4px;
+  background: #f56c6c;
+  color: #fff;
+}
+.btn-bell .el-icon-bell {
+  color: #fff;
+}
+.user-name {
+  margin-left: 10px;
+}
+.user-avator {
+  margin-left: 20px;
+  margin-right: 10px;
+}
+.user-avator img {
+  display: block;
+  width: 40px;
+  height: 40px;
+  border-radius: 50%;
+ 
+}
+.el-dropdown-link {
+  color: #fff;
+  font-size: 16px;
+  margin-left: 50px;
+}
+.el-dropdown-menu__item {
+  text-align: center;
+}
+</style>

+ 70 - 0
src/components/Sidebar.vue

@@ -0,0 +1,70 @@
+<template>
+  <div class="sidebar">
+    <el-menu
+      class="sidebar-el-menu"
+      :default-active="onRoutes"
+      :collapse="collapse"
+      background-color="#324157"
+      text-color="#bfcbd9"
+      active-text-color="#20a0ff"
+      unique-opened
+      router
+    >
+      <template v-for="item in router.options.routes[1].children">
+        <template v-if="item.children">
+          <el-sub-menu :index="item.path" :key="item.name"  v-if="item.isshow == identity || !item.isshow">
+            <template #title>
+              <i :class="item.icon" style="margin-right:10px"></i>
+              
+              <span>{{ item.meta.title }}</span>
+            </template>
+            <template v-for="subItem in item.children" :key="subItem.name">
+              <el-menu-item :index="subItem.path">
+                {{ subItem.meta.title }}
+              </el-menu-item>
+            </template>
+          </el-sub-menu>
+        </template>
+        <template v-else >
+          <el-menu-item :index="item.path" :key="item.path"  v-if="item.isshow == identity || !item.isshow">
+            <i :class="item.icon" style="margin-right:10px"></i>
+            <template #title>{{ item.meta.title }}</template>
+          </el-menu-item>
+        </template>
+      </template>
+    </el-menu>
+  </div>
+</template>
+
+<script setup>
+import { computed } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { useStore } from "vuex";
+const identity = sessionStorage.getItem("identity")
+
+const route = useRoute();
+const store = useStore();
+const router = useRouter();
+let onRoutes = computed(() => route.path.replace("/", ""));
+let collapse = computed(() => store.state.collapse);
+</script>
+
+<style scoped>
+.sidebar {
+  display: block;
+  position: absolute;
+  left: 0;
+  top: 55px;
+  bottom: 0;
+  overflow-y: scroll;
+}
+.sidebar::-webkit-scrollbar {
+  width: 0;
+}
+.sidebar-el-menu:not(.el-menu--collapse) {
+  width: 250px;
+}
+.sidebar > ul {
+  height: 100%;
+}
+</style>

+ 16 - 0
src/components/SubmitBtn.vue

@@ -0,0 +1,16 @@
+<script setup name="SubmitBtn">
+const props = defineProps({
+	desc: {
+		type: String,
+		default: ''
+	},
+	type: {
+		type: String,
+		default: 'primary'
+	}
+})
+</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 :type="type">{{props.desc}}</el-button>
+</template>

+ 174 - 0
src/components/Tags.vue

@@ -0,0 +1,174 @@
+<template>
+	<div class="tags" v-if="showTags">
+		<ul>
+			<li
+				class="tags-li"
+				v-for="(item, index) in tagsList"
+				:class="{ active: isActive(item.path) }"
+				:key="index"
+			>
+				<router-link :to="item.path" class="tags-li-title">{{
+					item.title
+				}}</router-link>
+				<span class="tags-li-icon" @click="closeTags(index)">x
+					<i class="el-icon-close"></i>
+				</span>
+			</li>
+		</ul>
+		<div class="tags-close-box">
+			<el-dropdown @command="handleTags">
+				<el-button size="mini" type="primary">
+					标签操作
+					<i class="el-icon-arrow-down el-icon--right"></i>
+				</el-button>
+				<template #dropdown>
+					<el-dropdown-menu size="small">
+						<el-dropdown-item command="other">关闭其他</el-dropdown-item>
+						<el-dropdown-item command="all">关闭所有</el-dropdown-item>
+					</el-dropdown-menu>
+				</template>
+			</el-dropdown>
+		</div>
+	</div>
+</template>
+
+<script setup>
+import { computed, onMounted, watch } from 'vue'
+import { useRouter, useRoute } from 'vue-router'
+import { useStore } from 'vuex'
+const router = useRouter()
+const route = useRoute()
+const store = useStore()
+
+let tagsList = computed(() => store.state.tagsList)
+let showTags = computed(() => tagsList.value.length > 0)
+
+const isActive = path => {
+	return path === route.fullPath
+}
+
+// 关闭单个标签
+const closeTags = index => {
+	const delItem = tagsList.value[index]
+	store.commit('delTagsItem', { index })
+	const item = tagsList.value[index] ? tagsList.value[index] : tagsList.value[index - 1]
+	if (item) {
+		delItem.path === route.fullPath && router.push(item.path)
+	} else {
+		router.push('/')
+	}
+}
+
+// 关闭全部标签
+const closeAll = () => {
+	store.commit('clearTags')
+	router.push('/')
+}
+
+// 关闭其他标签
+const closeOther = () => {
+	const curItem = tagsList.value.filter(item => item.path === route.fullPath)
+	store.commit('closeTagsOther', curItem)
+}
+
+// 设置标签
+const setTags = route => {
+	const isExist = tagsList.value.some(item => item.path === route.fullPath)
+	console.warn(isExist);
+	if (!isExist) {
+		if (tagsList.value.length >= 8) {
+			store.commit('delTagsItem', { index: 0 })
+		}
+		store.commit('setTagsItem', {
+			name: route.name,
+			title: route.meta.title,
+			path: route.fullPath,
+		})
+	}
+}
+const handleTags = command => {
+	command === 'other' ? closeOther() : closeAll()
+}
+
+onMounted(() => {
+	setTags(route)
+})
+
+watch(
+	() => route.path,
+	(newValue, oldValue) => {
+		setTags(route)
+	}
+)
+</script>
+
+<style>
+.tags {
+	position: relative;
+	height: 40px;
+	overflow: hidden;
+	background: #fff;
+	padding-right: 120px;
+	box-shadow: 0 5px 10px #ddd;
+}
+
+.tags ul {
+	box-sizing: border-box;
+	width: 100%;
+	height: 100%;
+}
+
+.tags-li {
+	float: left;
+	margin: 7px 0 0 7px;
+	border-radius: 3px;
+	font-size: 12px;
+	overflow: hidden;
+	cursor: pointer;
+	height: 23px;
+	line-height: 23px;
+	border: 1px solid #e9eaec;
+	background: #fff;
+	padding: 0 5px 0 12px;
+	vertical-align: middle;
+	color: #666;
+	-webkit-transition: all 0.3s ease-in;
+	-moz-transition: all 0.3s ease-in;
+	transition: all 0.3s ease-in;
+}
+
+.tags-li:not(.active):hover {
+	background: #f8f8f8;
+}
+
+.tags-li.active {
+	color: #fff;
+}
+
+.tags-li-title {
+	float: left;
+	/* max-width: 80px; */
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	margin-right: 5px;
+	color: #666;
+}
+
+.tags-li.active .tags-li-title {
+	color: #fff;
+}
+
+.tags-close-box {
+	position: absolute;
+	right: 3px;
+	top: 0;
+	box-sizing: border-box;
+	padding-top: 7px;
+	text-align: center;
+	width: 110px;
+	height: 23px;
+	background: #fff;
+	z-index: 10;
+}
+</style>

+ 172 - 0
src/components/chart/bar/horizontal-bar-chart.vue

@@ -0,0 +1,172 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "800px",
+    },
+    // 传入数据
+    data: {
+      type: Object,
+      default: () => {
+        return {
+          area: ["新荣区", "平城区", "云冈区", "云州区", "阳高县", "天镇县", "广灵县", "浑源县", "左云县"],
+          legend: ["因病", "因残", "因学", "因灾", "缺土地", "缺水"],
+          data: [
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+          ],
+        };
+      },
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#323E6F", "#1DA0D7", "#02BB4C", "#DB5520", "#EDB32F", "#EDEB2F"],
+    };
+  },
+  computed: {
+    datas() {
+      return this.list.map((t) => {
+        return t.value;
+      });
+    },
+    xdata() {
+      return this.list[0].value.map((t) => {
+        return t.text;
+      });
+    },
+    ydata() {
+      let result = [];
+
+      return result;
+    },
+    series() {
+      let result = [];
+      return result;
+    },
+  },
+  methods: {
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        grid: {
+          left: 40,
+          right: 16,
+          bottom: 16,
+          top: 16,
+          containLabel: true,
+        },
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: 14,
+          },
+        },
+        yAxis: {
+          type: "category",
+          axisLabel: {
+            color: partten.getColor("gray"),
+          },
+          axisLine: {
+            lineStyle: {
+              color: "#96A4F4",
+            },
+            width: 5,
+          },
+          axisTick: {
+            show: false,
+          },
+          data: this.data.area,
+        },
+        xAxis: {
+          type: "value",
+          axisLabel: {
+            color: partten.getColor("gray"),
+          },
+          axisLine: {
+            lineStyle: {
+              color: "#96A4F4",
+              type: "dashed",
+            },
+            width: 5,
+          },
+          axisTick: {
+            show: false,
+          },
+          splitLine: {
+            lineStyle: {
+              color: partten.getColor("gray") + "20",
+            },
+          },
+        },
+        series: [],
+      };
+
+      for (var i = 0; i < this.data.legend.length; i++) {
+        option.series.push({
+          name: this.data.legend[i],
+          type: "bar",
+          stack: "总量",
+          barWidth: "10%",
+          label: {
+            show: false,
+            position: "insideRight",
+          },
+          data: this.data.data[i],
+        });
+      }
+
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 267 - 0
src/components/chart/bar/hover-bar-chart.vue

@@ -0,0 +1,267 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 传入数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          text: "1",
+          value: 1,
+        },
+        {
+          text: "2",
+          value: 2,
+        },
+        {
+          text: "3",
+          value: 1,
+        },
+        {
+          text: "4",
+          value: 3,
+        },
+        {
+          text: "5",
+          value: 3,
+        },
+        {
+          text: "6",
+          value: 3,
+        },
+        {
+          text: "7",
+          value: 3,
+        },
+        {
+          text: "8",
+          value: 3,
+        },
+        {
+          text: "9",
+          value: 3,
+        },
+        {
+          text: "10",
+          value: 3,
+        },
+        {
+          text: "11",
+          value: 3,
+        },
+        {
+          text: "12",
+          value: 3,
+        },
+        {
+          text: "13",
+          value: 3,
+        },
+        {
+          text: "14",
+          value: 3,
+        },
+        {
+          text: "15",
+          value: 3,
+        },
+        {
+          text: "16",
+          value: 3,
+        },
+        {
+          text: "17",
+          value: 3,
+        },
+        {
+          text: "18",
+          value: 3,
+        },
+        {
+          text: "19",
+          value: 3,
+        },
+        {
+          text: "20",
+          value: 3,
+        },
+        {
+          text: "21",
+          value: 3,
+        },
+        {
+          text: "22",
+          value: 3,
+        },
+        {
+          text: "23",
+          value: 3,
+        },
+        {
+          text: "24",
+          value: 3,
+        },
+        {
+          text: "25",
+          value: 3,
+        },
+        {
+          text: "26",
+          value: 3,
+        },
+        {
+          text: "27",
+          value: 3,
+        },
+        {
+          text: "28",
+          value: 3,
+        },
+        {
+          text: "29",
+          value: 3,
+        },
+        {
+          text: "30",
+          value: 3,
+        },
+        {
+          text: "31",
+          value: 3,
+        },
+      ],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b"],
+    };
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+    datas() {
+      return this.list.map((t) => {
+        return t.value;
+      });
+    },
+    xdata() {
+      return this.list.map((t) => {
+        return t.text;
+      });
+    },
+  },
+  methods: {
+    initChart() {
+      let chart = echarts.init(this.$el);
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "item",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: 14,
+          },
+          formatter: function(param) {
+            let marker = '<span style="display:inline-block;margin-right:0.370vh;border-radius:0.926vh;width:0.926vh;height:0.926vh;background-color:' + partten.getColor("green") + ';"></span>';
+            return param.name + "<br >" + marker + param.seriesName + ":" + param.value;
+          },
+        },
+        grid: {
+          top: 28,
+          left: 16,
+          bottom: 16,
+          right: 16,
+          containLabel: true,
+        },
+        xAxis: [
+          {
+            type: "category",
+            data: this.xdata,
+            axisLabel: {
+              fontSize: 14,
+            },
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            name: "(万KWh)",
+            //分格线
+            splitLine: {
+              lineStyle: {
+                color: "#999",
+                type: "dashed",
+              },
+            },
+            axisLabel: {
+              fontSize: 14,
+            },
+          },
+        ],
+        series: {
+          name: "损失电量",
+          type: "bar",
+          data: this.datas,
+          itemStyle: {
+            color: partten.getColor("gray") + 50,
+          },
+          emphasis: {
+            itemStyle: {
+              color: partten.getColor("green"),
+            },
+          },
+        },
+      };
+
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 416 - 0
src/components/chart/bar/list-bar-chart.vue

@@ -0,0 +1,416 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "percent-pie",
+  componentName: "percent-pie",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "18.519vh",
+    },
+    //  传入数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          name: "当日预测电量",
+          value: 103.62,
+        },
+        {
+          name: "实际发电量",
+          value: 98.62,
+        },
+        {
+          name: "当月预测电量",
+          value: 113.27,
+        },
+        {
+          name: "实际发电量",
+          value: 136.72,
+        },
+      ],
+    },
+    total: {
+      type: Number,
+      default: 150,
+    },
+    colors: {
+      type: Array,
+      default: () => ["green", "purple"],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    datas() {
+      return this.list.map((t) => {
+        return t.value;
+      });
+    },
+  },
+  methods: {
+    initChart() {
+      let color1 = this.colors[0];
+      let color2 = this.colors[1];
+
+      let option = {
+        xAxis: {
+          max: this.total,
+          splitLine: {
+            show: false,
+          },
+          axisLine: {
+            show: false,
+          },
+          axisLabel: {
+            show: false,
+          },
+          axisTick: {
+            show: false,
+          },
+        },
+        grid: {
+          left: 16,
+          top: 16, // 设置条形图的边s距
+          right: 80,
+          bottom: 0,
+        },
+        yAxis: [
+          {
+            type: "category",
+            inverse: true,
+            data: this.list,
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            axisLabel: {
+              show: false,
+            },
+          },
+        ],
+        series: [
+          // 内
+          {
+            type: "bar",
+            barWidth: 6,
+            // legendHoverLink: false,
+            // silent: true,
+            itemStyle: {
+              normal: {
+                color: function(params) {
+                  var color;
+                  if (params.dataIndex == 0 || params.dataIndex == 2) {
+                    color = {
+                      type: "linear",
+                      x: 0,
+                      y: 0,
+                      x2: 1,
+                      y2: 0,
+                      colorStops: [
+                        {
+                          offset: 0,
+                          color: partten.getColor(color1), // 0% 处的颜色
+                        },
+                        {
+                          offset: 1,
+                          color: partten.getColor(color1), // 100% 处的颜色
+                        },
+                      ],
+                    };
+                  } else if (params.dataIndex == 1 || params.dataIndex == 3) {
+                    color = {
+                      type: "linear",
+                      x: 0,
+                      y: 0,
+                      x2: 1,
+                      y2: 0,
+                      colorStops: [
+                        {
+                          offset: 0,
+                          color: partten.getColor(color2), // 0% 处的颜色
+                        },
+                        {
+                          offset: 1,
+                          color: partten.getColor(color2), // 100% 处的颜色
+                        },
+                      ],
+                    };
+                  } else {
+                    color = {
+                      type: "linear",
+                      x: 0,
+                      y: 0,
+                      x2: 1,
+                      y2: 0,
+                      colorStops: [
+                        {
+                          offset: 0,
+                          color: partten.getColor(color1), // 0% 处的颜色
+                        },
+                        {
+                          offset: 1,
+                          color: partten.getColor(color1), // 100% 处的颜色
+                        },
+                      ],
+                    };
+                  }
+                  return color;
+                },
+                shadowBlur: 10,
+                shadowColor: "rgba(255, 255, 255, 0.30)",
+              },
+            },
+            label: {
+              normal: {
+                show: true,
+                position: [0, util.vh("-20")],
+                formatter: function(param) {
+                  return param.data.name;
+                },
+                textStyle: {
+                  color: "#7a8385",
+                  fontSize: 12,
+                },
+                rich: {
+                  c1: {
+                    color: partten.getColor(color1),
+                  },
+                  c2: {
+                    color: partten.getColor(color2),
+                  },
+                },
+              },
+            },
+            data: this.list,
+            z: 1,
+            animationEasing: "elasticOut",
+          },
+          // 三角
+          {
+            type: "pictorialBar",
+            symbolPosition: "end",
+            data: this.list,
+            symbol: "triangle",
+            symbolOffset: [0, -10],
+            symbolSize: [5, 5],
+            symbolRotate: 180,
+            itemStyle: {
+              normal: {
+                borderWidth: 0,
+                color: function(params) {
+                  var color;
+                  if (params.dataIndex == 0 || params.dataIndex == 2) {
+                    color = partten.getColor(color1);
+                  } else if (params.dataIndex == 1 || params.dataIndex == 3) {
+                    color = partten.getColor(color2);
+                  } else {
+                    color = partten.getColor(color1);
+                  }
+                  return color;
+                },
+              },
+            },
+          },
+          // 分隔
+          {
+            type: "pictorialBar",
+            itemStyle: {
+              normal: {
+                color: "#20314f",
+              },
+            },
+            animation: this.firstAnimation,
+            symbolRepeat: "fixed",
+            symbolMargin: 4,
+            symbol: "rect",
+            symbolClip: true,
+            symbolSize: [1, 8],
+            symbolPosition: "start",
+            symbolOffset: [8, -1],
+            symbolBoundingData: this.total,
+            symbolRotate: -15,
+            data: this.list,
+            z: 2,
+            animationEasing: "elasticOut",
+          },
+          // 外边框
+          {
+            type: "pictorialBar",
+            symbol: "rect",
+            symbolBoundingData: this.total,
+            itemStyle: {
+              normal: {
+                color: "none",
+              },
+            },
+            label: {
+              normal: {
+                formatter: (params) => {
+                  var text;
+                  if (params.dataIndex == 0 || params.dataIndex == 2) {
+                    text = "{gm|}{f|  " + params.data + "}";
+                  } else if (params.dataIndex == 1 || params.dataIndex == 3) {
+                    text = "{pm|}{f|  " + params.data + "}";
+                  } else {
+                    text = "{gm|}{f|  " + params.data + "}";
+                  }
+                  return text;
+                },
+                rich: {
+                  f: {
+                    color: "#ffffff",
+                    fontSize: 14,
+                    lineHeight: 20,
+                    fontFamily: "Bicubik",
+                  },
+                  gm: {
+                    backgroundColor: partten.getColor(color1),
+                    width: 4,
+                    height: 4,
+                    lineHeight: 20,
+                    verticalAlign: "middle",
+                    borderRadius: [50, 50, 50, 50],
+                  },
+                  pm: {
+                    backgroundColor: partten.getColor(color2),
+                    width: 4,
+                    height: 4,
+                    lineHeight: 20,
+                    verticalAlign: "middle",
+                    borderRadius: [50, 50, 50, 50],
+                  },
+                },
+                position: "right",
+                distance: 8, // 向右偏移位置
+                show: true,
+              },
+            },
+            data: this.datas,
+          },
+          // 外框
+          {
+            type: "bar",
+            name: "外框",
+            barGap: "-120%", // 设置外框粗细
+            data: [
+              {
+                value: this.total,
+                itemStyle: {
+                  normal: {
+                    color: "transparent",
+                    borderColor: partten.getColor(color1), // [, "#333"],// [, "#333"],
+                    borderWidth: 1, // 边框宽度
+                    // barBorderRadius: 0, //圆角半径
+                    opacity: 0.5,
+                    label: {
+                      // 标签显示位置
+                      show: false,
+                      position: "top", // insideTop 或者横向的 insideLeft
+                    },
+                  },
+                },
+              },
+              {
+                value: this.total,
+                itemStyle: {
+                  normal: {
+                    color: "transparent",
+                    borderColor: partten.getColor(color2), // [, "#333"],
+                    opacity: 0.5,
+                    borderWidth: 1, // 边框宽度
+                    // barBorderRadius: 0, //圆角半径
+                    label: {
+                      // 标签显示位置
+                      show: false,
+                      position: "top", // insideTop 或者横向的 insideLeft
+                    },
+                  },
+                },
+              },
+              {
+                value: this.total,
+                itemStyle: {
+                  normal: {
+                    color: "transparent",
+                    borderColor: partten.getColor(color1), // [, "#333"],
+                    borderWidth: 1, // 边框宽度
+                    opacity: 0.5,
+                    // barBorderRadius: 0, //圆角半径
+                    label: {
+                      // 标签显示位置
+                      show: false,
+                      position: "top", // insideTop 或者横向的 insideLeft
+                    },
+                  },
+                },
+              },
+              {
+                value: this.total,
+                itemStyle: {
+                  normal: {
+                    color: "transparent",
+                    borderColor: partten.getColor(color2), // [, "#333"],
+                    opacity: 0.7,
+                    borderWidth: 1, // 边框宽度
+                    // barBorderRadius: 0, //圆角半径
+                    label: {
+                      // 标签显示位置
+                      show: false,
+                      position: "top", // insideTop 或者横向的 insideLeft
+                    },
+                  },
+                },
+              },
+            ],
+            barWidth: 9,
+          },
+        ],
+      };
+
+      this.chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.chart = echarts.init(this.$el);
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 340 - 0
src/components/chart/bar/list-bar-chart2.vue

@@ -0,0 +1,340 @@
+<template>
+  <div>
+    <div
+      class="chart"
+      v-for="index of list.length"
+      :key="index"
+      :id="id + index"
+    ></div>
+  </div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "percent-pie",
+  componentName: "percent-pie",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "18.519vh",
+    },
+    //  传入数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          name: "当日预测电量",
+          value: 103.62,
+          total: 200,
+        },
+        {
+          name: "实际发电量",
+          value: 98.62,
+          total: 100,
+        },
+        {
+          name: "当月预测电量",
+          value: 113.27,
+          total: 100,
+        },
+        {
+          name: "实际发电量",
+          value: 136.72,
+          total: 100,
+        },
+      ],
+    },
+    total: {
+      type: Number,
+      default: 150,
+    },
+    colors: {
+      type: Array,
+      default: () => ["green", "purple"],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      firstAnimation: true,
+    };
+  },
+  computed: {
+    datas() {
+      return this.list.map((t) => {
+        return t.value;
+      });
+    },
+  },
+  methods: {
+    resize() {},
+    initChart(value, index) {
+      var currColor = this.colors[index % 2];
+      var $dom = document.getElementById(this.id + (index + 1));
+      $dom.style.width = this.width;
+      $dom.style.height = `calc(${this.height} / ${this.list.length} - 4px)`;
+      let chart = echarts.init($dom);
+
+      let option = {
+        xAxis: {
+          max: value.total,
+          splitLine: {
+            show: false,
+          },
+          axisLine: {
+            show: false,
+          },
+          axisLabel: {
+            show: false,
+          },
+          axisTick: {
+            show: false,
+          },
+        },
+        grid: {
+          left: 16,
+          top: 16, // 设置条形图的边s距
+          right: 110,
+          bottom: 0,
+          containLabel: true,
+        },
+        yAxis: [
+          {
+            type: "category",
+            inverse: true,
+            data: [value],
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            axisLabel: {
+              show: false,
+            },
+          },
+        ],
+        series: [
+          // 内
+          {
+            type: "bar",
+            barWidth: 6,
+            animation: this.firstAnimation,
+            // legendHoverLink: false,
+            // silent: true,
+            itemStyle: {
+              normal: {
+                color: function (params) {
+                  return {
+                    type: "linear",
+                    x: 0,
+                    y: 0,
+                    x2: 1,
+                    y2: 0,
+                    colorStops: [
+                      {
+                        offset: 0,
+                        color: partten.getColor(currColor), // 0% 处的颜色
+                      },
+                      {
+                        offset: 1,
+                        color: partten.getColor(currColor), // 100% 处的颜色
+                      },
+                    ],
+                  };
+                },
+                shadowBlur: 10,
+                shadowColor: "rgba(255, 255, 255, 0.30)",
+              },
+            },
+            label: {
+              normal: {
+                show: true,
+                position: [0, util.vh("-20")],
+                formatter: function (param) {
+                  return param.data.name;
+                },
+                textStyle: {
+                  color: this.$store.state.themeName === "dark" ? "#7a8385" : "#000",
+                  fontSize: 12,
+                },
+              },
+            },
+            data: [value],
+            z: 1,
+            animationEasing: "elasticOut",
+          },
+          // 三角
+          {
+            type: "pictorialBar",
+            symbolPosition: "end",
+            animation: this.firstAnimation,
+            data: [value],
+            symbol: "triangle",
+            symbolOffset: [0, -10],
+            symbolSize: [5, 5],
+            symbolRotate: 180,
+            itemStyle: {
+              normal: {
+                borderWidth: 0,
+                color: function (params) {
+                  return partten.getColor(currColor);
+                },
+                // shadowBlur: 2,
+                // shadowColor: "rgba(255, 255, 255, 0.80)",
+              },
+            },
+          },
+          // 分隔
+          {
+            type: "pictorialBar",
+            itemStyle: {
+              normal: {
+                color: this.$store.state.themeName === "dark" ? "#20314f" : "#000",
+              },
+            },
+            animation: this.firstAnimation,
+            symbolRepeat: "fixed",
+            symbolMargin: 4,
+            symbol: "rect",
+            symbolClip: true,
+            symbolSize: [1, 8],
+            symbolPosition: "start",
+            symbolOffset: [8, -1],
+            symbolBoundingData: value.total,
+            symbolRotate: -15,
+            data: [value],
+            z: 2,
+            animationEasing: "elasticOut",
+          },
+          // 外边框
+          {
+            type: "pictorialBar",
+            animation: this.firstAnimation,
+            symbol: "rect",
+            symbolBoundingData: value.total,
+            itemStyle: {
+              normal: {
+                color: "none",
+              },
+            },
+            label: {
+              normal: {
+                formatter: (params) => {
+                  return "{gm|}{f|  " + params.data + "}";
+                },
+                rich: {
+                  f: {
+                    color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+                    fontSize: 14,
+                    lineHeight: 20,
+                    fontFamily: "Bicubik",
+                  },
+                  gm: {
+                    backgroundColor: partten.getColor(currColor),
+                    width: 4,
+                    height: 4,
+                    lineHeight: 20,
+                    verticalAlign: "middle",
+                    borderRadius: [50, 50, 50, 50],
+                  },
+                },
+                position: "right",
+                distance: 8, // 向右偏移位置
+                show: true,
+              },
+            },
+            data: [value.value],
+          },
+          // 外框
+          {
+            type: "bar",
+            animation: this.firstAnimation,
+            name: "外框",
+            barGap: "-120%", // 设置外框粗细
+            data: [
+              {
+                value: value.total,
+                itemStyle: {
+                  normal: {
+                    color: "transparent",
+                    borderColor: partten.getColor(currColor), // [, "#333"],
+                    borderWidth: 1, // 边框宽度
+                    // barBorderRadius: 0, //圆角半径
+                    opacity: 0.5,
+                    label: {
+                      // 标签显示位置
+                      show: false,
+                      position: "top", // insideTop 或者横向的 insideLeft
+                    },
+                  },
+                },
+              },
+            ],
+            barWidth: 9,
+          },
+        ],
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.removeEventListener("resize", this.resize);
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.list.forEach((value, index) => {
+        this.initChart(value, index);
+      });
+      this.firstAnimation = false;
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.list.forEach((value, index) => {
+        this.initChart(value, index);
+      });
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+
+  watch: {
+    "$store.state.themeName"() {
+      this.list.forEach((value, index) => {
+        this.initChart(value, index);
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+  cursor: default;
+}
+</style>

+ 406 - 0
src/components/chart/bar/multiple-bar-chart.vue

@@ -0,0 +1,406 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 传入数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "日发电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+          ],
+        },
+        {
+          title: "上网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 2,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 3,
+            },
+            {
+              text: "5日",
+              value: 3,
+            },
+            {
+              text: "6日",
+              value: 3,
+            },
+            {
+              text: "7日",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "购网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 2,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 3,
+            },
+            {
+              text: "5日",
+              value: 3,
+            },
+            {
+              text: "6日",
+              value: 3,
+            },
+            {
+              text: "7日",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "风速",
+          yAxisIndex: 1,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 2,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 3,
+            },
+            {
+              text: "5日",
+              value: 3,
+            },
+            {
+              text: "6日",
+              value: 3,
+            },
+            {
+              text: "7日",
+              value: 3,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["(万kWh)", "(风速)"],
+    },
+    // 显示 legend
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 颜色#
+    color: {
+      type: Array,
+      default: () => [
+        "#05bb4c",
+        "#4b55ae",
+        "#fa8c16",
+        "#f8de5b",
+        "#1a93cf",
+        "#c531c7",
+        "#bd3338",
+      ],
+    },
+    showAnimation: {
+      type: Boolean,
+      default: true,
+    },
+    // 柱子最大宽度
+    barMaxWidth: {
+      type: Number || String,
+      default: 0,
+    },
+    // 柱子间距
+    barGap: {
+      type: Number || String,
+      default: 0,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      firstAnimation: true,
+    };
+  },
+  computed: {
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      let result = [];
+      if (this.list && this.list.length > 0 && this.list[0].value.length > 0) {
+        result = this.list[0].value.map((t) => {
+          return t.text;
+        });
+      }
+      return result;
+    },
+    ydata() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        let data = null;
+        if (index == 0) {
+          data = {
+            type: "value",
+            name: value,
+            axisLabel: {
+              formatter: "{value} ",
+              fontSize: 12,
+              textStyle: {
+                color:
+                  this.$store.state.themeName === "dark"
+                    ? "rgb(116,124,128)"
+                    : "#000",
+              },
+            },
+            //分格线
+            splitLine: {
+              lineStyle: {
+                color:
+                  this.$store.state.themeName === "dark" ? "#5a6162" : "#000",
+                type: "dashed",
+              },
+            },
+          };
+        } else {
+          data = {
+            type: "value",
+            name: value,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: 12,
+              textStyle: {
+                color:
+                  this.$store.state.themeName === "dark"
+                    ? "rgb(116,124,128)"
+                    : "#000",
+              },
+            },
+            //分格线
+            splitLine: {
+              show: false,
+            },
+          };
+        }
+
+        result.push(data);
+      });
+
+      return result;
+    },
+    series() {
+      let result = [];
+      if (this.list && this.list.length > 0) {
+        this.list.forEach((value, index) => {
+          let seriesItem = {
+            name: value.title,
+            type: "bar",
+            barWidth: "8%",
+            animation: this.firstAnimation && this.showAnimation,
+            yAxisIndex: value.yAxisIndex,
+            data: value.value.map((t) => {
+              return t.value;
+            }),
+          };
+          if (this.barMaxWidth) {
+            seriesItem.barMaxWidth = this.barMaxWidth;
+          } else {
+            seriesItem.barWidth = "8%";
+          }
+
+          if (this.barGap) {
+            seriesItem.barGap = this.barGap;
+          }
+          result.push(seriesItem);
+        });
+      }
+      return result;
+    },
+  },
+  methods: {
+    resize() {
+      this.initChart();
+    },
+    initChart() {
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor:
+            this.$store.state.themeName === "dark"
+              ? "rgba(0,0,0,0.4)"
+              : "rgba(255,255,255,0.5)",
+          borderColor:
+            this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: 12,
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "ract",
+          itemWidth: 8,
+          itemHeight: 8,
+          inactiveColor:
+            this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            fontSize: 12,
+            color:
+              this.$store.state.themeName === "dark"
+                ? partten.getColor("grayl")
+                : "#000",
+          },
+        },
+        grid: {
+          top: 32,
+          left: 8,
+          right: 8,
+          bottom: 0,
+          containLabel: true,
+        },
+        xAxis: [
+          {
+            type: "category",
+            data: this.xdata,
+            nameLocation: "center",
+            axisPointer: {
+              type: "shadow",
+            },
+            axisLabel: {
+              interval: 0,
+              fontSize: 12,
+              textStyle: {
+                color:
+                  this.$store.state.themeName === "dark"
+                    ? "rgb(116,124,128)"
+                    : "#000",
+              },
+            },
+          },
+        ],
+        yAxis: this.ydata,
+        series: this.series,
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.$nextTick(() => {
+      this.id = "pie-chart-" + util.newGUID();
+    });
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+      this.firstAnimation = false;
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+
+  watch: {
+    "$store.state.themeName"() {
+      let myChart = echarts.init(document.getElementById(this.id));
+      myChart.dispose();
+      setTimeout(() => {
+        this.initChart();
+      }, 300);
+    },
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 369 - 0
src/components/chart/bar/multiple-hover-bar-chart.vue

@@ -0,0 +1,369 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 传入数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "日发电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 1,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 1,
+            },
+            {
+              text: "5日",
+              value: 1,
+            },
+            {
+              text: "6日",
+              value: 1,
+            },
+            {
+              text: "7日",
+              value: 1,
+            },
+            {
+              text: "8日",
+              value: 1,
+            },
+            {
+              text: "9日",
+              value: 1,
+            },
+            {
+              text: "10日",
+              value: 1,
+            },
+            {
+              text: "11日",
+              value: 1,
+            },
+            {
+              text: "12日",
+              value: 1,
+            },
+          ],
+        },
+        {
+          title: "上网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 2,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 3,
+            },
+            {
+              text: "5日",
+              value: 3,
+            },
+            {
+              text: "6日",
+              value: 3,
+            },
+            {
+              text: "7日",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "购网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 2,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 3,
+            },
+            {
+              text: "5日",
+              value: 3,
+            },
+            {
+              text: "6日",
+              value: 3,
+            },
+            {
+              text: "7日",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "风速",
+          yAxisIndex: 1,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 2,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 3,
+            },
+            {
+              text: "5日",
+              value: 3,
+            },
+            {
+              text: "6日",
+              value: 3,
+            },
+            {
+              text: "7日",
+              value: 3,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["(万kWh)", "(风速)"],
+    },
+    // 自定义tooltip 显示内容
+    customerTooltip: {
+      type: Boolean,
+      default: true,
+    },
+    // 颜色
+    color: {
+      type: Array,
+      default: () => ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b", "#1a93cf", "#c531c7", "#bd3338"],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    xdata() {
+      let result = [];
+      if (this.list && this.list.length > 0 && this.list[0].value.length > 0) {
+        result = this.list[0].value.map((t) => {
+          return t.text;
+        });
+      }
+      return result;
+    },
+    ydata() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        let data = null;
+        if (index == 0) {
+          data = {
+            type: "value",
+            name: value,
+            axisLabel: {
+              formatter: "{value} ",
+              fontSize: 14,
+            },
+            //分格线
+            splitLine: {
+              lineStyle: {
+                color: "#5a6162",
+                type: "dashed",
+              },
+            },
+          };
+        } else {
+          data = {
+            type: "value",
+            name: value,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: 14,
+            },
+
+            //分格线
+            splitLine: {
+              show: false,
+            },
+          };
+        }
+
+        result.push(data);
+      });
+
+      return result;
+    },
+    series() {
+      let result = [];
+      if (this.list && this.list.length > 0) {
+        this.list.forEach((value, index) => {
+          result.push({
+            name: value.title,
+            type: "bar",
+            yAxisIndex: value.yAxisIndex,
+            data: value.value.map((t) => {
+              return t.value;
+            }),
+            itemStyle: {
+              color: partten.getColor("gray") + 50,
+            },
+            emphasis: {
+              itemStyle: {
+                color: this.color[index],
+              },
+            },
+          });
+        });
+      }
+      return result;
+    },
+  },
+  emits: {
+    tooltip: function(param, callback) {
+      var color = ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b"];
+      var result = param[0].axisValue;
+      param.forEach((value, index) => {
+        result += "<br />" + `<span style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:${color[index]};"></span>` + value.seriesName + ":" + value.value;
+      });
+      callback(result);
+      return true;
+    },
+  },
+  methods: {
+    initChart() {
+      let that = this;
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: 14,
+          },
+        },
+        grid: {
+          top: util.vh(32),
+          left: util.vh(40),
+          right: this.ydata.length > 1 ? util.vh(40) : util.vh(16),
+          bottom: util.vh(24),
+        },
+        xAxis: [
+          {
+            type: "category",
+            data: this.xdata,
+            axisPointer: {
+              type: "shadow",
+            },
+            axisLabel: {
+              fontSize: 14,
+            },
+          },
+        ],
+        yAxis: this.ydata,
+        series: this.series,
+      };
+
+      if (that.customerTooltip) {
+        option.tooltip.formatter = function(param) {
+          let result = "";
+          let callback = function(value) {
+            result = value;
+          };
+          that.$emit("tooltip", param, callback);
+          return result;
+        };
+      }
+
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 204 - 0
src/components/chart/bar/percent-bar-2.vue

@@ -0,0 +1,204 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "dsah-pie",
+  componentName: "dsah-pie",
+  props: {
+    width: {
+      type: String,
+      default: "7.407vh",
+    },
+    height: {
+      type: String,
+      default: "7.407vh",
+    },
+    name: {
+      type: String,
+      default: "名称",
+    },
+    // 传入数据
+    value: {
+      type: Number,
+      default: 25,
+    },
+    // 颜色 green yellow (partten中支持的颜色)
+    color: {
+      type: String,
+      default: "green",
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+    text() {
+      return this.value + "%";
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  methods: {
+    initChart() {
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        title: [
+          {
+            text: this.text,
+            subtext: this.name,
+            x: "47%",
+            y: "25%",
+            textAlign: "center",
+            textStyle: {
+              fontSize: 20,
+              fontFamily: "Bicubik",
+              color: this.colorValue,
+              textAlign: "center",
+            },
+            subtextStyle: {
+              fontSize: 12,
+              color: "#fff",
+              textAlign: "center",
+            },
+          },
+        ],
+        polar: {
+          radius: ["100%", "85%"],
+          center: ["50%", "50%"],
+        },
+        angleAxis: {
+          max: 100,
+          show: false,
+          startAngle: 180,
+        },
+        radiusAxis: {
+          type: "category",
+          show: true,
+          axisLabel: {
+            show: false,
+          },
+          axisLine: {
+            show: false,
+          },
+          axisTick: {
+            show: false,
+          },
+        },
+        series: [
+          {
+            name: "",
+            z: "3",
+            type: "bar",
+            roundCap: true,
+            barWidth: 60,
+            showBackground: true,
+            backgroundStyle: {
+              color: this.colorValue + "30",
+            },
+            data: [this.value],
+            coordinateSystem: "polar",
+            itemStyle: {
+              normal: {
+                color: this.colorValue,
+                //    new echarts.graphic.LinearGradient(1, 0, 0, 0, [
+                //     {
+                //       offset: 0,
+                //       color: "#0ff",
+                //     },
+                //     {
+                //       offset: 1,
+                //       color: "#02aeff",
+                //     },
+                //   ]),
+              },
+            },
+          },
+          {
+            type: "pie",
+            radius: ["100%", "97%"],
+            startAngle: 180,
+            center: ["50%", "50%"],
+            data: [
+              {
+                hoverOffset: 1,
+                value: 100,
+                name: "",
+                itemStyle: {
+                  color: this.colorValue,
+                },
+                label: {
+                  show: false,
+                },
+                labelLine: {
+                  normal: {
+                    smooth: true,
+                    lineStyle: {
+                      width: 0,
+                    },
+                  },
+                },
+                hoverAnimation: false,
+              },
+              {
+                label: {
+                  show: false,
+                },
+                labelLine: {
+                  normal: {
+                    smooth: true,
+                    lineStyle: {
+                      width: 0,
+                    },
+                  },
+                },
+                value: 0,
+                hoverAnimation: false,
+                itemStyle: {
+                  color: "transparent",
+                },
+              },
+            ],
+          },
+        ],
+      };
+
+      chart.setOption(option);
+    },
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: block;
+  margin: auto;
+}
+</style>

+ 199 - 0
src/components/chart/bar/percent-bar-3.vue

@@ -0,0 +1,199 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "dsah-pie",
+  componentName: "dsah-pie",
+  props: {
+    width: {
+      type: String,
+      default: "7.407vh",
+    },
+    height: {
+      type: String,
+      default: "7.407vh",
+    },
+    // 传入数据
+    value: {
+      type: Number,
+      default: 25,
+    },
+    // 颜色 green yellow (partten中支持的颜色)
+    color: {
+      type: String,
+      default: "green",
+    },
+    fontsize: {
+      type: Number,
+      default: 12,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+    text() {
+      return this.value + "%";
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  methods: {
+    initChart() {
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        title: [
+          {
+            text: this.text,
+            x: "43%",
+            y: "32%",
+            textAlign: "center",
+            textStyle: {
+              fontSize: this.fontsize,
+              fontFamily: "Bicubik",
+              fontWeight: "400",
+              color: partten.getColor(this.colors),
+              textAlign: "center",
+            },
+          },
+        ],
+        polar: {
+          radius: ["100%", "85%"],
+          center: ["50%", "50%"],
+        },
+        angleAxis: {
+          max: 100,
+          show: false,
+          startAngle: 180,
+        },
+        radiusAxis: {
+          type: "category",
+          show: true,
+          axisLabel: {
+            show: false,
+          },
+          axisLine: {
+            show: false,
+          },
+          axisTick: {
+            show: false,
+          },
+        },
+        series: [
+          {
+            name: "",
+            z: "3",
+            type: "bar",
+            roundCap: true,
+            barWidth: 60,
+            showBackground: true,
+            backgroundStyle: {
+              color: partten.getColor(this.colors) + "30",
+            },
+            data: [this.value],
+            coordinateSystem: "polar",
+            itemStyle: {
+              normal: {
+                color: partten.getColor(this.colors),
+                //    new echarts.graphic.LinearGradient(1, 0, 0, 0, [
+                //     {
+                //       offset: 0,
+                //       color: "#0ff",
+                //     },
+                //     {
+                //       offset: 1,
+                //       color: "#02aeff",
+                //     },
+                //   ]),
+              },
+            },
+          },
+          {
+            type: "pie",
+            radius: ["100%", "97%"],
+            startAngle: 180,
+            center: ["50%", "50%"],
+            data: [
+              {
+                hoverOffset: 1,
+                value: 100,
+                name: "",
+                itemStyle: {
+                  color: partten.getColor(this.colors),
+                },
+                label: {
+                  show: false,
+                },
+                labelLine: {
+                  normal: {
+                    smooth: true,
+                    lineStyle: {
+                      width: 0,
+                    },
+                  },
+                },
+                hoverAnimation: false,
+              },
+              {
+                label: {
+                  show: false,
+                },
+                labelLine: {
+                  normal: {
+                    smooth: true,
+                    lineStyle: {
+                      width: 0,
+                    },
+                  },
+                },
+                value: 0,
+                hoverAnimation: false,
+                itemStyle: {
+                  color: "transparent",
+                },
+              },
+            ],
+          },
+        ],
+      };
+
+      chart.setOption(option);
+    },
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: block;
+  margin: auto;
+}
+</style>

+ 211 - 0
src/components/chart/bar/percent-bar.vue

@@ -0,0 +1,211 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "dsah-pie",
+  componentName: "dsah-pie",
+  props: {
+    width: {
+      type: String,
+      default: "7.407vh",
+    },
+    height: {
+      type: String,
+      default: "7.407vh",
+    },
+    // 传入数据
+    value: {
+      type: Number,
+      default: 25,
+    },
+    // 颜色 green yellow (partten中支持的颜色)
+    color: {
+      type: String,
+      default: "green",
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+    text() {
+      return this.value + "%";
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  methods: {
+    initChart() {
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        title: [
+          {
+            text: this.text,
+            x: "47%",
+            y: "32%",
+            textAlign: "center",
+            textStyle: {
+              fontSize: 14,
+              fontFamily: "Bicubik",
+              fontWeight: "600",
+              color:
+                this.$store.state.themeName === "dark"
+                  ? partten.getColor(this.colors)
+                  : "rgb(57, 54, 143)",
+              textAlign: "center",
+            },
+          },
+        ],
+        polar: {
+          radius: ["100%", "85%"],
+          center: ["50%", "50%"],
+        },
+        angleAxis: {
+          max: 100,
+          show: false,
+          startAngle: 180,
+        },
+        radiusAxis: {
+          type: "category",
+          show: true,
+          axisLabel: {
+            show: false,
+          },
+          axisLine: {
+            show: false,
+          },
+          axisTick: {
+            show: false,
+          },
+        },
+        series: [
+          {
+            name: "",
+            z: "3",
+            type: "bar",
+            roundCap: true,
+            barWidth: 60,
+            showBackground: true,
+            backgroundStyle: {
+              color:
+                this.$store.state.themeName === "dark"
+                    ? partten.getColor(this.colors)
+                    : "rgb(57, 54, 143)",
+            },
+            data: [this.value],
+            coordinateSystem: "polar",
+            itemStyle: {
+              normal: {
+                color:this.$store.state.themeName === "dark"
+                  ? 'black'
+                  : "#fff",
+                //    new echarts.graphic.LinearGradient(1, 0, 0, 0, [
+                //     {
+                //       offset: 0,
+                //       color: "#0ff",
+                //     },
+                //     {
+                //       offset: 1,
+                //       color: "#02aeff",
+                //     },
+                //   ]),
+              },
+            },
+          },
+          {
+            type: "pie",
+            radius: ["100%", "97%"],
+            startAngle: 180,
+            center: ["50%", "50%"],
+            data: [
+              {
+                hoverOffset: 1,
+                value: 100,
+                name: "",
+                itemStyle: {
+                  color:
+                    this.$store.state.themeName === "dark"
+                      ? partten.getColor(this.colors)
+                      : "rgb(57, 54, 143)",
+                },
+                label: {
+                  show: false,
+                },
+                labelLine: {
+                  normal: {
+                    smooth: true,
+                    lineStyle: {
+                      width: 0,
+                    },
+                  },
+                },
+                hoverAnimation: false,
+              },
+              {
+                label: {
+                  show: false,
+                },
+                labelLine: {
+                  normal: {
+                    smooth: true,
+                    lineStyle: {
+                      width: 0,
+                    },
+                  },
+                },
+                value: 0,
+                hoverAnimation: false,
+                itemStyle: {
+                  color: "transparent",
+                },
+              },
+            ],
+          },
+        ],
+      };
+
+      chart.setOption(option);
+    },
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  watch: {
+    "$store.state.themeName"() {
+      this.initChart();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: block;
+  margin: auto;
+}
+</style>

+ 408 - 0
src/components/chart/bar/single-bar-chart.vue

@@ -0,0 +1,408 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "percent-pie",
+  componentName: "percent-pie",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "18.519vh",
+    },
+    //  传入数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          name: "当日预测电量",
+          value: 103.62,
+        },
+        {
+          name: "实际发电量",
+          value: 98.62,
+        },
+        {
+          name: "当月预测电量",
+          value: 113.27,
+        },
+        {
+          name: "实际发电量",
+          value: 136.72,
+        },
+      ],
+    },
+    total: {
+      type: Number,
+      default: 150,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    datas() {
+      return this.list.map((t) => {
+        return t.value;
+      });
+    },
+  },
+  methods: {
+    initChart() {
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        xAxis: {
+          max: this.total,
+          splitLine: {
+            show: false,
+          },
+          axisLine: {
+            show: false,
+          },
+          axisLabel: {
+            show: false,
+          },
+          axisTick: {
+            show: false,
+          },
+        },
+        // tooltip: {
+        //   trigger: "axis",
+        //   backgroundColor: "rgba(0,0,0,0.4)",
+        //   borderColor: partten.getColor("gray"),
+        //   textStyle: {
+        //     color: "#fff",
+        //     fontSize: 14,
+        //   },
+        // },
+        grid: {
+          left: 16,
+          top: 16, // 设置条形图的边s距
+          right: 80,
+          bottom: 0,
+        },
+        yAxis: [
+          {
+            type: "category",
+            inverse: true,
+            data: this.list,
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            axisLabel: {
+              show: false,
+            },
+          },
+        ],
+        series: [
+          {
+            // 内
+            type: "bar",
+            barWidth: 10,
+            // legendHoverLink: false,
+            // silent: true,
+            itemStyle: {
+              normal: {
+                color: function(params) {
+                  var color;
+                  if (params.dataIndex == 0 || params.dataIndex == 2) {
+                    color = {
+                      type: "linear",
+                      x: 0,
+                      y: 0,
+                      x2: 1,
+                      y2: 0,
+                      colorStops: [
+                        {
+                          offset: 0,
+                          color: partten.getColor("green"), // 0% 处的颜色
+                        },
+                        {
+                          offset: 1,
+                          color: partten.getColor("green"), // 100% 处的颜色
+                        },
+                      ],
+                    };
+                  } else if (params.dataIndex == 1 || params.dataIndex == 3) {
+                    color = {
+                      type: "linear",
+                      x: 0,
+                      y: 0,
+                      x2: 1,
+                      y2: 0,
+                      colorStops: [
+                        {
+                          offset: 0,
+                          color: partten.getColor("purple"), // 0% 处的颜色
+                        },
+                        {
+                          offset: 1,
+                          color: partten.getColor("purple"), // 100% 处的颜色
+                        },
+                      ],
+                    };
+                  } else {
+                    color = {
+                      type: "linear",
+                      x: 0,
+                      y: 0,
+                      x2: 1,
+                      y2: 0,
+                      colorStops: [
+                        {
+                          offset: 0,
+                          color: partten.getColor("green"), // 0% 处的颜色
+                        },
+                        {
+                          offset: 1,
+                          color: partten.getColor("green"), // 100% 处的颜色
+                        },
+                      ],
+                    };
+                  }
+                  return color;
+                },
+                shadowBlur: 3,
+                shadowColor: "rgba(255, 255, 255, 0.70)",
+              },
+            },
+            label: {
+              normal: {
+                show: true,
+                position: [0, util.vh("-20")],
+                formatter: "{b}",
+                textStyle: {
+                  color: "#7a8385",
+                  fontSize: util.vh("14"),
+                },
+              },
+            },
+            data: this.list,
+            z: 1,
+            animationEasing: "elasticOut",
+          },
+          {
+            // 三角
+            type: "pictorialBar",
+            symbolPosition: "end",
+            data: this.list,
+            symbol: "triangle",
+            symbolOffset: [0, -16],
+            symbolSize: [10, 10],
+            symbolRotate: 180,
+            itemStyle: {
+              normal: {
+                borderWidth: 0,
+                color: function(params) {
+                  var color;
+                  if (params.dataIndex == 0 || params.dataIndex == 2) {
+                    color = partten.getColor("green");
+                  } else if (params.dataIndex == 1 || params.dataIndex == 3) {
+                    color = partten.getColor("purple");
+                  } else {
+                    color = partten.getColor("green");
+                  }
+                  return color;
+                },
+                shadowBlur: 2,
+                shadowColor: "rgba(255, 255, 255, 0.80)",
+              },
+            },
+          },
+          {
+            // 分隔
+            type: "pictorialBar",
+            itemStyle: {
+              normal: {
+                color: "#20314f",
+              },
+            },
+            symbolRepeat: "fixed",
+            symbolMargin: 6,
+            symbol: "rect",
+            symbolClip: true,
+            symbolSize: [1, 10],
+            symbolPosition: "start",
+            symbolOffset: [10, -1],
+            symbolBoundingData: this.total,
+            symbolRotate: -15,
+            data: this.list,
+            z: 2,
+            animationEasing: "elasticOut",
+          },
+          {
+            // 外边框
+            type: "pictorialBar",
+            symbol: "rect",
+            symbolBoundingData: this.total,
+            itemStyle: {
+              normal: {
+                color: "none",
+              },
+            },
+            label: {
+              normal: {
+                formatter: (params) => {
+                  var text;
+                  if (params.dataIndex == 0 || params.dataIndex == 2) {
+                    text = "{gm|}{f|  " + params.data + "}";
+                  } else if (params.dataIndex == 1 || params.dataIndex == 3) {
+                    text = "{pm|}{f|  " + params.data + "}";
+                  } else {
+                    text = "{gm|}{f|  " + params.data + "}";
+                  }
+                  return text;
+                },
+                rich: {
+                  f: {
+                    color: "#ffffff",
+                    fontSize: util.vh("14"),
+                    lineHeight: util.vh(20),
+                  },
+                  gm: {
+                    backgroundColor: partten.getColor("green"),
+                    width: util.vh(8),
+                    height: util.vh(8),
+                    lineHeight: util.vh(20),
+                    verticalAlign: "middle",
+                    borderRadius: [50, 50, 50, 50],
+                  },
+                  pm: {
+                    backgroundColor: partten.getColor("purple"),
+                    width: util.vh(8),
+                    height: util.vh(8),
+                    lineHeight: util.vh(20),
+                    verticalAlign: "middle",
+                    borderRadius: [50, 50, 50, 50],
+                  },
+                },
+                position: "right",
+                distance: 8, // 向右偏移位置
+                show: true,
+              },
+            },
+            data: this.datas,
+          },
+          {
+            type: "bar",
+            name: "外框",
+            barGap: "-120%", // 设置外框粗细
+            data: [
+              {
+                value: this.total,
+                itemStyle: {
+                  normal: {
+                    color: "transparent",
+                    borderColor: partten.getColor("green"), // [, "#333"],
+                    borderWidth: 1, // 边框宽度
+                    // barBorderRadius: 0, //圆角半径
+                    opacity: 0.5,
+                    label: {
+                      // 标签显示位置
+                      show: false,
+                      position: "top", // insideTop 或者横向的 insideLeft
+                    },
+                  },
+                },
+              },
+              {
+                value: this.total,
+                itemStyle: {
+                  normal: {
+                    color: "transparent",
+                    borderColor: partten.getColor("purple"), // [, "#333"],
+                    opacity: 0.5,
+                    borderWidth: 1, // 边框宽度
+                    // barBorderRadius: 0, //圆角半径
+                    label: {
+                      // 标签显示位置
+                      show: false,
+                      position: "top", // insideTop 或者横向的 insideLeft
+                    },
+                  },
+                },
+              },
+              {
+                value: this.total,
+                itemStyle: {
+                  normal: {
+                    color: "transparent",
+                    borderColor: partten.getColor("green"), // [, "#333"],
+                    borderWidth: 1, // 边框宽度
+                    opacity: 0.5,
+                    // barBorderRadius: 0, //圆角半径
+                    label: {
+                      // 标签显示位置
+                      show: false,
+                      position: "top", // insideTop 或者横向的 insideLeft
+                    },
+                  },
+                },
+              },
+              {
+                value: this.total,
+                itemStyle: {
+                  normal: {
+                    color: "transparent",
+                    borderColor: partten.getColor("purple"), // [, "#333"],
+                    opacity: 0.7,
+                    borderWidth: 1, // 边框宽度
+                    // barBorderRadius: 0, //圆角半径
+                    label: {
+                      // 标签显示位置
+                      show: false,
+                      position: "top", // insideTop 或者横向的 insideLeft
+                    },
+                  },
+                },
+              },
+            ],
+            barWidth: 14,
+          },
+        ],
+      };
+
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 320 - 0
src/components/chart/bar/thermometer.vue

@@ -0,0 +1,320 @@
+<template>
+  <div class="thermometer"></div>
+</template>
+
+<script>
+import * as echarts from "echarts";
+export default {
+  // 名称
+  name: "thermometer",
+  // 使用组件
+  components: {},
+  // 传入参数
+  props: {
+    width: {
+      type: String,
+      default: "9.259vh",
+    },
+    height: {
+      type: String,
+      default: "11.111vh",
+    },
+    min: {
+      type: Number,
+      default: -20,
+    },
+    max: {
+      type: Number,
+      default: 100,
+    },
+    value: {
+      type: Number,
+      default: 36.6,
+    },
+    title: {
+      type: String,
+      default: "温度",
+    },
+  },
+  // 自定义事件
+  emits: {},
+  // 数据
+  data() {
+    return {
+      option: {},
+    };
+  },
+  // 函数
+  methods: {
+    initChart: function() {
+      const chart = echarts.init(this.$el);
+      let kd = []; // 刻度
+      for (var i = 0, len = 135; i <= len; i++) {
+        if (i < 30 || i > 130) {
+          kd.push("");
+        } else {
+          if ((i - 30) % 20 === 0) {
+            kd.push("-3");
+          } else if ((i - 30) % 4 === 0) {
+            kd.push("-1");
+          } else {
+            kd.push("");
+          }
+        }
+      }
+      let width = this.$el.offsetWidth;
+      this.option = {
+        backgroundColor: "transparent",
+        grid: {
+          top: "0",
+          left: "0",
+          right: "0",
+          bottom: "45%",
+        },
+        yAxis: [
+          {
+            axisLine: {
+              show: false,
+            },
+            axisLabel: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          {
+            show: false,
+            data: [],
+            min: 0,
+            max: 135,
+            axisLine: {
+              show: false,
+            },
+          },
+        ],
+        xAxis: [
+          {
+            axisTick: "none",
+            axisLine: "none",
+            offset: 0,
+            data: [this.title],
+            axisLabel: {
+              show: true,
+              textStyle: {
+                color: "#606769",
+                fontSize: "14",
+              },
+              lineHeight: 40,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          {
+            axisTick: "none",
+            axisLabel: {
+              show: false,
+            },
+            data: [0],
+            splitLine: {
+              show: false,
+            },
+            axisLine: {
+              show: false,
+            },
+          },
+          {
+            name: "单位:件",
+            nameGap: "50",
+            data: [],
+            splitLine: {
+              show: false,
+            },
+            axisLine: {
+              show: false,
+              color: "#ffffff",
+            },
+          },
+          {
+            show: false,
+            min: 0 - width * 0.35,
+            max: width * 0.5,
+          },
+        ],
+        series: [
+          {
+            name: "℃",
+            type: "bar",
+            yAxisIndex: 0,
+            xAxisIndex: 0,
+            label: {
+              show: true,
+              position: "top",
+              formatter: "{back|" + "{c}" + "}",
+              rich: {
+                back: {
+                  align: "right",
+                  lineHeight: 14,
+                  fontSize: 14,
+                  fontFamily: "微软雅黑",
+                  color: "#05bb4c",
+                },
+              },
+              offset: [25, 15],
+            },
+            data: [this.value],
+            barWidth: 5,
+            itemStyle: {
+              normal: {
+                color: "#05bb4c",
+              },
+            },
+            z: 2,
+          },
+          {
+            name: "温度背景框",
+            type: "bar",
+            yAxisIndex: 0,
+            xAxisIndex: 1,
+            barGap: "-100%",
+            data: [99],
+            barWidth: 8,
+            itemStyle: {
+              normal: {
+                color: "#040c0b",
+                barBorderRadius: 5,
+              },
+            },
+            z: 1,
+          },
+          {
+            name: "外框",
+            type: "bar",
+            yAxisIndex: 0,
+            xAxisIndex: 2,
+            barGap: "-100%",
+            data: [100],
+            barWidth: width * 0.1,
+            itemStyle: {
+              normal: {
+                color: "#606769",
+                barBorderRadius: width * 0.5,
+              },
+            },
+            z: 0,
+          },
+          {
+            name: "外圆",
+            type: "scatter",
+            hoverAnimation: false,
+            data: [0],
+            yAxisIndex: 0,
+            xAxisIndex: 2,
+            symbolSize: width * 0.15,
+            itemStyle: {
+              normal: {
+                color: "#05bb4c",
+                opacity: 1,
+              },
+            },
+            z: 2,
+          },
+          {
+            name: "白圆",
+            type: "scatter",
+            hoverAnimation: false,
+            data: [0],
+            yAxisIndex: 0,
+            xAxisIndex: 1,
+            symbolSize: width * 0.2,
+            itemStyle: {
+              normal: {
+                color: "#040c0b",
+                opacity: 1,
+              },
+            },
+            z: 1,
+          },
+          {
+            name: "外圆",
+            type: "scatter",
+            hoverAnimation: false,
+            data: [0],
+            yAxisIndex: 0,
+            xAxisIndex: 2,
+            symbolSize: width * 0.23,
+            itemStyle: {
+              normal: {
+                color: "#606769",
+                opacity: 1,
+              },
+            },
+            z: 0,
+          },
+          {
+            name: "刻度",
+            type: "bar",
+            yAxisIndex: 1,
+            xAxisIndex: 3,
+            label: {
+              normal: {
+                show: false,
+              },
+            },
+            barGap: "100%",
+            data: kd,
+            barWidth: 1,
+            itemStyle: {
+              normal: {
+                color: "#606769",
+                barBorderRadius: width * 1.2,
+              },
+            },
+            z: 0,
+          },
+        ],
+      };
+      chart.setOption(this.option);
+    },
+    setValue: function() {
+      this.option.series[0].data[0] = this.value;
+      const chart = echarts.getInstanceByDom(this.$el);
+      chart.setOption(this.option);
+    },
+  },
+  // 生命周期钩子
+  beforeCreate() {
+    // 创建前
+  },
+  created() {
+    // 创建后
+  },
+  beforeMount() {
+    // 渲染前
+  },
+  mounted() {
+    // 渲染后
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  beforeUpdate() {
+    // 数据更新前
+  },
+  updated() {
+    // 数据更新后
+    this.setValue();
+  },
+};
+</script>
+
+<style lang="less">
+.thermometer {
+}
+</style>

+ 372 - 0
src/components/chart/combination/area-bar-chart.vue

@@ -0,0 +1,372 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "800px",
+    },
+    // 传入数据
+    bardata: {
+      type: Object,
+      default: () => {
+        return {
+          area: ["风场1", "风场2", "风场3", "风场4", "风场5", "风场6", "风场7", "风场8", "风场9"],
+          legend: ["实际电量", "计划检修损失", "非计划检修损失", "限电损失", "受累损失", "性能损失"],
+          data: [
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+          ],
+        };
+      },
+    },
+    lineData: {
+      type: Array,
+      default: () => [[200, 350, 400, 500, 600, 700, 800, 900, 1200]],
+    },
+    areaData: {
+      type: Array,
+      default: () => [
+        {
+          name: "1",
+          start: 0,
+          end: 100,
+          state: "green",
+        },
+        {
+          name: "1",
+          start: 100,
+          end: 200,
+          state: "red",
+        },
+        {
+          name: "1",
+          start: 200,
+          end: 300,
+          state: "yellow",
+        },
+        {
+          name: "",
+          start: 300,
+          end: 400,
+          state: "green",
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["健康趋势", "风机健康状态数量"],
+    },
+    // 显示 legend
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 颜色
+    color: {
+      type: Array,
+      default: () => ["#323E6F", "#1DA0D7", "#02BB4C", "#DB5520", "#EDB32F", "#EDEB2F"],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    legend() {
+      let data = this.bardata.legend;
+      data.push(this.units[0]);
+      return data;
+    },
+    areaChartData() {
+      let data = [];
+      for (var i = 0; i < this.areaData.length; i++) {
+        let item = this.areaData[i];
+        var color = item.color ? item.color : partten.getColor(item.state);
+        data.push({
+          name: item.name,
+          value: [item.start, item.end, item.end - item.start],
+          itemStyle: {
+            normal: {
+              color: color,
+            },
+          },
+          exData: item,
+        });
+      }
+      return data;
+    },
+    areaMax() {
+      let max = 0;
+      this.areaData.forEach((value) => {
+        if (max < value.end) max = value.end;
+      });
+      return max;
+    },
+  },
+  methods: {
+    renderItem(params, api) {
+      var start = api.coord([api.value(0)]);
+      var end = api.coord([api.value(1)]);
+      var height = api.size([0, 1])[1];
+
+      var rectShape = echarts.graphic.clipRectByRect(
+        {
+          x: start[0],
+          y: start[1] - height / 2,
+          width: end[0] - start[0],
+          height: height,
+        },
+        {
+          x: params.coordSys.x,
+          y: params.coordSys.y,
+          width: params.coordSys.width,
+          height: params.coordSys.height,
+        }
+      );
+
+      return (
+        rectShape && {
+          type: "rect",
+          transition: ["shape"],
+          shape: rectShape,
+          style: api.style(),
+        }
+      );
+    },
+    initChart() {
+      let that = this;
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        grid: {
+          left: 16,
+          right: 16,
+          bottom: 0,
+          top: 32,
+          containLabel: true,
+        },
+        tooltip: {
+          show: true,
+          trigger: "axis",
+          axisPointer: {
+            type: "line",
+          },
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: 14,
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.bardata.legend,
+          right: 120,
+          icon: "ract",
+          itemWidth: 8,
+          itemHeight: 8,
+          inactiveColor: partten.getColor("gray"),
+          textStyle: {
+            color: partten.getColor("grayl"),
+            fontSize: 12,
+          },
+        },
+        xAxis: [
+          {
+            type: "category",
+            axisLabel: {
+              color: partten.getColor("gray"),
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            data: this.bardata.area,
+          },
+          {
+            show: false,
+            min: 0,
+            max: this.areaMax,
+            axisLabel: {
+              show: false,
+              formatter: function(val) {
+                return Math.max(0, val - 0) + " ms";
+              },
+            },
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            name: this.units[0],
+            axisLabel: {
+              formatter: "{value} ",
+              color: partten.getColor("gray"),
+            },
+            axisLine: {
+              type: "dashed",
+              lineStyle: {
+                color: partten.getColor("gray"),
+              },
+              width: 5,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              lineStyle: {
+                type: "dashed",
+                dashOffset: 10,
+                color: partten.getColor("gray") + 80,
+              },
+            },
+          },
+          {
+            type: "value",
+            name: this.units[1],
+            axisLabel: {
+              formatter: "{value} ",
+              color: partten.getColor("gray"),
+              align: "left",
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+          {
+            data: [(this.areaData && this.areaData[0] && this.areaData[0].name) || ""],
+            axisLabel: { show: false },
+            splitLine: { show: false },
+          },
+        ],
+        series: [],
+      };
+
+      // line data
+      if (this.lineData.length) {
+        this.lineData.forEach((ele, index) => {
+          option.series.push({
+            name: this.units[index] || this.units[0] || "",
+            type: "line",
+            data: ele,
+            smooth: true, //平滑展示
+            yAxisIndex: 0,
+            lineStyle: {
+              color: this.color[index],
+            },
+            itemStyle: {
+              color: this.color[index],
+            },
+          });
+        });
+      }
+
+      // bar data
+      for (var i = 0; i < this.bardata.legend.length; i++) {
+        option.series.push({
+          name: this.bardata.legend[i],
+          type: "bar",
+          stack: "总量",
+          yAxisIndex: 1,
+          barWidth: "10%",
+          label: {
+            show: false,
+            position: "insideRight",
+          },
+          data: this.bardata.data[i],
+        });
+      }
+
+      // 区域
+      if (this.areaData && this.areaData.length > 0) {
+        option.series.push({
+          type: "custom",
+          renderItem: this.renderItem,
+          yAxisIndex: 2,
+          xAxisIndex: 1,
+          itemStyle: {
+            opacity: 0.2,
+          },
+          tooltip: {
+            show: false,
+            formatter: function(params) {
+              return params.marker + params.name + ": " + params.value[2] + "s";
+            },
+          },
+          encode: {
+            x: [1, 2],
+            y: 0,
+          },
+          data: this.areaChartData,
+        });
+      }
+
+      chart.setOption(option);
+
+      chart.on("click", function(e, p) {
+        if (e.seriesType == "custom") {
+          that.$emit("areaClick", { data: e.data.exData });
+        }
+      });
+    },
+  },
+  emits: {
+    areaClick: null,
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 484 - 0
src/components/chart/combination/area-line-chart-2.vue

@@ -0,0 +1,484 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "800px",
+    },
+    lineData: {
+      type: Array,
+      default: () => [
+        {
+          text: "日发电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+            {
+              text: "5",
+              value: 3,
+            },
+            {
+              text: "6",
+              value: 3,
+            },
+            {
+              text: "7",
+              value: 3,
+            },
+            {
+              text: "8",
+              value: 3,
+            },
+            {
+              text: "9",
+              value: 3,
+            },
+            {
+              text: "10",
+              value: 3,
+            },
+            {
+              text: "11",
+              value: 3,
+            },
+            {
+              text: "12",
+              value: 3,
+            },
+            {
+              text: "13",
+              value: 3,
+            },
+            {
+              text: "14",
+              value: 3,
+            },
+            {
+              text: "15",
+              value: 3,
+            },
+            {
+              text: "16",
+              value: 3,
+            },
+          ],
+        },
+        {
+          text: "上网电量",
+          yAxisIndex: 1,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+            {
+              text: "5",
+              value: 4,
+            },
+            {
+              text: "6",
+              value: 5,
+            },
+            {
+              text: "7",
+              value: 6,
+            },
+            {
+              text: "8",
+              value: 7,
+            },
+            {
+              text: "9",
+              value: 8,
+            },
+            {
+              text: "10",
+              value: 7,
+            },
+            {
+              text: "11",
+              value: 9,
+            },
+            {
+              text: "12",
+              value: 2,
+            },
+            {
+              text: "13",
+              value: 3,
+            },
+            {
+              text: "14",
+              value: 5,
+            },
+            {
+              text: "15",
+              value: 12,
+            },
+            {
+              text: "16",
+              value: 11,
+            },
+          ],
+        },
+      ],
+    },
+    areaData: {
+      type: Array,
+      default: () => [
+        {
+          name: "1",
+          start: 0,
+          end: 100,
+          state: "green",
+        },
+        {
+          name: "1",
+          start: 100,
+          end: 200,
+          state: "red",
+        },
+        {
+          name: "1",
+          start: 200,
+          end: 300,
+          state: "yellow",
+        },
+        {
+          name: "2",
+          start: 300,
+          end: 800,
+          state: "green",
+        },
+        {
+          name: "3",
+          start: 800,
+          end: 9000,
+          state: "green",
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["健康趋势", "风机健康状态数量"],
+    },
+    // 显示 legend
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 颜色
+    color: {
+      type: Array,
+      default: () => ["#323E6F", "#1DA0D7", "#02BB4C", "#DB5520", "#EDB32F", "#EDEB2F"],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    legend() {
+      let data = [];
+      this.lineData.forEach((value, index) => {
+        data.push(value.text);
+      });
+      return data;
+    },
+    xAxisData() {
+      let data = [];
+      if (this.lineData.length > 0)
+        this.lineData[0].value.forEach((value, index) => {
+          data.push(value.text);
+        });
+      return data;
+    },
+    yAxisData() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        let data = {
+          type: "value",
+          name: value,
+          axisLabel: {
+            formatter: "{value} ",
+            color: partten.getColor("gray"),
+          },
+          axisLine: {
+            type: "dashed",
+            lineStyle: {
+              color: partten.getColor("gray"),
+            },
+            width: 5,
+          },
+          axisTick: {
+            show: false,
+          },
+          splitLine: {
+            lineStyle: {
+              type: "dashed",
+              dashOffset: 10,
+              color: partten.getColor("gray") + 80,
+            },
+          },
+        };
+        result.push(data);
+      });
+
+      result.push({
+        data: [this.areaData[0].name],
+        axisLabel: { show: false },
+      });
+
+      return result;
+    },
+    areaChartData() {
+      let data = [];
+      for (var i = 0; i < this.areaData.length; i++) {
+        let item = this.areaData[i];
+        var color = item.state;
+        data.push({
+          name: item.name,
+          value: [item.start, item.end, item.end - item.start],
+          itemStyle: {
+            normal: {
+              color: color,
+            },
+          },
+          exData: item,
+        });
+      }
+      return data;
+    },
+    areaMax() {
+      let max = 0;
+      this.areaData.forEach((value) => {
+        if (max < value.end) max = value.end;
+      });
+      return max;
+    },
+  },
+  methods: {
+    renderItem(params, api) {
+      var start = api.coord([api.value(0)]);
+      var end = api.coord([api.value(1)]);
+      var height = api.size([0, 1])[1];
+
+      var rectShape = echarts.graphic.clipRectByRect(
+        {
+          x: start[0],
+          y: start[1] - height / 2,
+          width: end[0] - start[0],
+          height: height,
+        },
+        {
+          x: params.coordSys.x,
+          y: params.coordSys.y,
+          width: params.coordSys.width,
+          height: params.coordSys.height,
+        }
+      );
+
+      return (
+        rectShape && {
+          type: "rect",
+          transition: ["shape"],
+          shape: rectShape,
+          style: api.style(),
+        }
+      );
+    },
+    initChart() {
+      let that = this;
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        grid: {
+          left: 40,
+          right: 40,
+          bottom: 40,
+          top: 32,
+          containLabel: true,
+        },
+        tooltip: {
+          show: true,
+          trigger: "axis",
+          axisPointer: {
+            type: "cross",
+          },
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: 14,
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 120,
+          icon: "ract",
+          itemWidth: 8,
+          itemHeight: 8,
+          inactiveColor: partten.getColor("gray"),
+          textStyle: {
+            color: partten.getColor("grayl"),
+            fontSize: 12,
+          },
+        },
+        xAxis: [
+          {
+            type: "category",
+            axisLabel: {
+              color: partten.getColor("gray"),
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            data: this.xAxisData,
+          },
+          {
+            show: false,
+            min: 0,
+            max: this.areaMax,
+            axisLabel: {
+              show: false,
+              formatter: function(val) {
+                return Math.max(0, val - 0) + " ms";
+              },
+            },
+          },
+        ],
+        yAxis: this.yAxisData,
+        series: [],
+      };
+
+      // line data
+      if (this.lineData.length > 0) {
+        this.lineData.forEach((value, index) => {
+          option.series.push({
+            name: value.text,
+            type: "line",
+            data: value.value,
+            smooth: true, //平滑展示
+            yAxisIndex: value.yAxisIndex,
+            // lineStyle: {
+            //   color: partten.getColor("green"),
+            // },
+            // itemStyle: {
+            //   color: partten.getColor("green"),
+            // },
+          });
+        });
+      }
+
+      // 区域
+      if (this.areaData && this.areaData.length > 0) {
+        option.series.push({
+          type: "custom",
+          renderItem: this.renderItem,
+          yAxisIndex: this.units.length,
+          xAxisIndex: 1,
+          itemStyle: {
+            opacity: 0.2,
+          },
+          tooltip: {
+            show: false,
+            formatter: function(params) {
+              return params.marker + params.name + ": " + params.value[2] + "s";
+            },
+          },
+          encode: {
+            x: [1, 2],
+            y: 0,
+          },
+          data: this.areaChartData,
+        });
+      }
+
+      chart.setOption(option);
+
+      return chart;
+    },
+  },
+  emits: {
+    areaClick: null,
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      let that = this;
+      let chart = this.initChart();
+      chart.on("click", function(e, p) {
+        if (e.seriesType == "custom") {
+          that.$emit("areaClick", { data: e.data.exData });
+        }
+      });
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 480 - 0
src/components/chart/combination/area-line-chart.vue

@@ -0,0 +1,480 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "800px",
+    },
+    lineData: {
+      type: Array,
+      default: () => [
+        {
+          text: "日发电量",
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+            {
+              text: "5",
+              value: 3,
+            },
+            {
+              text: "6",
+              value: 3,
+            },
+            {
+              text: "7",
+              value: 3,
+            },
+            {
+              text: "8",
+              value: 3,
+            },
+            {
+              text: "9",
+              value: 3,
+            },
+            {
+              text: "10",
+              value: 3,
+            },
+            {
+              text: "11",
+              value: 3,
+            },
+            {
+              text: "12",
+              value: 3,
+            },
+            {
+              text: "13",
+              value: 3,
+            },
+            {
+              text: "14",
+              value: 3,
+            },
+            {
+              text: "15",
+              value: 3,
+            },
+            {
+              text: "16",
+              value: 3,
+            },
+          ],
+        },
+        {
+          text: "上网电量",
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+            {
+              text: "5",
+              value: 4,
+            },
+            {
+              text: "6",
+              value: 5,
+            },
+            {
+              text: "7",
+              value: 6,
+            },
+            {
+              text: "8",
+              value: 7,
+            },
+            {
+              text: "9",
+              value: 8,
+            },
+            {
+              text: "10",
+              value: 7,
+            },
+            {
+              text: "11",
+              value: 9,
+            },
+            {
+              text: "12",
+              value: 2,
+            },
+            {
+              text: "13",
+              value: 3,
+            },
+            {
+              text: "14",
+              value: 5,
+            },
+            {
+              text: "15",
+              value: 12,
+            },
+            {
+              text: "16",
+              value: 11,
+            },
+          ],
+        },
+      ],
+    },
+    areaData: {
+      type: Array,
+      default: () => [
+        {
+          name: "1",
+          start: 0,
+          end: 100,
+          state: "green",
+        },
+        {
+          name: "1",
+          start: 100,
+          end: 200,
+          state: "red",
+        },
+        {
+          name: "1",
+          start: 200,
+          end: 300,
+          state: "yellow",
+        },
+        {
+          name: "2",
+          start: 300,
+          end: 800,
+          state: "green",
+        },
+        {
+          name: "3",
+          start: 800,
+          end: 9000,
+          state: "green",
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["健康趋势", "风机健康状态数量"],
+    },
+    // 显示 legend
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 颜色
+    color: {
+      type: Array,
+      default: () => ["#323E6F", "#1DA0D7", "#02BB4C", "#DB5520", "#EDB32F", "#EDEB2F"],
+    },
+  },
+  data () {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    legend () {
+      let data = [];
+      this.lineData.forEach((value, index) => {
+        data.push(value.text);
+      });
+      return data;
+    },
+    xAxisData () {
+      let data = [];
+      if (this.lineData.length > 0)
+        this.lineData[0].value.forEach((value, index) => {
+          data.push(value.text);
+        });
+      return data;
+    },
+    areaChartData () {
+      let data = [];
+      for (var i = 0; i < this.areaData.length; i++) {
+        let item = this.areaData[i];
+        var color = item.color || item.state;
+        data.push({
+          name: item.name,
+          value: [item.start, item.end, item.end - item.start],
+          itemStyle: {
+            normal: {
+              color: color,
+            },
+          },
+          exData: item,
+        });
+      }
+      return data;
+    },
+    areaMax () {
+      let max = 0;
+      this.areaData.forEach((value) => {
+        if (max < value.end) max = value.end;
+      });
+      return max;
+    },
+  },
+  methods: {
+    renderItem (params, api) {
+      var start = api.coord([api.value(0)]);
+      var end = api.coord([api.value(1)]);
+      var height = api.size([0, 1])[1];
+
+      var rectShape = echarts.graphic.clipRectByRect(
+        {
+          x: start[0],
+          y: start[1] - height / 2,
+          width: end[0] - start[0],
+          height: height,
+        },
+        {
+          x: params.coordSys.x,
+          y: params.coordSys.y,
+          width: params.coordSys.width,
+          height: params.coordSys.height,
+        }
+      );
+
+      return (
+        rectShape && {
+          type: "rect",
+          transition: ["shape"],
+          shape: rectShape,
+          style: api.style(),
+        }
+      );
+    },
+    initChart () {
+      // console.log("units:",this.units)
+      let that = this;
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        grid: {
+          left: 40,
+          right: 40,
+          bottom: 40,
+          top: 32,
+          containLabel: true,
+        },
+        tooltip: {
+          show: true,
+          trigger: "axis",
+          axisPointer: {
+            type: "cross",
+          },
+          backgroundColor: this.$store.state.themeName === "dark" ? "rgba(0,0,0,0.4)" : "rgba(255,255,255,0.5)",
+          borderColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: 14,
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 120,
+          icon: "ract",
+          itemWidth: 8,
+          itemHeight: 8,
+          inactiveColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? partten.getColor("grayl") : "#000",
+            fontSize: 12,
+          },
+        },
+        xAxis: [
+          {
+            type: "category",
+            axisLabel: {
+              color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            data: this.xAxisData,
+          },
+          {
+            show: false,
+            min: 0,
+            max: this.areaMax,
+            axisLabel: {
+              show: false,
+              formatter: function (val) {
+                return Math.max(0, val - 0) + " ms";
+              },
+            },
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            name: this.units[0],
+            axisLabel: {
+              formatter: "{value} ",
+              color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+            },
+            axisLine: {
+              type: "dashed",
+              lineStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+              },
+              width: 5,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              lineStyle: {
+                type: "dashed",
+                dashOffset: 10,
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000" + 80,
+              },
+            },
+          },
+          {
+            data: [this.areaData[0].name],
+            axisLabel: { show: false },
+          },
+        ],
+        series: [],
+      };
+
+      // line data
+      if (this.lineData.length > 0) {
+        this.lineData.forEach((value, index) => {
+          option.series.push({
+            name: value.text,
+            type: "line",
+            data: value.value,
+            smooth: true, //平滑展示
+            yAxisIndex: 0,
+            // lineStyle: {
+            //   color: partten.getColor("green"),
+            // },
+            // itemStyle: {
+            //   color: partten.getColor("green"),
+            // },
+          });
+        });
+      }
+
+      // 区域
+      if (this.areaData && this.areaData.length > 0) {
+        option.series.push({
+          type: "custom",
+          renderItem: this.renderItem,
+          yAxisIndex: 1,
+          xAxisIndex: 1,
+          itemStyle: {
+            opacity: 0.2,
+          },
+          tooltip: {
+            show: false,
+            formatter: function (params) {
+              return params.marker + params.name + ": " + params.value[2] + "s";
+            },
+          },
+          encode: {
+            x: [1, 2],
+            y: 0,
+          },
+          data: this.areaChartData,
+        });
+      }
+
+      chart.setOption(option);
+
+      return chart;
+    },
+  },
+  emits: {
+    areaClick: null,
+  },
+  created () {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted () {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      let that = this;
+      let chart = this.initChart();
+      chart.on("click", function(e, p) {
+        if (e.seriesType == "custom") {
+          that.$emit("areaClick", { data: e.data.exData });
+        }
+      });
+    });
+  },
+  updated () {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  watch: {
+      "$store.state.themeName"() {
+        this.initChart();
+      },
+    },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 355 - 0
src/components/chart/combination/bar-line-chart.vue

@@ -0,0 +1,355 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "800px",
+    },
+    // 传入数据
+    bardata: {
+      type: Object,
+      default: () => {
+        return {
+          area: [
+            "风场1",
+            "风场2",
+            "风场3",
+            "风场4",
+            "风场5",
+            "风场6",
+            "风场7",
+            "风场8",
+            "风场9",
+          ],
+          legend: [
+            "实际电量",
+            "计划检修损失",
+            "非计划检修损失",
+            "限电损失",
+            "受累损失",
+            "性能损失",
+          ],
+          data: [
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+          ],
+        };
+      },
+    },
+    lineData: {
+      type: Array,
+      default: () => [200, 350, 400, 500, 600, 700, 800, 900, 1200],
+    },
+    lineName: {
+      type: String,
+      default: "损失电量",
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["(万kWh)", "(风速)"],
+    },
+    // 显示 legend
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 颜色
+    color: {
+      type: Array,
+      default: () => ["#323E6F", "#e17e23", "#ba3237", "#c531c7", "#ffffff", "#EDEB2F"],
+    },
+    // 每页显示个数
+    pageSize: {
+      type: Number,
+      default: 20,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      areaData: [],
+    };
+  },
+  computed: {
+    legend() {
+      return this.bardata.legend;
+    },
+    end() {
+      var result = 20;
+      if (this.areaData) {
+        result = parseInt((this.pageSize / this.areaData.length) * 100);
+      }
+      return result;
+    },
+  },
+  methods: {
+    initChart() {
+      let chart = echarts.init(this.$el);
+      let option = {
+        color: this.color,
+        grid: {
+          left: 40,
+          right: 16,
+          bottom: 16,
+          top: 16,
+          containLabel: true,
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.bardata.legend,
+          right: 56,
+          icon: "ract",
+          itemWidth: 8,
+          itemHeight: 8,
+          inactiveColor: this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark"
+              ? partten.getColor("grayl")
+              : "#000",
+            fontSize: 12,
+          },
+        },
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: this.$store.state.themeName === "dark"
+              ? "rgba(0,0,0,0.4)"
+              : "rgba(255,255,255,0.5)",
+          borderColor: this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: util.vh(16),
+          },
+        },
+        dataZoom: [
+          {
+            type: "inside",
+            start: 0,
+            end: this.end,
+            yAxisIndex: [0],
+          },
+          {
+            start: 0,
+            end: this.end,
+            bottom: 40,
+            yAxisIndex: [0],
+            backgroundColor: "transparent",
+            // handleIcon: "path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z",
+            handleStyle: {
+              color: this.$store.state.themeName === "dark"
+              ? partten.getColor("green")
+              : partten.getColor("blue"),
+            },
+            moveHandleSize: 0,
+            // dataBackground: {
+            //   lineStyle: {
+            //     color: partten.getColor("gray"),
+            //   },
+            //   areaStyle: {
+            //     color: partten.getColor("gray"),
+            //   },
+            // },
+            // selectedDataBackground: {
+            //   lineStyle: {
+            //     color: partten.getColor("yellow"),
+            //   },
+            //   areaStyle: {
+            //     color: partten.getColor("yellow"),
+            //   },
+            // },
+            fillerColor: "transparent",
+            textStyle: {
+              color: this.$store.state.themeName === "dark"
+              ? partten.getColor("grayl")
+              : "#000",
+            },
+            borderColor: this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+            brushSelect: false,
+          },
+        ],
+        yAxis: [
+          {
+            type: "category",
+            axisLabel: {
+              color: this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+            },
+            inverse: true,
+            // minInterval: 10,
+            // maxInterval: 10,
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            data: this.areaData,
+          },
+        ],
+        xAxis: [
+          {
+            type: "value",
+            axisLabel: {
+              color: this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+            },
+            axisLine: {
+              type: "dashed",
+              lineStyle: {
+                color: this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+              },
+              width: 5,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              lineStyle: {
+                type: "dashed",
+                dashOffset: 10,
+                color: this.$store.state.themeName === "dark" ? "#5a6162" : "#000" + 80,
+              },
+            },
+          },
+          {
+            type: "value",
+            name: "",
+            axisLabel: {
+              show: false,
+              // formatter: "{value}",
+              // color: partten.getColor("gray"),
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        series: [],
+      };
+
+      if (this.bardata && this.bardata.legend)
+        // bar data
+        for (var i = 0; i < this.bardata.legend.length; i++) {
+          option.series.push({
+            name: this.bardata.legend[i],
+            type: "bar",
+            stack: "总量",
+            barWidth: 16,
+            label: {
+              show: false,
+              position: "insideRight",
+            },
+            data: this.bardata.data[i],
+          });
+        }
+
+      // line data
+      if (this.lineData.length > 0) {
+        option.series.push({
+          name: this.lineName,
+          type: "line",
+          data: this.lineData,
+          smooth: false, //平滑展示
+          xAxisIndex: 1,
+          lineStyle: {
+            color: this.$store.state.themeName === "dark"
+              ? partten.getColor("green")
+              : partten.getColor("blue"),
+          },
+          itemStyle: {
+            color: this.$store.state.themeName === "dark"
+              ? partten.getColor("green")
+              : partten.getColor("blue"),
+          },
+        });
+      }
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+    if (this.bardata.area && this.bardata.area.length < this.pageSize) {
+      this.areaData = this.bardata.area;
+      for (let i = this.bardata.area.length; i <= this.pageSize; i++) {
+        this.areaData.push("");
+      }
+    }
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  beforeUpdate(){
+	  this.areaData = this.bardata.area;
+  },
+  beforeUpdate(){
+  	  this.areaData = this.bardata.area;
+  },
+  watch: {
+    bardata(val) {
+      if (val.area && val.area.length < this.pageSize) {
+        this.areaData = val.area;
+        for (let i = val.area.length; i <= this.pageSize; i++) {
+          this.areaData.push("");
+        }
+      }
+    },
+	"$store.state.themeName"() {
+	  this.initChart();
+	},
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 253 - 0
src/components/chart/combination/health-bar-line-chart.vue

@@ -0,0 +1,253 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "800px",
+    },
+    // 传入数据
+    bardata: {
+      type: Object,
+      default: () => {
+        return {
+          area: ["风场1", "风场2", "风场3", "风场4", "风场5", "风场6", "风场7", "风场8", "风场9"],
+          legend: ["实际电量", "计划检修损失", "非计划检修损失", "限电损失", "受累损失", "性能损失"],
+          data: [
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+          ],
+        };
+      },
+    },
+    lineData: {
+      type: Array,
+      // default: () => [200, 350, 400, 500, 600, 700, 800, 900, 1200],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["", "风机健康状态数量"],
+    },
+    // 显示 legend
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 颜色
+    color: {
+      type: Array,
+      default: () => ["#05bb4c", "#4b55ae", "#e17e23", "#02BB4C", "#EDB32F", "#EDEB2F"],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      newbardata:null
+    };
+  },
+    watch: {
+    bardata: {
+      handler(newValue, oldValue) {
+        console.warn(newValue);
+        this.newbardata = newValue;
+        this.initChart();
+      },
+      deep: true,
+    },
+  },
+  computed: {
+    legend() {
+      return this.newbardata.legend;
+    },
+  },
+  methods: {
+    initChart() {
+      let chart = echarts.init(this.$el);
+      let option = {
+        color: this.color,
+        grid: {
+          left: 16,
+          right: 16,
+          bottom: 0,
+          top: 32,
+          containLabel: true,
+        },
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: 14,
+          },
+          // formatter: function(param) {
+          //   return param.name + "<br >" + param.marker + param.seriesName + ":" + param.value;
+          // },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.newbardata.legend,
+          right: 120,
+          icon: "ract",
+          itemWidth: 8,
+          itemHeight: 8,
+          inactiveColor: partten.getColor("gray"),
+          textStyle: {
+            color: partten.getColor("grayl"),
+            fontSize: 12,
+          },
+        },
+        xAxis: [
+          {
+            type: "category",
+            axisLabel: {
+              color: partten.getColor("gray"),
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            data: this.newbardata.area,
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            min: function(value){
+               return (value.min-1)%1==0?value.min-1:(value.min-1).toFixed(0);
+            },
+            max: function(value){
+               return value.max; 
+            },
+            name: this.units[0],
+            axisLabel: {
+              formatter: "{value} ",
+              color: partten.getColor("gray"),
+            },
+            axisLine: {
+              type: "dashed",
+              lineStyle: {
+                color: partten.getColor("gray"),
+              },
+              width: 5,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              lineStyle: {
+                type: "dashed",
+                dashOffset: 10,
+                color: partten.getColor("gray") + 80,
+              },
+            },
+          },
+          {
+            type: "value",
+            name: this.units[1],
+            axisLabel: {
+              formatter: "{value} ",
+              color: partten.getColor("gray"),
+              align: "left",
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        series: [],
+      };
+
+      // line data
+      if (this.lineData.length > 0) {
+        option.series.push({
+          name: this.units[0],
+          type: "line",
+          data: this.lineData,
+          smooth: false, //平滑展示
+          yAxisIndex: 0,
+          lineStyle: {
+            // color: partten.getColor("green"),
+            color: "#1a93cf",
+          },
+          itemStyle: {
+            // color: partten.getColor("green"),
+            color: "#1a93cf",
+          },
+        });
+      }
+
+      // bar data
+      for (var i = 0; i < this.newbardata.legend.length; i++) {
+        option.series.push({
+          name: this.newbardata.legend[i],
+          type: "bar",
+          stack: "总量",
+          yAxisIndex: 1,
+          barWidth: "10%",
+          label: {
+            show: false,
+            position: "insideRight",
+          },
+          data: this.newbardata.data[i],
+        });
+      }
+
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+    this.newbardata = this.bardata
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 437 - 0
src/components/chart/combination/multiple-bar-line-chart.vue

@@ -0,0 +1,437 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 传入数据
+    barData: {
+      type: Array,
+      default: () => [
+        {
+          title: "日发电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 2,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 3,
+            },
+            {
+              text: "5日",
+              value: 3,
+            },
+            {
+              text: "6日",
+              value: 3,
+            },
+            {
+              text: "7日",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "上网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 2,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 3,
+            },
+            {
+              text: "5日",
+              value: 3,
+            },
+            {
+              text: "6日",
+              value: 3,
+            },
+            {
+              text: "7日",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "购网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 2,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 3,
+            },
+            {
+              text: "5日",
+              value: 3,
+            },
+            {
+              text: "6日",
+              value: 3,
+            },
+            {
+              text: "7日",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "风速",
+          yAxisIndex: 1,
+          value: [
+            {
+              text: "1日",
+              value: 1,
+            },
+            {
+              text: "2日",
+              value: 2,
+            },
+            {
+              text: "3日",
+              value: 1,
+            },
+            {
+              text: "4日",
+              value: 3,
+            },
+            {
+              text: "5日",
+              value: 3,
+            },
+            {
+              text: "6日",
+              value: 3,
+            },
+            {
+              text: "7日",
+              value: 3,
+            },
+          ],
+        },
+      ],
+    },
+    lineData: {
+      type: Object,
+      default: () => {
+        return {
+          name: "风速",
+          unit: "km",
+          data: [200, 800, 400, 500, 800, 700, 800, 900, 200],
+        };
+      },
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["(万kWh)", "(风速)"],
+    },
+    // 显示 legend
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 颜色
+    color: {
+      type: Array,
+      default: () => [
+        "#05bb4c",
+        "#4b55ae",
+        "#fa8c16",
+        "#f8de5b",
+        "#1a93cf",
+        "#c531c7",
+        "#bd3338",
+      ],
+    },
+    showAnimation: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      firstAnimation: true,
+      newbarData: null,
+    };
+  },
+  watch: {
+    barData: {
+      handler(newValue, oldValue) {
+        this.newbarData = newValue;
+        this.initChart();
+      },
+      deep: true,
+    },
+    lineData : {
+      handler(newValue, oldValue) {
+        this.newlineData = newValue;
+        this.initChart();
+      },
+      deep: true,
+    },
+	"$store.state.themeName"() {
+	  this.initChart();
+	},
+  },
+  computed: {
+    legend() {
+      return this.newbarData.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      let result = [];
+      if (
+        this.newbarData &&
+        this.newbarData.length > 0 &&
+        this.newbarData[0].value.length > 0
+      ) {
+        result = this.newbarData[0].value.map((t) => {
+          return t.text;
+        });
+      }
+      return result;
+    },
+    ydata() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        let data = null;
+        if (index == 0) {
+          data = {
+            type: "value",
+            name: value,
+            axisLabel: {
+              formatter: "{value} ",
+              fontSize: 12,
+            },
+            //分格线
+            splitLine: {
+              lineStyle: {
+                color: "#5a6162",
+                type: "dashed",
+              },
+            },
+          };
+        } else {
+          data = {
+            type: "value",
+            name: value,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: 12,
+            },
+            //分格线
+            splitLine: {
+              show: false,
+            },
+          };
+        }
+
+        result.push(data);
+      });
+
+      return result;
+    },
+    series() {
+      let result = [];
+      if (this.newbarData && this.newbarData.length > 0) {
+        this.newbarData.forEach((value, index) => {
+          result.push({
+            name: value.title,
+            type: "bar",
+            barWidth: "10%",
+            animation: this.firstAnimation && this.showAnimation,
+            yAxisIndex: value.yAxisIndex,
+            data: value.value.map((t) => {
+              return t.value;
+            }),
+          });
+        });
+      }
+      return result;
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: this.$store.state.themeName === "dark" ? "rgba(0,0,0,0.4)" : "rgba(255,255,255,0.5)",
+          borderColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: 12,
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "ract",
+          itemWidth: 8,
+          itemHeight: 8,
+          inactiveColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? partten.getColor("grayl") : "#000",
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: 32,
+          left: 40,
+          right: this.ydata.length > 1 ? 40 : 14,
+          bottom: 24,
+        },
+        xAxis: [
+          {
+            type: "category",
+            data: this.xdata,
+            axisPointer: {
+              type: "shadow",
+            },
+            axisLabel: {
+              fontSize: 12,
+            },
+          },
+        ],
+        yAxis: this.ydata,
+        series: this.series,
+      };
+
+      // line data
+      if (this.newlineData && this.newlineData.data.length > 0) {
+        option.yAxis.push({
+          type: "value",
+          name: this.newlineData.name,
+          axisLabel: {
+            formatter: "{value} ",
+            color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          },
+          axisLine: {
+            show: false,
+          },
+          axisTick: {
+            show: false,
+          },
+          splitLine: {
+            show: false,
+            lineStyle: {
+              type: "dashed",
+              dashOffset: 10,
+              color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000" + 80,
+            },
+          },
+        });
+
+        option.series.push({
+          name: this.newlineData.name,
+          type: "line",
+          data: this.newlineData.data,
+          smooth: true, //平滑展示
+          yAxisIndex: option.yAxis.length - 1,
+          lineStyle: {
+            color: partten.getColor("yellow"),
+          },
+          itemStyle: {
+            color: partten.getColor("yellow"),
+          },
+        });
+      }
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+    this.newbarData = this.barData;
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+      this.firstAnimation = false;
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 804 - 0
src/components/chart/combination/scatter-line-chart.vue

@@ -0,0 +1,804 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "350px",
+    },
+    // 传入数据
+    data: {
+      type: Array,
+      default: () => [
+        {
+          title: "男",
+          value: [
+            [161.2, 51.6],
+            [167.5, 59.0],
+            [159.5, 49.2],
+            [157.0, 63.0],
+            [155.8, 53.6],
+            [170.0, 59.0],
+            [159.1, 47.6],
+            [166.0, 69.8],
+            [176.2, 66.8],
+            [160.2, 75.2],
+            [172.5, 55.2],
+            [170.9, 54.2],
+            [172.9, 62.5],
+            [153.4, 42.0],
+            [160.0, 50.0],
+            [147.2, 49.8],
+            [168.2, 49.2],
+            [175.0, 73.2],
+            [157.0, 47.8],
+            [167.6, 68.8],
+            [159.5, 50.6],
+            [175.0, 82.5],
+            [166.8, 57.2],
+            [176.5, 87.8],
+            [170.2, 72.8],
+            [174.0, 54.5],
+            [173.0, 59.8],
+            [179.9, 67.3],
+            [170.5, 67.8],
+            [160.0, 47.0],
+            [154.4, 46.2],
+            [162.0, 55.0],
+            [176.5, 83.0],
+            [160.0, 54.4],
+            [152.0, 45.8],
+            [162.1, 53.6],
+            [170.0, 73.2],
+            [160.2, 52.1],
+            [161.3, 67.9],
+            [166.4, 56.6],
+            [168.9, 62.3],
+            [163.8, 58.5],
+            [167.6, 54.5],
+            [160.0, 50.2],
+            [161.3, 60.3],
+            [167.6, 58.3],
+            [165.1, 56.2],
+            [160.0, 50.2],
+            [170.0, 72.9],
+            [157.5, 59.8],
+            [167.6, 61.0],
+            [160.7, 69.1],
+            [163.2, 55.9],
+            [152.4, 46.5],
+            [157.5, 54.3],
+            [168.3, 54.8],
+            [180.3, 60.7],
+            [165.5, 60.0],
+            [165.0, 62.0],
+            [164.5, 60.3],
+            [156.0, 52.7],
+            [160.0, 74.3],
+            [163.0, 62.0],
+            [165.7, 73.1],
+            [161.0, 80.0],
+            [162.0, 54.7],
+            [166.0, 53.2],
+            [174.0, 75.7],
+            [172.7, 61.1],
+            [167.6, 55.7],
+            [151.1, 48.7],
+            [164.5, 52.3],
+            [163.5, 50.0],
+            [152.0, 59.3],
+            [169.0, 62.5],
+            [164.0, 55.7],
+            [161.2, 54.8],
+            [155.0, 45.9],
+            [170.0, 70.6],
+            [176.2, 67.2],
+            [170.0, 69.4],
+            [162.5, 58.2],
+            [170.3, 64.8],
+            [164.1, 71.6],
+            [169.5, 52.8],
+            [163.2, 59.8],
+            [154.5, 49.0],
+            [159.8, 50.0],
+            [173.2, 69.2],
+            [170.0, 55.9],
+            [161.4, 63.4],
+            [169.0, 58.2],
+            [166.2, 58.6],
+            [159.4, 45.7],
+            [162.5, 52.2],
+            [159.0, 48.6],
+            [162.8, 57.8],
+            [159.0, 55.6],
+            [179.8, 66.8],
+            [162.9, 59.4],
+            [161.0, 53.6],
+            [151.1, 73.2],
+            [168.2, 53.4],
+            [168.9, 69.0],
+            [173.2, 58.4],
+            [171.8, 56.2],
+            [178.0, 70.6],
+            [164.3, 59.8],
+            [163.0, 72.0],
+            [168.5, 65.2],
+            [166.8, 56.6],
+            [172.7, 105.2],
+            [163.5, 51.8],
+            [169.4, 63.4],
+            [167.8, 59.0],
+            [159.5, 47.6],
+            [167.6, 63.0],
+            [161.2, 55.2],
+            [160.0, 45.0],
+            [163.2, 54.0],
+            [162.2, 50.2],
+            [161.3, 60.2],
+            [149.5, 44.8],
+            [157.5, 58.8],
+            [163.2, 56.4],
+            [172.7, 62.0],
+            [155.0, 49.2],
+            [156.5, 67.2],
+            [164.0, 53.8],
+            [160.9, 54.4],
+            [162.8, 58.0],
+            [167.0, 59.8],
+            [160.0, 54.8],
+            [160.0, 43.2],
+            [168.9, 60.5],
+            [158.2, 46.4],
+            [156.0, 64.4],
+            [160.0, 48.8],
+            [167.1, 62.2],
+            [158.0, 55.5],
+            [167.6, 57.8],
+            [156.0, 54.6],
+            [162.1, 59.2],
+            [173.4, 52.7],
+            [159.8, 53.2],
+            [170.5, 64.5],
+            [159.2, 51.8],
+            [157.5, 56.0],
+            [161.3, 63.6],
+            [162.6, 63.2],
+            [160.0, 59.5],
+            [168.9, 56.8],
+            [165.1, 64.1],
+            [162.6, 50.0],
+            [165.1, 72.3],
+            [166.4, 55.0],
+            [160.0, 55.9],
+            [152.4, 60.4],
+            [170.2, 69.1],
+            [162.6, 84.5],
+            [170.2, 55.9],
+            [158.8, 55.5],
+            [172.7, 69.5],
+            [167.6, 76.4],
+            [162.6, 61.4],
+            [167.6, 65.9],
+            [156.2, 58.6],
+            [175.2, 66.8],
+            [172.1, 56.6],
+            [162.6, 58.6],
+            [160.0, 55.9],
+            [165.1, 59.1],
+            [182.9, 81.8],
+            [166.4, 70.7],
+            [165.1, 56.8],
+            [177.8, 60.0],
+            [165.1, 58.2],
+            [175.3, 72.7],
+            [154.9, 54.1],
+            [158.8, 49.1],
+            [172.7, 75.9],
+            [168.9, 55.0],
+            [161.3, 57.3],
+            [167.6, 55.0],
+            [165.1, 65.5],
+            [175.3, 65.5],
+            [157.5, 48.6],
+            [163.8, 58.6],
+            [167.6, 63.6],
+            [165.1, 55.2],
+            [165.1, 62.7],
+            [168.9, 56.6],
+            [162.6, 53.9],
+            [164.5, 63.2],
+            [176.5, 73.6],
+            [168.9, 62.0],
+            [175.3, 63.6],
+            [159.4, 53.2],
+            [160.0, 53.4],
+            [170.2, 55.0],
+            [162.6, 70.5],
+            [167.6, 54.5],
+            [162.6, 54.5],
+            [160.7, 55.9],
+            [160.0, 59.0],
+            [157.5, 63.6],
+            [162.6, 54.5],
+            [152.4, 47.3],
+            [170.2, 67.7],
+            [165.1, 80.9],
+            [172.7, 70.5],
+            [165.1, 60.9],
+            [170.2, 63.6],
+            [170.2, 54.5],
+            [170.2, 59.1],
+            [161.3, 70.5],
+            [167.6, 52.7],
+            [167.6, 62.7],
+            [165.1, 86.3],
+            [162.6, 66.4],
+            [152.4, 67.3],
+            [168.9, 63.0],
+            [170.2, 73.6],
+            [175.2, 62.3],
+            [175.2, 57.7],
+            [160.0, 55.4],
+            [165.1, 104.1],
+            [174.0, 55.5],
+            [170.2, 77.3],
+            [160.0, 80.5],
+            [167.6, 64.5],
+            [167.6, 72.3],
+            [167.6, 61.4],
+            [154.9, 58.2],
+            [162.6, 81.8],
+            [175.3, 63.6],
+            [171.4, 53.4],
+            [157.5, 54.5],
+            [165.1, 53.6],
+            [160.0, 60.0],
+            [174.0, 73.6],
+            [162.6, 61.4],
+            [174.0, 55.5],
+            [162.6, 63.6],
+            [161.3, 60.9],
+            [156.2, 60.0],
+            [149.9, 46.8],
+            [169.5, 57.3],
+            [160.0, 64.1],
+            [175.3, 63.6],
+            [169.5, 67.3],
+            [160.0, 75.5],
+            [172.7, 68.2],
+            [162.6, 61.4],
+            [157.5, 76.8],
+            [176.5, 71.8],
+            [164.4, 55.5],
+            [160.7, 48.6],
+            [174.0, 66.4],
+            [163.8, 67.3],
+          ],
+        },
+        {
+          title: "女",
+          value: [
+            [174.0, 65.6],
+            [175.3, 71.8],
+            [193.5, 80.7],
+            [186.5, 72.6],
+            [187.2, 78.8],
+            [181.5, 74.8],
+            [184.0, 86.4],
+            [184.5, 78.4],
+            [175.0, 62.0],
+            [184.0, 81.6],
+            [180.0, 76.6],
+            [177.8, 83.6],
+            [192.0, 90.0],
+            [176.0, 74.6],
+            [174.0, 71.0],
+            [184.0, 79.6],
+            [192.7, 93.8],
+            [171.5, 70.0],
+            [173.0, 72.4],
+            [176.0, 85.9],
+            [176.0, 78.8],
+            [180.5, 77.8],
+            [172.7, 66.2],
+            [176.0, 86.4],
+            [173.5, 81.8],
+            [178.0, 89.6],
+            [180.3, 82.8],
+            [180.3, 76.4],
+            [164.5, 63.2],
+            [173.0, 60.9],
+            [183.5, 74.8],
+            [175.5, 70.0],
+            [188.0, 72.4],
+            [189.2, 84.1],
+            [172.8, 69.1],
+            [170.0, 59.5],
+            [182.0, 67.2],
+            [170.0, 61.3],
+            [177.8, 68.6],
+            [184.2, 80.1],
+            [186.7, 87.8],
+            [171.4, 84.7],
+            [172.7, 73.4],
+            [175.3, 72.1],
+            [180.3, 82.6],
+            [182.9, 88.7],
+            [188.0, 84.1],
+            [177.2, 94.1],
+            [172.1, 74.9],
+            [167.0, 59.1],
+            [169.5, 75.6],
+            [174.0, 86.2],
+            [172.7, 75.3],
+            [182.2, 87.1],
+            [164.1, 55.2],
+            [163.0, 57.0],
+            [171.5, 61.4],
+            [184.2, 76.8],
+            [174.0, 86.8],
+            [174.0, 72.2],
+            [177.0, 71.6],
+            [186.0, 84.8],
+            [167.0, 68.2],
+            [171.8, 66.1],
+            [182.0, 72.0],
+            [167.0, 64.6],
+            [177.8, 74.8],
+            [164.5, 70.0],
+            [192.0, 101.6],
+            [175.5, 63.2],
+            [171.2, 79.1],
+            [181.6, 78.9],
+            [167.4, 67.7],
+            [181.1, 66.0],
+            [177.0, 68.2],
+            [174.5, 63.9],
+            [177.5, 72.0],
+            [170.5, 56.8],
+            [182.4, 74.5],
+            [197.1, 90.9],
+            [180.1, 93.0],
+            [175.5, 80.9],
+            [180.6, 72.7],
+            [184.4, 68.0],
+            [175.5, 70.9],
+            [180.6, 72.5],
+            [177.0, 72.5],
+            [177.1, 83.4],
+            [181.6, 75.5],
+            [176.5, 73.0],
+            [175.0, 70.2],
+            [174.0, 73.4],
+            [165.1, 70.5],
+            [177.0, 68.9],
+            [192.0, 102.3],
+            [176.5, 68.4],
+            [169.4, 65.9],
+            [182.1, 75.7],
+            [179.8, 84.5],
+            [175.3, 87.7],
+            [184.9, 86.4],
+            [177.3, 73.2],
+            [167.4, 53.9],
+            [178.1, 72.0],
+            [168.9, 55.5],
+            [157.2, 58.4],
+            [180.3, 83.2],
+            [170.2, 72.7],
+            [177.8, 64.1],
+            [172.7, 72.3],
+            [165.1, 65.0],
+            [186.7, 86.4],
+            [165.1, 65.0],
+            [174.0, 88.6],
+            [175.3, 84.1],
+            [185.4, 66.8],
+            [177.8, 75.5],
+            [180.3, 93.2],
+            [180.3, 82.7],
+            [177.8, 58.0],
+            [177.8, 79.5],
+            [177.8, 78.6],
+            [177.8, 71.8],
+            [177.8, 116.4],
+            [163.8, 72.2],
+            [188.0, 83.6],
+            [198.1, 85.5],
+            [175.3, 90.9],
+            [166.4, 85.9],
+            [190.5, 89.1],
+            [166.4, 75.0],
+            [177.8, 77.7],
+            [179.7, 86.4],
+            [172.7, 90.9],
+            [190.5, 73.6],
+            [185.4, 76.4],
+            [168.9, 69.1],
+            [167.6, 84.5],
+            [175.3, 64.5],
+            [170.2, 69.1],
+            [190.5, 108.6],
+            [177.8, 86.4],
+            [190.5, 80.9],
+            [177.8, 87.7],
+            [184.2, 94.5],
+            [176.5, 80.2],
+            [177.8, 72.0],
+            [180.3, 71.4],
+            [171.4, 72.7],
+            [172.7, 84.1],
+            [172.7, 76.8],
+            [177.8, 63.6],
+            [177.8, 80.9],
+            [182.9, 80.9],
+            [170.2, 85.5],
+            [167.6, 68.6],
+            [175.3, 67.7],
+            [165.1, 66.4],
+            [185.4, 102.3],
+            [181.6, 70.5],
+            [172.7, 95.9],
+            [190.5, 84.1],
+            [179.1, 87.3],
+            [175.3, 71.8],
+            [170.2, 65.9],
+            [193.0, 95.9],
+            [171.4, 91.4],
+            [177.8, 81.8],
+            [177.8, 96.8],
+            [167.6, 69.1],
+            [167.6, 82.7],
+            [180.3, 75.5],
+            [182.9, 79.5],
+            [176.5, 73.6],
+            [186.7, 91.8],
+            [188.0, 84.1],
+            [188.0, 85.9],
+            [177.8, 81.8],
+            [174.0, 82.5],
+            [177.8, 80.5],
+            [171.4, 70.0],
+            [185.4, 81.8],
+            [185.4, 84.1],
+            [188.0, 90.5],
+            [188.0, 91.4],
+            [182.9, 89.1],
+            [176.5, 85.0],
+            [175.3, 69.1],
+            [175.3, 73.6],
+            [188.0, 80.5],
+            [188.0, 82.7],
+            [175.3, 86.4],
+            [170.5, 67.7],
+            [179.1, 92.7],
+            [177.8, 93.6],
+            [175.3, 70.9],
+            [182.9, 75.0],
+            [170.8, 93.2],
+            [188.0, 93.2],
+            [180.3, 77.7],
+            [177.8, 61.4],
+            [185.4, 94.1],
+            [168.9, 75.0],
+            [185.4, 83.6],
+            [180.3, 85.5],
+            [174.0, 73.9],
+            [167.6, 66.8],
+            [182.9, 87.3],
+            [160.0, 72.3],
+            [180.3, 88.6],
+            [167.6, 75.5],
+            [186.7, 101.4],
+            [175.3, 91.1],
+            [175.3, 67.3],
+            [175.9, 77.7],
+            [175.3, 81.8],
+            [179.1, 75.5],
+            [181.6, 84.5],
+            [177.8, 76.6],
+            [182.9, 85.0],
+            [177.8, 102.5],
+            [184.2, 77.3],
+            [179.1, 71.8],
+            [176.5, 87.9],
+            [188.0, 94.3],
+            [174.0, 70.9],
+            [167.6, 64.5],
+            [170.2, 77.3],
+            [167.6, 72.3],
+            [188.0, 87.3],
+            [174.0, 80.0],
+            [176.5, 82.3],
+            [180.3, 73.6],
+            [167.6, 74.1],
+            [188.0, 85.9],
+            [180.3, 73.2],
+            [167.6, 76.3],
+            [183.0, 65.9],
+            [183.0, 90.9],
+            [179.1, 89.1],
+            [170.2, 62.3],
+            [177.8, 82.7],
+            [179.1, 79.1],
+            [190.5, 98.2],
+            [177.8, 84.1],
+            [180.3, 83.2],
+            [180.3, 83.2],
+          ],
+        },
+      ],
+    },
+    xTitle: {
+      type: String,
+      default: "x轴标题",
+    },
+    yTitle: {
+      type: String,
+      default: "Y轴标题",
+    },
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    lineData: {
+      type: Object,
+      default: () => {
+        return {
+          xTitle: "折线X",
+          yTitle: "折线y",
+          legends: ["1", "2", "3"],
+          data: [[1, 2, 3, 4]],
+        };
+      },
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#f8de5b", "#4b55ae", "#fa8c16"],
+    };
+  },
+  computed: {
+    series() {
+      let result = [];
+      this.data.forEach((element, index) => {
+        result.push({
+          name: element.title,
+          type: "scatter",
+          emphasis: {
+            focus: "series",
+          },
+          data: element.value,
+          markLine: {
+            data: [
+              {
+                type: "max",
+                name: "最大值",
+                label: {
+                  color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+                },
+              },
+              {
+                type: "min",
+                name: "最小值",
+                label: {
+                  color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+                },
+              },
+            ],
+          },
+        });
+      });
+      return result;
+    },
+    legend() {
+      let result = [];
+
+      // if (this.data && this.data.length > 0)
+      //   result.push(
+      //     this.data.map((t) => {
+      //       return t.title;
+      //     })
+      //   );
+
+      // if (this.lineData && this.lineData.legends && this.lineData.legends.legends > 0) result.push(this.lineData.legends);
+
+      this.data.forEach((ele) => {
+        result.push(ele.title);
+      });
+
+      this.lineData.legends.forEach((ele) => {
+        result.push(ele);
+      });
+
+      return result;
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      let that = this;
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        grid: {
+          top: 40,
+          left: 40,
+          right: 64,
+          bottom: 24,
+          containLabel: true,
+        },
+        tooltip: {
+          trigger: "item",
+          showDelay: 0,
+          backgroundColor: this.$store.state.themeName === "dark" ? "rgba(0,0,0,0.4)" : "rgba(255,255,255,0.5)",
+          borderColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            fontSize: util.vh(16),
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+          },
+          formatter(params) {
+            if (params.componentType == "markLine") {
+              return params.name + "<br />" + params.value;
+            }
+            var msg = params.seriesName + "<br />";
+            msg +=
+              params.marker + that.xTitle + ":" + params.value[0] + "<br />";
+            msg +=
+              params.marker + that.yTitle + ":" + params.value[1] + "<br />";
+            return msg;
+          },
+          axisPointer: {
+            show: true,
+            type: "cross",
+            lineStyle: {
+              type: "dashed",
+              width: 1,
+            },
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: "40",
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? partten.getColor("grayl") : "#000",
+            fontSize: 12,
+          },
+        },
+        xAxis: [
+          {
+            name: this.xTitle,
+            type: "value",
+            scale: true,
+            axisLabel: {
+              formatter: "{value}",
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        yAxis: [
+          {
+            min: 0,
+            type: "value",
+            name: this.yTitle,
+            scale: true,
+            axisLabel: {
+              formatter: "{value}",
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        series: this.series,
+      };
+
+      if (this.lineData && this.lineData.data) {
+        option.xAxis.push({
+          type: "category",
+          // name: this.lineData.xTitle,
+          boundaryGap: false,
+          axisLabel: {
+            show: false,
+          },
+          axisLine: {
+            show: false,
+          },
+          data: this.lineData.legends,
+        });
+
+        option.yAxis.push({
+          type: "value",
+          // name: this.lineData.yTitle,
+          axisLabel: {
+            show: false,
+          },
+          axisLine: {
+            show: false,
+          },
+          //分格线
+          splitLine: {
+            show: false,
+          },
+        });
+
+        this.lineData.data.forEach((value, index) => {
+          option.series.push({
+            name: this.lineData.legends[index],
+            type: "line",
+            smooth: true,
+            showSymbol: false,
+            zlevel: index,
+            lineStyle: {
+              show: false,
+            },
+            yAxisIndex: 0,
+            xAxisIndex: 1,
+            data: value,
+          });
+        });
+      }
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+  watch: {
+      "$store.state.themeName"() {
+        this.initChart();
+      },
+    },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 247 - 0
src/components/chart/combination/vertival-bar-line-chart.vue

@@ -0,0 +1,247 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "800px",
+    },
+    // 传入数据
+    bardata: {
+      type: Object,
+      default: () => {
+        return {
+          area: ["风场1", "风场2", "风场3", "风场4", "风场5", "风场6", "风场7", "风场8", "风场9"],
+          legend: ["实际电量", "计划检修损失", "非计划检修损失", "限电损失", "受累损失", "性能损失"],
+          data: [
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+          ],
+        };
+      },
+    },
+    lineData: {
+      type: Array,
+      // default: () => [200, 350, 400, 500, 600, 700, 800, 900, 1200],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["", "风机健康状态数量"],
+    },
+    // 显示 legend
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 颜色
+    color: {
+      type: Array,
+      default: () => ["#05bb4c", "#4b55ae", "#e17e23", "#02BB4C", "#EDB32F", "#EDEB2F"],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      newbardata:null
+    };
+  },
+    watch: {
+    bardata: {
+      handler(newValue, oldValue) {
+        console.warn(newValue);
+        this.newbardata = newValue;
+        this.initChart();
+      },
+      deep: true,
+    },
+	"$store.state.themeName"() {
+	  this.initChart();
+	},
+  },
+  computed: {
+    legend() {
+      return this.newbardata.legend;
+    },
+  },
+  methods: {
+    initChart() {
+      let chart = echarts.init(this.$el);
+      let option = {
+        color: this.color,
+        grid: {
+          left: 16,
+          right: 16,
+          bottom: 0,
+          top: 32,
+          containLabel: true,
+        },
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: this.$store.state.themeName === "dark" ? "rgba(0,0,0,0.4)" : "rgba(255,255,255,0.5)",
+          borderColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: 14,
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.newbardata.legend,
+          right: 120,
+          icon: "ract",
+          itemWidth: 8,
+          itemHeight: 8,
+          inactiveColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? partten.getColor("grayl") : "#000",
+            fontSize: 12,
+          },
+        },
+        xAxis: [
+          {
+            type: "category",
+            axisLabel: {
+              color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            data: this.newbardata.area,
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            name: this.units[0],
+            axisLabel: {
+              formatter: "{value} ",
+              color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+            },
+            axisLine: {
+              type: "dashed",
+              lineStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+              },
+              width: 5,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              lineStyle: {
+                type: "dashed",
+                dashOffset: 10,
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000" + 80,
+              },
+            },
+          },
+          {
+            type: "value",
+            name: this.units[1],
+            axisLabel: {
+              formatter: "{value} ",
+              color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+              align: "left",
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        series: [],
+      };
+
+      // line data
+      // if (this.lineData.length > 0) {
+      //   option.series.push({
+      //     name: this.units[0],
+      //     type: "line",
+      //     data: this.lineData,
+      //     smooth: false, //平滑展示
+      //     yAxisIndex: 0,
+      //     lineStyle: {
+      //       // color: partten.getColor("green"),
+      //       color: "#323E6F",
+      //     },
+      //     itemStyle: {
+      //       // color: partten.getColor("green"),
+      //       color: "#323E6F",
+      //     },
+      //   });
+      // }
+
+      // bar data
+      for (var i = 0; i < this.newbardata.legend.length; i++) {
+        option.series.push({
+          name: this.newbardata.legend[i],
+          type: "bar",
+          stack: "总量",
+          yAxisIndex: 1,
+          barWidth: "10%",
+          label: {
+            show: false,
+            position: "insideRight",
+          },
+          data: this.newbardata.data[i],
+        });
+      }
+
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+    this.newbardata = this.bardata
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 301 - 0
src/components/chart/line/arrow-dash-line-chart.vue

@@ -0,0 +1,301 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multi-arrow-line-chart",
+  componentName: "multi-arrow-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "功率",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "0m/s",
+              value: 1,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "2m/s",
+              value: 2,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "3m/s",
+              value: 16,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "4m/s",
+              value: 3,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "5m/s",
+              value: 3,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "6m/s",
+              value: 31,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "7m/s",
+              value: 33,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "8m/s",
+              value: 43,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "9m/s",
+              value: 3,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "10m/s",
+              value: 3,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "11m/s",
+              value: 31,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "12m/s",
+              value: 3,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+            {
+              text: "13m/s",
+              value: 3,
+              show: true,
+              size: 12,
+              route: -90,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["()"],
+    },
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#606769"],
+    };
+  },
+  computed: {
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      return this.list[0].value.map((t) => {
+        return t.text;
+      });
+    },
+    yAxis() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        result.push({
+          type: "value",
+          name: value,
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: util.vh(14),
+          },
+          //分格线
+          splitLine: {
+            lineStyle: {
+              color: partten.getColor("gray") + 55,
+              type: "dashed",
+            },
+          },
+        });
+      });
+
+      return result;
+    },
+    series() {
+      let result = [];
+
+      this.list.forEach((value, index) => {
+        var data = value.value.map((t) => {
+          return t.value;
+        });
+
+        var arrowArr = [];
+        data.forEach((dvalue, dindex) => {
+          var item = dvalue;
+          if (value.value[dindex].show) {
+            arrowArr.push({
+              symbol: "arrow",
+              symbolSize: value.value[dindex].size,
+              symbolRotate: value.value[dindex].route,
+              value: item,
+            });
+          } else {
+            arrowArr.push({ symbol: "none", value: item });
+          }
+        });
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: true,
+          zlevel: index,
+          lineStyle: {
+            type: "dotted", //dashed
+          },
+          yAxisIndex: value.yAxisIndex,
+          data: arrowArr,
+        });
+      });
+
+      return result;
+    },
+  },
+  methods: {
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: util.vh(16),
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: partten.getColor("gray"),
+          textStyle: {
+            color: partten.getColor("grayl"),
+            fontsize: 12,
+          },
+        },
+        grid: {
+          top: util.vh(32),
+          left: util.vh(40),
+          right: util.vh(40),
+          bottom: util.vh(24),
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: util.vh(14),
+              textStyle: {
+                color: partten.getColor("gray"),
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function() {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 304 - 0
src/components/chart/line/arrow-line-chart.vue

@@ -0,0 +1,304 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "normal-line-chart",
+  componentName: "normal-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "日发电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+            {
+              text: "5",
+              value: 3,
+            },
+            {
+              text: "6",
+              value: 3,
+            },
+            {
+              text: "7",
+              value: 3,
+            },
+            {
+              text: "8",
+              value: 3,
+            },
+            {
+              text: "9",
+              value: 3,
+            },
+            {
+              text: "10",
+              value: 3,
+            },
+            {
+              text: "11",
+              value: 3,
+            },
+            {
+              text: "12",
+              value: 3,
+            },
+            {
+              text: "13",
+              value: 3,
+            },
+            {
+              text: "14",
+              value: 3,
+            },
+            {
+              text: "15",
+              value: 3,
+            },
+            {
+              text: "16",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "上网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+            {
+              text: "5",
+              value: 2,
+            },
+            {
+              text: "6",
+              value: 2,
+            },
+            {
+              text: "7",
+              value: 2,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["(MW)"],
+    },
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b"],
+    };
+  },
+  computed: {
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      return this.list[0].value.map((t) => {
+        return t.text;
+      });
+    },
+    yAxis() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        result.push({
+          type: "value",
+          name: value,
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: util.vh(14),
+          },
+          //分格线
+          splitLine: {
+            lineStyle: {
+              color: partten.getColor("gray") + 55,
+              type: "dashed",
+            },
+          },
+        });
+      });
+
+      return result;
+    },
+    series() {
+      let result = [];
+
+      this.list.forEach((value, index) => {
+        var data = value.value.map((t) => {
+          return t.value;
+        });
+        const lastvalue = data[data.length - 1];
+        data[data.length - 1] = {
+          symbol: "arrow",
+          symbolSize: 12,
+          symbolRotate: -90,
+          value: lastvalue,
+        };
+
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: true,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              color: this.color[index],
+              width: 1,
+            },
+          },
+          yAxisIndex: value.yAxisIndex,
+          data: data,
+        });
+      });
+
+      return result;
+    },
+  },
+  methods: {
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: util.vh(16),
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: partten.getColor("gray"),
+          textStyle: {
+            color: partten.getColor("grayl"),
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: util.vh(32),
+          left: util.vh(40),
+          right: util.vh(40),
+          bottom: util.vh(24),
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: util.vh(14),
+              textStyle: {
+                color: partten.getColor("gray"),
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function() {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 317 - 0
src/components/chart/line/double-line-chart.vue

@@ -0,0 +1,317 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "double-line-chart",
+  componentName: "double-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 传入数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "绿线",
+          smooth: true,
+          value: [
+            {
+              text: "",
+              value: 0,
+            },
+            {
+              text: "0:00",
+              value: 20,
+            },
+            {
+              text: "10:00",
+              value: 1,
+            },
+            {
+              text: "11:00",
+              value: 40,
+            },
+            {
+              text: "12:00",
+              value: 10,
+            },
+            {
+              text: "13:00",
+              value: 15,
+            },
+            {
+              text: "14:00",
+              value: 30,
+            },
+            {
+              text: "15:00",
+              value: 40,
+            },
+            {
+              text: "",
+              value: 10,
+            },
+          ],
+        },
+        {
+          title: "黄线",
+          smooth: true,
+          value: [
+            {
+              text: "",
+              value: 0,
+            },
+            {
+              text: "0:00",
+              value: 40,
+            },
+            {
+              text: "10:00",
+              value: 20,
+            },
+            {
+              text: "11:00",
+              value: 20,
+            },
+            {
+              text: "12:00",
+              value: 10,
+            },
+            {
+              text: "13:00",
+              value: 40,
+            },
+            {
+              text: "14:00",
+              value: 50,
+            },
+            {
+              text: "15:00",
+              value: 40,
+            },
+            {
+              text: "",
+              value: 10,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    unit: {
+      type: String,
+      default: "",
+    },
+    showLegend: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#f8de5b", "#4b55ae", "#fa8c16", "#1DA0D7", "#DD5044"],
+      newlist: null,
+    };
+  },
+  watch: {
+    list: {
+      handler(newValue, oldValue) {
+        console.warn(newValue);
+        this.newlist = newValue;
+        this.$nextTick(() => {
+          this.initChart();
+        });
+      },
+      deep: true,
+    },
+    "$store.state.themeName"() {
+      this.initChart();
+    },
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+    datas() {
+      return this.newlist.map((t) => {
+        return t.value;
+      });
+    },
+    legend() {
+      if (this.newlist) {
+        return this.newlist.map((t) => {
+          return t.title;
+        });
+      }
+    },
+    xdata() {
+      return this.newlist[0].value.map((t) => {
+        return t.text;
+      });
+    },
+    series() {
+      let result = [];
+      this.newlist.forEach((value, index) => {
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: value.smooth,
+          showSymbol: false,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              color: this.color[index],
+              width: 1,
+            },
+          },
+          yAxisIndex: value.yAxisIndex,
+          data: value.value.map((t) => {
+            return t.value;
+          }),
+        });
+      });
+
+      return result;
+    },
+    yAxis() {
+      let result = [];
+      result.push({
+        type: "value",
+        name: this.unit,
+        axisLabel: {
+          formatter: "{value}",
+          fontSize: util.vh(14),
+        },
+        boundaryGap: false,
+        //分格线
+        splitLine: {
+          show: false,
+        },
+      });
+      return result;
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor:
+            this.$store.state.themeName === "dark"
+              ? "rgba(0,0,0,0.4)"
+              : "rgba(255,255,255,0.4)",
+          borderColor:
+            this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: util.vh(16),
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor:
+            this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color:
+              this.$store.state.themeName === "dark"
+                ? partten.getColor("grayl")
+                : "#000",
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: 16,
+          left: 40,
+          right: 15,
+          bottom: 24,
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              formatter: "{value}",
+              textStyle: {
+                color:
+                  this.$store.state.themeName === "dark"
+                    ? partten.getColor("gray")
+                    : "#000",
+                fontSize: util.vh(10),
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.$nextTick(() => {
+      this.id = "pie-chart-" + util.newGUID();
+    });
+    this.newlist = this.list;
+    console.warn(this.list);
+    console.warn(this.newlist);
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 289 - 0
src/components/chart/line/double-line-chartold.vue

@@ -0,0 +1,289 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "double-line-chart",
+  componentName: "double-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 传入数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "绿线",
+          smooth: true,
+          value: [
+            {
+              text: "",
+              value: 0,
+            },
+            {
+              text: "0:00",
+              value: 20,
+            },
+            {
+              text: "10:00",
+              value: 1,
+            },
+            {
+              text: "11:00",
+              value: 40,
+            },
+            {
+              text: "12:00",
+              value: 10,
+            },
+            {
+              text: "13:00",
+              value: 15,
+            },
+            {
+              text: "14:00",
+              value: 30,
+            },
+            {
+              text: "15:00",
+              value: 40,
+            },
+            {
+              text: "",
+              value: 10,
+            },
+          ],
+        },
+        {
+          title: "黄线",
+          smooth: true,
+          value: [
+            {
+              text: "",
+              value: 0,
+            },
+            {
+              text: "0:00",
+              value: 40,
+            },
+            {
+              text: "10:00",
+              value: 20,
+            },
+            {
+              text: "11:00",
+              value: 20,
+            },
+            {
+              text: "12:00",
+              value: 10,
+            },
+            {
+              text: "13:00",
+              value: 40,
+            },
+            {
+              text: "14:00",
+              value: 50,
+            },
+            {
+              text: "15:00",
+              value: 40,
+            },
+            {
+              text: "",
+              value: 10,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    unit: {
+      type: String,
+      default: "",
+    },
+    showLegend: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#f8de5b", "#4b55ae", "#fa8c16"],
+    };
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+    datas() {
+      return this.list.map((t) => {
+        return t.value;
+      });
+    },
+    legend() {
+      if (this.newlist) {
+        return this.newlist.map((t) => {
+          return t.title;
+        });
+      } else {
+        return "";
+      }
+    },
+    xdata() {
+      if (this.list) {
+        return this.list[0].value.map((t) => {
+          return t.text;
+        });
+      } else {
+        return "";
+      }
+    },
+    series() {
+      let result = [];
+      this.list.forEach((value, index) => {
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: value.smooth,
+          showSymbol: false,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              color: this.color[index],
+              width: 1,
+            },
+          },
+          yAxisIndex: value.yAxisIndex,
+          data: value.value.map((t) => {
+            return t.value;
+          }),
+        });
+      });
+
+      return result;
+    },
+    yAxis() {
+      let result = [];
+      result.push({
+        type: "value",
+        name: this.unit,
+        axisLabel: {
+          formatter: "{value}",
+          fontSize: util.vh(14),
+        },
+        boundaryGap: false,
+        //分格线
+        splitLine: {
+          show: false,
+        },
+      });
+      return result;
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: util.vh(16),
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: partten.getColor("gray"),
+          textStyle: {
+            color: partten.getColor("grayl"),
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: 16,
+          left: 32,
+          right: 8,
+          bottom: 24,
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              formatter: "{value}",
+              textStyle: {
+                color: partten.getColor("gray"),
+                fontSize: util.vh(14),
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function() {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.$nextTick(() => {
+      this.id = "pie-chart-" + util.newGUID();
+    });
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 481 - 0
src/components/chart/line/img-line-chart.vue

@@ -0,0 +1,481 @@
+<template>
+    <div class="chart" :id="id"></div>
+</template>
+
+<script>
+    import util from "@/helper/util.js";
+    import partten from "@/helper/partten.js";
+    import * as echarts from "echarts";
+
+    export default {
+        name: "img-line-chart",
+        componentName: "img-line-chart",
+        props: {
+            width: {
+                type: String,
+                default: "100%",
+            },
+            height: {
+                type: String,
+                default: "13.889vh",
+            },
+            // 数据
+            list: {
+                type: Array,
+                default: () => [
+                    {
+                        title: "日发电量",
+                        yAxisIndex: 0,
+                        value: [
+                            {
+                                text: "1",
+                                value: 1,
+                                weather: "sun",
+                                direction: "n",
+                                angle: 0,
+                            },
+                            {
+                                text: "2",
+                                value: 2,
+                                weather: "sun",
+                                direction: "s",
+                                angle: 10,
+                            },
+                            {
+                                text: "3",
+                                value: 1,
+                                weather: "sun",
+                                direction: "w",
+                                angle: 40,
+                            },
+                            {
+                                text: "4",
+                                value: 3,
+                                weather: "sun",
+                                direction: "e",
+                                angle: 80,
+                            },
+                            {
+                                text: "5",
+                                value: 3,
+                                weather: "sun",
+                                direction: "nw",
+                                angle: 120,
+                            },
+                            {
+                                text: "6",
+                                value: 3,
+                                weather: "sun",
+                                direction: "ne",
+                                angle: 150,
+                            },
+                            {
+                                text: "7",
+                                value: 3,
+                                weather: "sun",
+                                direction: "se",
+                                angle: 180,
+                            },
+                            {
+                                text: "8",
+                                value: 3,
+                                weather: "sun",
+                                direction: "sw",
+                                angle: 270,
+                            },
+                            {
+                                text: "9",
+                                value: 3,
+                                weather: "sun",
+                                direction: "sw",
+                                angle: 290,
+                            },
+                            {
+                                text: "10",
+                                value: 3,
+                                weather: "sun",
+                                direction: "sw",
+                                angle: 10,
+                            },
+                            {
+                                text: "11",
+                                value: 3,
+                                weather: "sun",
+                                direction: "sw",
+                                angle: 10,
+                            },
+                            {
+                                text: "12",
+                                value: 3,
+                                weather: "sun",
+                                direction: "sw",
+                                angle: 10,
+                            },
+                            {
+                                text: "13",
+                                value: 3,
+                                weather: "sun",
+                                direction: "sw",
+                                angle: 10,
+                            },
+                            {
+                                text: "14",
+                                value: 3,
+                                weather: "sun",
+                                direction: "sw",
+                                angle: 10,
+                            },
+                            {
+                                text: "15",
+                                value: 3,
+                                weather: "sun",
+                                direction: "sw",
+                                angle: 10,
+                            },
+                            {
+                                text: "16",
+                                value: 3,
+                                weather: "sun",
+                                direction: "sw",
+                                angle: 10,
+                            },
+                        ],
+                    },
+                    {
+                        title: "上网电量",
+                        yAxisIndex: 0,
+                        value: [
+                            {
+                                text: "1",
+                                value: 1,
+                            },
+                            {
+                                text: "2",
+                                value: 2,
+                            },
+                            {
+                                text: "3",
+                                value: 1,
+                            },
+                            {
+                                text: "4",
+                                value: 3,
+                            },
+                        ],
+                    },
+                ],
+            },
+            // 单位
+            units: {
+                type: Array,
+                default: () => ["(MW)"],
+            },
+            showLegend: {
+                type: Boolean,
+                default: false,
+            },
+        },
+        data() {
+            return {
+                id: "",
+                chart: null,
+                color: ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b"],
+                imgs: {
+                    sun: require("@assets/png/weather/sun.png"),
+                    cloud: require("@assets/png/weather/cloud.png"),
+                    rain: require("@assets/png/weather/rain.png"),
+                },
+                directions: {
+                    n: require("@assets/png/direction/n.svg"),
+                    s: require("@assets/png/direction/s.svg"),
+                    w: require("@assets/png/direction/w.svg"),
+                    e: require("@assets/png/direction/e.svg"),
+                    nw: require("@assets/png/direction/nw.svg"),
+                    ne: require("@assets/png/direction/ne.svg"),
+                    sw: require("@assets/png/direction/sw.svg"),
+                    se: require("@assets/png/direction/se.svg"),
+                },
+                angles: []
+            };
+        },
+        computed: {
+            legend() {
+                return this.list.map((t) => {
+                    return t.title;
+                });
+            },
+            xdata() {
+                return this.list[0].value.map((t) => {
+                    return t.text;
+                });
+            },
+            yAxis() {
+                let result = [
+                    {
+                        type: "value",
+                        name: "",
+                        axisLabel: {
+                            show: false,
+                        },
+                        //分格线
+                        splitLine: {
+                            show: false,
+                        },
+                        min: 0,
+                        max: 10,
+                    },
+                ];
+                this.units.forEach((value, index) => {
+                    result.push({
+                        type: "value",
+                        name: value,
+                        axisLabel: {
+                            formatter: "{value}",
+                            fontSize: util.vh(14),
+                        },
+                        //分格线
+                        splitLine: {
+                            lineStyle: {
+                                color: partten.getColor("gray"),
+                                type: "dashed",
+                            },
+                        },
+                    });
+                });
+
+                return result;
+            },
+            series() {
+                let result = [];
+
+                this.list.forEach((value, index) => {
+                    if (index == 0) {
+                        result.push({
+                            name: value.title,
+                            type: "line",
+                            smooth: true,
+                            zlevel: index,
+                            lineStyle: {
+                                normal: {
+                                    color: this.color[index],
+                                    width: 1,
+                                },
+                            },
+                            yAxisIndex: value.yAxisIndex,
+                            data: value.value.map((t) => {
+                                return {
+                                    value: t.value,
+                                    label: {
+                                        show: true,
+                                        position: "top",
+                                        formatter: function (e) {
+                                            return ["  {weather| }"];
+                                        },
+                                        rich: {
+                                            weather: {
+                                                height: 15,
+                                                backgroundColor: {
+                                                    image: this.imgs[t.weather],
+                                                },
+                                            },
+                                        },
+                                        borderWidth: 1,
+                                        borderRadius: 4,
+                                        padding: [4, 10],
+                                        lineHeight: 26,
+                                        distance: 20,
+                                    },
+                                };
+                            }),
+                        });
+                        result.push({
+                            name: "风向",
+                            type: "bar",
+                            smooth: true,
+                            zlevel: 9999,
+                            lineStyle: {
+                                normal: {
+                                    color: this.color[index],
+                                    width: 1,
+                                },
+                            },
+                            yAxisIndex: 0,
+                            barGap: "0%",
+                            barCategoryGap: "0%",
+                            clip: false,
+                            data: value.value.map((t) => {
+                                return {
+                                    value: -2,
+                                    label: {
+                                        show: true,
+                                        position: "inside",
+                                        formatter: function (e) {
+                                            return ["  {direction| }"];
+                                        },
+                                        rich: {
+                                            direction: {
+                                                height: 20,
+                                                backgroundColor: {
+                                                    image: this.angles[parseInt(t.angle) % 360],
+                                                },
+                                            },
+                                        },
+                                        borderWidth: 1,
+                                        borderRadius: 4,
+                                        padding: [4, 10],
+                                        lineHeight: 26,
+                                        distance: 20,
+                                    },
+                                    itemStyle: {
+                                        borderWidth: 1,
+                                        borderColor: "#606769",
+                                        color: "transparent",
+                                    },
+                                };
+                            }),
+                        });
+                    } else {
+                        result.push({
+                            name: value.title,
+                            type: "line",
+                            smooth: true,
+                            zlevel: index,
+                            label: {
+                                show: false,
+                                position: "top",
+                                borderWidth: 1,
+                                borderRadius: 4,
+                                padding: [4, 10],
+                                lineHeight: 26,
+                                distance: 20,
+                            },
+                            lineStyle: {
+                                normal: {
+                                    color: this.color[index],
+                                    width: 1,
+                                },
+                            },
+                            yAxisIndex: value.yAxisIndex,
+                            data: value.value.map((t) => {
+                                return t.value;
+                            }),
+                        });
+                    }
+                });
+
+                return result;
+            },
+        },
+        methods: {
+            initChart() {
+                const chart = echarts.init(this.$el);
+                let option = {
+                    color: this.color,
+                    tooltip: {
+                        trigger: "axis",
+                        backgroundColor: "rgba(0,0,0,0.4)",
+                        textStyle: {
+                            color: "#fff",
+                            fontSize: util.vh(16),
+                        },
+                        formatter: function (params) {
+                            let str = "";
+                            for (let i = 0; i < params.length; i++) {
+                                if (params[i].seriesName == "风向") {
+                                    continue;
+                                }
+                                if (i == 0) {
+                                    str += `${params[i].name}<br/>${params[i].seriesName}: ${
+                                        params[i].data.value ? params[i].data.value : params[i].data
+                                    }<br/>`;
+                                    continue;
+                                }
+                                str += `${params[i].seriesName}: ${
+                                    params[i].data.value ? params[i].data.value : params[i].data
+                                }<br/>`;
+                            }
+                            return str;
+                        },
+                    },
+                    legend: {
+                        show: this.showLegend,
+                        data: this.legend,
+                        right: 56,
+                        icon: "circle",
+                        itemWidth: 6,
+                        inactiveColor: partten.getColor("gray"),
+                        textStyle: {
+                            color: partten.getColor("grayl"),
+                            fontSize: 12,
+                        },
+                    },
+                    grid: {
+                        top: 32,
+                        left: 8,
+                        right: 8,
+                        bottom: 32,
+                        containLabel: true,
+                    },
+                    xAxis: [
+                        {
+                            type: "category",
+                            // boundaryGap: false,
+                            axisLabel: {
+                                formatter: "{value}",
+                                fontSize: 14,
+                                textStyle: {
+                                    color: partten.getColor("gray"),
+                                },
+                            },
+                            data: this.xdata,
+                            offset: 32,
+                            axisLine: { onZero: true },
+                        },
+                    ],
+                    yAxis: this.yAxis,
+                    series: this.series,
+                };
+
+                chart.clear();
+                chart.setOption(option);
+
+                this.resize = function () {
+                    chart.resize();
+                };
+
+                window.addEventListener("resize", this.resize);
+            },
+        },
+        created() {
+            this.id = "pie-chart-" + util.newGUID();
+            for (let i = 0; i <= 360; i++) {
+                this.angles.push(require(`@assets/png/angle/angle${i}.svg`));
+            }
+        },
+        mounted() {
+            this.$nextTick(() => {
+                setTimeout(() => {
+                    this.$el.style.width = this.width;
+                    this.$el.style.height = this.height;
+                    this.initChart();
+                }, 1000);
+            });
+        },
+        updated() {
+            this.$nextTick(() => {
+                this.initChart();
+            });
+        },
+        unmounted() {
+            window.removeEventListener("resize", this.resize);
+        },
+    };
+</script>
+
+<style lang="less">
+    .chart {
+        width: 100%;
+        height: 100%;
+        display: inline-block;
+    }
+</style>

+ 332 - 0
src/components/chart/line/marker-line-chart.vue

@@ -0,0 +1,332 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "double-line-chart",
+  componentName: "double-line-chart",
+  props: {
+    isChartClick:{
+      type: Boolean,
+      default: false,
+    },
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 传入数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "绿线",
+          value: [
+            {
+              text: "",
+              value: 0,
+            },
+            {
+              text: "0:00",
+              value: 20,
+            },
+            {
+              text: "10:00",
+              value: 1,
+            },
+            {
+              text: "11:00",
+              value: 40,
+            },
+            {
+              text: "12:00",
+              value: 10,
+            },
+            {
+              text: "13:00",
+              value: 15,
+            },
+            {
+              text: "14:00",
+              value: 30,
+            },
+            {
+              text: "15:00",
+              value: 40,
+            },
+            {
+              text: "",
+              value: 10,
+            },
+          ],
+        },
+        {
+          title: "黄线",
+          value: [
+            {
+              text: "",
+              value: 0,
+            },
+            {
+              text: "0:00",
+              value: 40,
+            },
+            {
+              text: "10:00",
+              value: 20,
+            },
+            {
+              text: "11:00",
+              value: 20,
+            },
+            {
+              text: "12:00",
+              value: 10,
+            },
+            {
+              text: "13:00",
+              value: 40,
+            },
+            {
+              text: "14:00",
+              value: 50,
+            },
+            {
+              text: "15:00",
+              value: 40,
+            },
+            {
+              text: "",
+              value: 10,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    unit: {
+      type: String,
+      default: "MW",
+    },
+    showLegend: {
+      type: Boolean,
+      default: false,
+    },
+	myUnit: {
+      type: String,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#f8de5b", "#4b55ae", "#fa8c16"],
+    };
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+    datas() {
+      return this.list.map((t) => {
+        return t.value;
+      });
+    },
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      return this.list[0].value.map((t) => {
+        return t.text;
+      });
+    },
+    series() {
+      let that = this;
+      let result = [];
+
+      this.list.forEach((value, index) => {
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: true,
+          showSymbol: false,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              color: this.color[index],
+              width: 1,
+            },
+          },
+          markPoint: {},
+          // index == 0
+          //   ? {
+          //       data: [
+          //         {
+          //           type: "average",
+          //           name: "保证功率",
+          //           symbolSize: 0,
+          //           label: {
+          //             offset: [0, -40],
+          //             formatter: function(param) {
+          //               return `{title|${param.name}}` + "\n" + `{value| ${param.value}${that.unit}}`;
+          //             },
+          //             backgroundColor: partten.getColor("green") + 33,
+          //             borderColor: partten.getColor("green"),
+          //             borderWidth: 0.5,
+          //             borderRadius: 2,
+          //             padding: 8,
+          //             rich: {
+          //               title: {
+          //                 color: partten.getColor("green"),
+          //                 fontSize: 12,
+          //               },
+          //               value: {
+          //                 color: "#fff",
+          //                 fontSize: 16,
+          //                 padding: [12, 0, 0, -4],
+          //               },
+          //             },
+          //           },
+          //         },
+          //       ],
+          //     }
+          //   : {},
+          yAxisIndex: value.yAxisIndex,
+          data: value.value.map((t) => {
+            return t.value;
+          }),
+        });
+      });
+
+      return result;
+    },
+    yAxis() {
+      let result = [];
+      result.push({
+        type: "value",
+        name: this.unit,
+        axisLabel: {
+          formatter: "{value}",
+          fontSize: util.vh(14),
+        },
+        boundaryGap: false,
+        //分格线
+        splitLine: {
+          show: true,
+          lineStyle: {
+            color: partten.getColor("gray"),
+            type: "dashed",
+          },
+        },
+      });
+      return result;
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      let that = this;
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: util.vh(16),
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: partten.getColor("gray"),
+          textStyle: {
+            color: partten.getColor("grayl"),
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: this.myUnit === 'MW' ? 32 : 16,
+          left: 32,
+          right: 8,
+          bottom: 24,
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              formatter: "{value}",
+              textStyle: {
+                color: partten.getColor("gray"),
+                fontSize: util.vh(14),
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+      chart.clear();
+      chart.setOption(option);
+      if(this.isChartClick){
+        chart.getZr().off("click");
+        chart.getZr().on("click", (params) => {
+          that.chartClick();
+        });
+      }
+      this.resize = function() {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+    chartClick(){
+      this.$emit("chartClick");
+    }
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 265 - 0
src/components/chart/line/multi-arrow-line-chart.vue

@@ -0,0 +1,265 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multi-arrow-line-chart",
+  componentName: "multi-arrow-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "功率",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "0m/s",
+              value: 1,
+            },
+            {
+              text: "2m/s",
+              value: 2,
+            },
+            {
+              text: "3m/s",
+              value: 16,
+            },
+            {
+              text: "4m/s",
+              value: 3,
+            },
+            {
+              text: "5m/s",
+              value: 3,
+            },
+            {
+              text: "6m/s",
+              value: 31,
+            },
+            {
+              text: "7m/s",
+              value: 33,
+            },
+            {
+              text: "8m/s",
+              value: 43,
+            },
+            {
+              text: "9m/s",
+              value: 3,
+            },
+            {
+              text: "10m/s",
+              value: 3,
+            },
+            {
+              text: "11m/s",
+              value: 31,
+            },
+            {
+              text: "12m/s",
+              value: 3,
+            },
+            {
+              text: "13m/s",
+              value: 3,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["()"],
+    },
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    isSingle: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b"],
+    };
+  },
+  computed: {
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      return this.list[0].value.map((t) => {
+        return t.text;
+      });
+    },
+    yAxis() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        result.push({
+          type: "value",
+          name: value,
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: util.vh(14),
+          },
+          //分格线
+          splitLine: {
+            lineStyle: {
+              color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000" + 55,
+              type: "dashed",
+            },
+          },
+        });
+      });
+
+      return result;
+    },
+    series() {
+      let result = [];
+      let isSingle = this.isSingle;
+      this.list.forEach((value, index) => {
+        var data = value.value.map((t) => {
+          return t.value;
+        });
+
+        var arrowArr = [];
+        data.forEach((dvalue, dindex) => {
+          var item = dvalue;
+          arrowArr.push({
+            symbol: "arrow",
+            symbolSize: 12,
+            symbolRotate: -90,
+            value: item,
+          });
+        });
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: true,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              color: this.color[index],
+              width: 1,
+            },
+          },
+          yAxisIndex: value.yAxisIndex,
+          data: arrowArr,
+        });
+      });
+
+      return result;
+    },
+  },
+  methods: {
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: this.$store.state.themeName === "dark" ? "rgba(0,0,0,0.4)" : "rgba(255,255,255,0.5)",
+			borderColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+			textStyle: {
+			  color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: util.vh(16),
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? partten.getColor("grayl") : "#000",
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: util.vh(32),
+          left: util.vh(40),
+          right: util.vh(40),
+          bottom: util.vh(24),
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: util.vh(14),
+              textStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function() {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 470 - 0
src/components/chart/line/multiple-line-chart.vue

@@ -0,0 +1,470 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-line-chart",
+  componentName: "multiple-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "日发电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 4,
+            },
+            {
+              text: "5",
+              value: 6,
+            },
+            {
+              text: "6",
+              value: 2,
+            },
+            {
+              text: "7",
+              value: 3,
+            },
+            {
+              text: "8",
+              value: 8,
+            },
+            {
+              text: "9",
+              value: 3,
+            },
+            {
+              text: "10",
+              value: 2,
+            },
+            {
+              text: "11",
+              value: 5,
+            },
+            {
+              text: "12",
+              value: 8,
+            },
+            {
+              text: "13",
+              value: 3,
+            },
+            {
+              text: "14",
+              value: 9,
+            },
+            {
+              text: "15",
+              value: 3,
+            },
+            {
+              text: "16",
+              value: 2,
+            },
+            {
+              text: "17",
+              value: 1,
+            },
+            {
+              text: "18",
+              value: 3,
+            },
+            {
+              text: "19",
+              value: 4,
+            },
+            {
+              text: "20",
+              value: 9,
+            },
+            {
+              text: "21",
+              value: 2,
+            },
+            {
+              text: "22",
+              value: 1,
+            },
+            {
+              text: "23",
+              value: 2,
+            },
+            {
+              text: "24",
+              value: 3,
+            },
+            {
+              text: "25",
+              value: 3,
+            },
+            {
+              text: "26",
+              value: 4,
+            },
+            {
+              text: "27",
+              value: 9,
+            },
+            {
+              text: "28",
+              value: 7,
+            },
+            {
+              text: "29",
+              value: 4,
+            },
+            {
+              text: "30",
+              value: 1,
+            },
+            {
+              text: "31",
+              value: 2,
+            },
+          ],
+        },
+        {
+          title: "上网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "购网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+          ],
+        },
+        {
+          title: "风速",
+          yAxisIndex: 1,
+          value: [
+            {
+              text: "1",
+              value: 100,
+            },
+            {
+              text: "2",
+              value: 200,
+            },
+            {
+              text: "1",
+              value: 100,
+            },
+            {
+              text: "2",
+              value: 400,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["(MW)", "(风速)"],
+    },
+    showLegend: {
+      type: Boolean,
+      default: false,
+    },
+    hoverType: {
+      type: String,
+      default: "item",
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      // color: ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b", "#1a93cf", "#c531c7", "#bd3338", "#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b", "#1a93cf", "#c531c7", "#bd3338"],
+      color: ["#05bb4c", "#f8de5b", "#4b55ae", "#fa8c16", "#1DA0D7", "#DD5044"],
+    };
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+    datas() {
+      return this.list.map((t) => {
+        return t.value;
+      });
+    },
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      return this.list[0].value.map((t, tIndex) => {
+        let xunit = [tIndex];
+        return xunit;
+      });
+    },
+    series() {
+      let result = [];
+
+      this.list.forEach((value, index) => {
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: true,
+          showSymbol: false,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              // color: index != 0 ? this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000" : this.color[index],
+              color: this.color[index],
+              width: 1,
+            },
+            // emphasis: {
+            //   color: this.color[index],
+            // },
+          },
+          // areaStyle: {
+          //   normal: {
+          //     color:
+          //       index == 0
+          //         ? new echarts.graphic.LinearGradient(
+          //             0,
+          //             0,
+          //             0,
+          //             1,
+          //             [
+          //               {
+          //                 offset: 0,
+          //                 color: this.hexToRgba(this.color[index], 0.3),
+          //               },
+          //               {
+          //                 offset: 1,
+          //                 color: this.hexToRgba(this.color[index], 0.1),
+          //               },
+          //             ],
+          //             false
+          //           )
+          //         : "transparent",
+          //     shadowColor: this.hexToRgba(this.color[index], 0.1),
+          //     shadowBlur: 10,
+          //   },
+          //   emphasis: {
+          //     color: new echarts.graphic.LinearGradient(
+          //       0,
+          //       0,
+          //       0,
+          //       1,
+          //       [
+          //         {
+          //           offset: 0,
+          //           color: this.hexToRgba(this.color[index], 0.3),
+          //         },
+          //         {
+          //           offset: 1,
+          //           color: this.hexToRgba(this.color[index], 0.1),
+          //         },
+          //       ],
+          //       false
+          //     ),
+          //     shadowColor: this.hexToRgba(this.color[index], 0.1),
+          //     shadowBlur: 10,
+          //   },
+          // },
+          tooltip: {
+            show: true,
+            position: [10, 10],
+          },
+          yAxisIndex: value.yAxisIndex,
+          data: value.value.map((t) => {
+            return t.value;
+          }),
+        });
+      });
+
+      return result;
+    },
+    yAxis() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        result.push({
+          type: "value",
+          name: value,
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: util.vh(14),
+          },
+          axisLine: {
+            show: false,
+          },
+          //分格线
+          splitLine: {
+            show: index == 0,
+            lineStyle: {
+              color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+              type: "dashed",
+            },
+          },
+        });
+      });
+      return result;
+    },
+  },
+  methods: {
+    hexToRgba(hex, opacity) {
+      let rgbaColor = "";
+      let reg = /^#[\da-f]{6}$/i;
+      if (reg.test(hex)) {
+        rgbaColor = `rgba(${parseInt("0x" + hex.slice(1, 3))},${parseInt(
+          "0x" + hex.slice(3, 5)
+        )},${parseInt("0x" + hex.slice(5, 7))},${opacity})`;
+      }
+      return rgbaColor;
+    },
+    resize() {},
+    initChart() {
+      let that = this;
+      let chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: this.hoverType,
+          axisPointer:
+            this.hoverType != "item"
+              ? {
+                  type: "cross",
+                }
+              : {},
+          backgroundColor: this.$store.state.themeName === "dark" ? "rgba(0,0,0,0.4)" : "rgba(255,255,255,0.5)",
+          borderColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            fontSize: util.vh(16),
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? partten.getColor("grayl") : "#000",
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: 32,
+          left: 40,
+          right: 40,
+          bottom: 24,
+        },
+        xAxis: [
+          {
+            name: "(m/s)",
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: util.vh(14),
+              textStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+              },
+            },
+            axisLine: {
+              show: false,
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+      chart.clear();
+      chart && option && chart.setOption(option);
+      this.resize = function () {
+        chart.resize();
+      };
+      window.addEventListener("resize", this.resize);
+      chart.resize();
+    },
+  },
+  created() {
+    this.$nextTick(() => {
+      this.id = "pie-chart-" + util.newGUID();
+    });
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 550 - 0
src/components/chart/line/multiple-y-line-chart-normal.vue

@@ -0,0 +1,550 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-y-line-chart-normal",
+  componentName: "multiple-y-line-chart-normal",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "机舱震动x方向",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "-0.003",
+              value: -0.003,
+            },
+            {
+              text: "-0.002",
+              value: -0.002,
+            },
+            {
+              text: "-0.003",
+              value: -0.006,
+            },
+            {
+              text: "-0.003",
+              value: -0.003,
+            },
+            {
+              text: "-0.002",
+              value: -0.002,
+            },
+            {
+              text: "-0.003",
+              value: -0.006,
+            },
+            {
+              text: "-0.003",
+              value: -0.003,
+            },
+            {
+              text: "-0.002",
+              value: -0.002,
+            },
+            {
+              text: "-0.003",
+              value: -0.006,
+            },
+          ],
+        },
+        {
+          title: "机舱震动y方向",
+          yAxisIndex: 1,
+          value: [
+            {
+              text: "-0.01",
+              value: -0.01,
+            },
+            {
+              text: "-0.005",
+              value: -0.005,
+            },
+            {
+              text: "-0.008",
+              value: -0.008,
+            },
+            {
+              text: "-0.01",
+              value: -0.01,
+            },
+            {
+              text: "-0.005",
+              value: -0.005,
+            },
+            {
+              text: "-0.008",
+              value: -0.008,
+            },
+            {
+              text: "-0.01",
+              value: -0.01,
+            },
+            {
+              text: "-0.005",
+              value: -0.005,
+            },
+            {
+              text: "-0.008",
+              value: -0.008,
+            },
+          ],
+        },
+        {
+          title: "机舱震动最大偏移值",
+          yAxisIndex: 2,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "0.05",
+              value: 0.05,
+            },
+            {
+              text: "0.5",
+              value: 0.5,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "0.05",
+              value: 0.05,
+            },
+            {
+              text: "0.5",
+              value: 0.5,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "0.05",
+              value: 0.05,
+            },
+            {
+              text: "0.5",
+              value: 0.5,
+            },
+          ],
+        },
+        {
+          title: "风速1",
+          yAxisIndex: 3,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "5",
+              value: 5,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "5",
+              value: 5,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "5",
+              value: 5,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+          ],
+        },
+        {
+          title: "风速2",
+          yAxisIndex: 4,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+          ],
+        },
+      ],
+    },
+    showLegend: {
+      type: Boolean,
+      default: false,
+    },
+    default: {
+      type: Boolean,
+      default: false,
+    },
+    // 轴
+    yAxises: {
+      type: Array,
+      default: () => [
+        {
+          name: "机舱震动x方向",
+          min: -0.01,
+          max: 0,
+          unit: "",
+          position: "left",
+        },
+        {
+          name: "机舱震动y方向",
+          min: -0.01,
+          max: 0,
+          unit: "",
+          position: "right",
+        },
+        {
+          name: "机舱震动最大偏移值",
+          min: 0,
+          max: 1,
+          unit: "",
+          position: "left",
+        },
+        {
+          name: "风速1",
+          min: 0,
+          max: 10,
+          unit: "",
+          position: "right",
+        },
+        {
+          name: "风速2",
+          min: 0,
+          max: 10,
+          unit: "",
+          position: "left",
+        },
+      ],
+    },
+
+    markLineData: {
+      type: Array,
+      defaylt: () => [],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#1DA0D7", "#05BB4C", "#323E6F", "#EDB32F", "#DB5520"],
+    };
+  },
+  computed: {
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      if (this.list.length > 1) {
+        // this.list[1].value.forEach((lEle, lIndex) => {
+        //   // console.log(
+        //     this.list[1].value.indexOf(
+        //       this.list[1].value[lIndex].text == "00:00"
+        //     )
+        //   );
+        // });
+        return this.list[1]?.value.map((t) => {
+          return t.text || new Date(t.ts).formatDate("hh:mm:ss");
+        });
+      } else if (this.list.length == 1) {
+        return this.list[0]?.value.map((t) => {
+          return t.text || new Date(t.ts).formatDate("hh:mm:ss");
+        });
+      }
+    },
+    yAxis() {
+      let result = [];
+      let p = { left: 0, right: 0 };
+      this.yAxises.forEach((item, index) => {
+        result.push({
+          type: "value",
+          name: `${item.name}${item.unit}`,
+          nameLocation: p[item.position] % 2 == 0 ? "end" : "start",
+          nameGap: 10,
+          min: item.min,
+          max: item.max,
+          position: item.position,
+          offset: p[item.position] * 50,
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: 12,
+          },
+          //分格线
+          splitLine: {
+            lineStyle: {
+              color:
+                this.$store.state.themeName === "dark"
+                  ? partten.getColor("gray")
+                  : partten.getColor("black"),
+              type: "dashed",
+            },
+          },
+          axisLine: {
+            show: true,
+          },
+          axisTick: {
+            show: true,
+          },
+        });
+        p[item.position]++;
+      });
+      return result;
+    },
+    series() {
+      let result = [];
+      this.list.forEach((value, index) => {
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: true,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              color: this.color[index],
+              width: 1,
+            },
+          },
+          showSymbol: false,
+          yAxisIndex: value.yAxisIndex,
+          markLine: this.markLineData
+            ? {
+                name: "",
+                silent: true,
+                label: {
+                  position: "end",
+                  formatter: "",
+                  color: "red",
+                  fontSize: 14,
+                },
+                data: this.markLineData,
+                lineStyle: {
+                  normal: {
+                    type: "dashed",
+                    color: "red",
+                    width: 2,
+                  },
+                },
+              }
+            : {},
+          data: value.value.map((t) => {
+            if (t.value || t.value === 0) {
+              return t.value;
+            } else if (t.doubleValue || t.doubleValue === 0) {
+              return t.doubleValue;
+            } else {
+              return t.longValue;
+            }
+          }),
+        });
+      });
+
+      return result;
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = this.option();
+      chart.clear();
+
+      chart.setOption(option);
+      if (this.default) {
+        chart.dispatchAction({
+          type: "showTip",
+          seriesIndex: 0, // 显示第几个series
+          dataIndex: this.list[0].value.length - 600, // 显示第几个数据
+        });
+      }
+
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+    option: function () {
+      let themeName = "";
+      this.$store.state.themeName === "dark"
+        ? (themeName = true)
+        : (themeName = false);
+      return {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          triggerOn: this.default ? "click" : "mousemove",
+          alwaysShowContent: true,
+          backgroundColor: themeName
+            ? "rgba(0,0,0,0.4)"
+            : "rgba(255,255,255,0.5)",
+          borderColor: themeName ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: themeName ? "#fff" : "#000",
+            fontSize: 12,
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          top: "top",
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: themeName ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: themeName ? partten.getColor("grayl") : "#000",
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: 27,
+          left: 16,
+          right: 16,
+          bottom: 0,
+          containLabel: true,
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              interval:
+                Number((this.xdata.length / 8).toFixed(0)) > 2
+                  ? Number((this.xdata.length / 8).toFixed(0))
+                  : 0,
+              showMinLabel: true,
+              showMaxLabel: true,
+              formatter: "{value}",
+              fontSize: 12,
+              textStyle: {
+                color: themeName ? partten.getColor("gray") : "#000",
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: 14,
+          },
+          axisLine: {
+            show: false,
+          },
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "#606769",
+              type: "dashed",
+            },
+          },
+        },
+        // yAxis: this.yAxis,
+        series: this.series,
+      };
+    },
+    reload: function () {
+      const chart = echarts.getInstanceByDom(this.$el);
+      chart.clear();
+      let option = this.option();
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  beforeUpdate() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="scss">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 373 - 0
src/components/chart/line/multiple-y-line-chart.vue

@@ -0,0 +1,373 @@
+<template>
+    <div class="chart" :id="id"></div>
+</template>
+
+<script>
+    import util from "@/helper/util.js";
+    import partten from "@/helper/partten.js";
+    import * as echarts from "echarts";
+
+    export default {
+        name: "multiple-y-line-chart",
+        componentName: "multiple-y-line-chart",
+        props: {
+            width: {
+                type: String,
+                default: "100%",
+            },
+            height: {
+                type: String,
+                default: "13.889vh",
+            },
+            // 数据
+            list: {
+                type: Array,
+                default: () => [
+                    {
+                        title: "机舱震动x方向",
+                        yAxisIndex: 0,
+                        value: [
+                            ["2021/07/01 00:00:00", 68],
+                            ["2021/07/01 05:00:00", 74],
+                            ["2021/07/01 10:00:00", 69],
+                            ["2021/07/01 15:00:00", 134],
+                            ["2021/07/01 20:00:00", 262],
+                        ],
+                    },
+                    {
+                        title: "机舱震动y方向",
+                        yAxisIndex: 1,
+                        value: [
+                            ["2021/07/01 00:00:00", 110],
+                            ["2021/07/01 05:00:00", 175],
+                            ["2021/07/01 10:00:00", 290],
+                            ["2021/07/01 15:00:00", 140],
+                            ["2021/07/01 20:00:00", 203],
+                        ],
+                    },
+                    {
+                        title: "机舱震动最大偏移值",
+                        yAxisIndex: 2,
+                        value: [
+                            ["2021/07/01 00:00:00", 312],
+                            ["2021/07/01 05:00:00", 203],
+                            ["2021/07/01 10:00:00", 231],
+                            ["2021/07/01 15:00:00", 305],
+                            ["2021/07/01 20:00:00", 230],
+                        ],
+                    },
+                    {
+                        title: "风速1",
+                        yAxisIndex: 3,
+                        value: [
+                            ["2021/07/01 00:00:00", 277],
+                            ["2021/07/01 05:00:00", 311],
+                            ["2021/07/01 10:00:00", 296],
+                            ["2021/07/01 15:00:00", 87],
+                            ["2021/07/01 20:00:00", 273],
+                        ],
+                    },
+                    {
+                        title: "风速2",
+                        yAxisIndex: 4,
+                        value: [
+                            ["2021/07/01 00:00:00", 214],
+                            ["2021/07/01 05:00:00", 224],
+                            ["2021/07/01 10:00:00", 313],
+                            ["2021/07/01 15:00:00", 230],
+                            ["2021/07/01 20:00:00", 264],
+                        ],
+                    }
+                ],
+            },
+            showLegend: {
+                type: Boolean,
+                default: false,
+            },
+            // 轴
+            yAxises: {
+                type: Array,
+                default: () => [
+                    {
+                        name: '机舱震动x方向',
+                        min: 50,
+                        max: 370,
+                        unit: "",
+                        position: "left",
+                    },
+                    {
+                        name: '机舱震动y方向',
+                        min: 60,
+                        max: 320,
+                        unit: "",
+                        position: "right",
+                    },
+                    {
+                        name: '机舱震动最大偏移值',
+                        min: 90,
+                        max: 330,
+                        unit: "",
+                        position: "left",
+                    },
+                    {
+                        name: '风速1',
+                        min: 30,
+                        max: 350,
+                        unit: "",
+                        position: "right",
+                    },
+                    {
+                        name: '风速2',
+                        min: 100,
+                        max: 360,
+                        unit: "",
+                        position: "left",
+                    },
+                ],
+            },
+            // 标线
+            markLine: {
+                type: Array,
+                default: () => [
+                    {
+                        yAxisIndex: 0,
+                        data: ["2021/07/01 10:00:00", "2021/07/01 20:00:00", "2021/07/05 15:00:00", "2021/07/15 15:00:00"]
+                    }
+                ]
+            }
+        },
+        data() {
+            return {
+                id: "",
+                chart: null,
+                color: ["#323E6F", "#1DA0D7", "#05BB4C", "#EDB32F", "#DB5520"],
+            };
+        },
+        computed: {
+            legend() {
+                return this.list.map((t) => {
+                    return t.title;
+                });
+            },
+            xdata() {
+                return this.list[0].value.map((t) => {
+                    return t.text;
+                });
+            },
+            yAxis() {
+				let themeName = this.$store.state.themeName.split(' ')[1];
+                let result = [];
+                let p = {left: 0, right: 0};
+                this.yAxises.forEach((item, index) => {
+                    result.push({
+                        type: "value",
+                        name: `${item.name}${item.unit}`,
+                        nameLocation: p[item.position] % 2 == 0 ? "end" : "start",
+                        min: item.min,
+                        max: item.max,
+                        position: item.position,
+                        offset: p[item.position] * 60,
+                        axisLabel: {
+                            formatter: "{value}",
+                            fontSize: util.vh(14),
+                        },
+                        //分格线
+                        splitLine: {
+                            lineStyle: {
+                                color: themeName === "dark"? partten.getColor("gray"): "#000",
+                                type: "dashed",
+                            },
+                        },
+                        axisLine: {
+                            show: true,
+                        },
+                        axisTick: {
+                            show: true
+                        }
+                    });
+                    p[item.position]++;
+                });
+
+                return result;
+            },
+            series() {
+                let result = [];
+
+                this.list.forEach((value, index) => {
+                    let ser = {
+                        name: value.title,
+                        type: "line",
+                        smooth: true,
+                        zlevel: index,
+                        lineStyle: {
+                            normal: {
+                                color: this.color[index],
+                                width: 1,
+                            },
+                        },
+                        yAxisIndex: value.yAxisIndex,
+                        // data: value.value.map((t) => {
+                        //     return t.value;
+                        // }),
+                        data: value.value,
+                    };
+                    let iMarkLine = this.markLine.find(t => t.yAxisIndex == index);
+                    if (iMarkLine) {
+                        ser.markLine = {
+                            silent: true,
+                            data: iMarkLine.data.map(t => {
+                                return { xAxis: t }
+                            }),
+                            lineStyle: {
+                                color: '#ff0000',
+                            },
+                            label: {
+                                color: 'rgba(204,187,225,0.5)'
+                            }
+                        }
+                    }
+                    result.push(ser);
+                });
+
+                return result;
+            },
+        },
+        methods: {
+            resize() {},
+            initChart() {
+				let themeName = this.$store.state.themeName.split(' ')[1];
+                const chart = echarts.init(this.$el);
+
+                let option = this.option(themeName);
+                // console.log(option)
+                chart.clear();
+                chart.setOption(option);
+
+                this.resize = function() {
+                    chart.resize();
+                };
+
+                window.addEventListener("resize", this.resize);
+            },
+            option: function (themeName) {
+                return {
+                    color: this.color,
+                    tooltip: {
+                        trigger: "axis",
+                        backgroundColor: themeName === "dark"? "rgba(0,0,0,0.4)": "rgba(255,255,255,0.5)",
+                        borderColor: themeName === "dark"? partten.getColor("gray"): "#000",
+                        textStyle: {
+                            color: themeName === "dark" ? "#fff" : "#000",
+                            fontSize: 14,
+                        },
+                    },
+                    legend: {
+                        show: this.showLegend,
+                        data: this.legend,
+                        right: 56,
+                        icon: "circle",
+                        itemWidth: 6,
+                        inactiveColor: themeName === "dark"? partten.getColor("gray"): "#000",
+                        textStyle: {
+                            color: themeName === "dark"? partten.getColor("grayl"): "#000",
+                            fontSize: 12,
+                        },
+                    },
+                    dataZoom: [{
+                        show: true,
+                        height: 30,
+                        xAxisIndex: [0],
+                        bottom: 30,
+                        "start": 0,
+                        "end": 5,
+                        handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
+                        handleSize: '110%',
+                        handleStyle: {
+                            color: themeName === "dark"?"#05bb4c":  partten.getColor("deepblue"),
+                        },
+                        textStyle:{
+                            color: themeName === "dark"? "rgba(204,187,225,0.5)": "#000",
+                        },
+                        fillerColor:themeName === "dark"?"rgba(5,187,76,0.4)":"rgba(54, 52, 142,0.4)",
+                        borderColor:themeName === "dark"?"rgba(5,187,76,0.5)":"rgba(54, 52, 142,0.5)",
+
+                    }, {
+                        type: "inside",
+                        show: true,
+                        height: 15,
+                        start: 1,
+                        end: 35
+                    }],
+                    grid: {
+                        top: util.vh(80),
+                        left: util.vh(80),
+                        right: util.vh(80),
+                        bottom: util.vh(64),
+                        containLabel: true,
+                    },
+                    xAxis: [
+                        {
+                            type: "time",
+                            boundaryGap: false,
+                            axisLabel: {
+                                // formatter: "{value}",
+                                fontSize: util.vh(14),
+                                textStyle: {
+                                    color: themeName === "dark"? partten.getColor("gray"): "#000",
+                                },
+                            },
+                            // data: this.xdata,
+                        },
+                    ],
+                    yAxis: this.yAxis,
+                    series: this.series,
+                };
+            },
+            datazoom: function (start, end) {
+                const chart = echarts.getInstanceByDom(this.$el);
+                chart.dispatchAction({
+                    type: 'dataZoom',
+                    start: start,
+                    end: end,
+                });
+            },
+            reload: function () {
+                const chart = echarts.getInstanceByDom(this.$el);
+                chart.clear();
+                let option = this.option();
+                chart.setOption(option);
+            },
+        },
+        created() {
+            this.id = "pie-chart-" + util.newGUID();
+        },
+        mounted() {
+            this.$nextTick(() => {
+                this.$el.style.width = this.width;
+                this.$el.style.height = this.height;
+                this.initChart();
+            });
+        },
+        updated() {
+            this.$nextTick(() => {
+                this.initChart();
+            });
+        },
+        unmounted() {
+            window.removeEventListener("resize", this.resize);
+        },
+		watch: {
+		    "$store.state.themeName"() {
+		      this.initChart();
+		    },
+		  },
+    };
+</script>
+
+<style lang="less">
+    .chart {
+        width: 100%;
+        height: 100%;
+        display: inline-block;
+    }
+</style>

+ 307 - 0
src/components/chart/line/normal-line-chart.vue

@@ -0,0 +1,307 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "normal-line-chart",
+  componentName: "normal-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "日发电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+            {
+              text: "5",
+              value: 3,
+            },
+            {
+              text: "6",
+              value: 3,
+            },
+            {
+              text: "7",
+              value: 3,
+            },
+            {
+              text: "8",
+              value: 3,
+            },
+            {
+              text: "9",
+              value: 3,
+            },
+            {
+              text: "10",
+              value: 3,
+            },
+            {
+              text: "11",
+              value: 3,
+            },
+            {
+              text: "12",
+              value: 3,
+            },
+            {
+              text: "13",
+              value: 3,
+            },
+            {
+              text: "14",
+              value: 3,
+            },
+            {
+              text: "15",
+              value: 3,
+            },
+            {
+              text: "16",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "上网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["(MW)"],
+    },
+    showLegend: {
+      type: Boolean,
+      default: false,
+    },
+    smooth: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b"],
+    };
+  },
+  computed: {
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      return this.list[0].value.map((t) => {
+        return t.text;
+      });
+    },
+    yAxis() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        result.push({
+          type: "value",
+          name: value,
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: util.vh(14),
+          },
+          //分格线
+          splitLine: {
+            lineStyle: {
+              color:
+                this.$store.state.themeName === "dark"
+                  ? partten.getColor("gray")
+                  : "#000" + 55,
+              type: "dashed",
+            },
+          },
+        });
+      });
+
+      return result;
+    },
+    series() {
+      let result = [];
+
+      this.list.forEach((value, index) => {
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: this.smooth,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              color: this.color[index],
+              width: 1,
+            },
+          },
+          yAxisIndex: value.yAxisIndex,
+          data: value.value.map((t) => {
+            return t.value;
+          }),
+        });
+      });
+
+      return result;
+    },
+  },
+  methods: {
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor:
+            this.$store.state.themeName === "dark"
+              ? "rgba(0,0,0,0.4)"
+              : "rgba(255,255,255,0.5)",
+          borderColor:
+            this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: util.vh(16),
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor:
+            this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color:
+              this.$store.state.themeName === "dark"
+                ? partten.getColor("grayl")
+                : "#000",
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: util.vh(32),
+          left: util.vh(40),
+          right: util.vh(40),
+          bottom: util.vh(24),
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: util.vh(14),
+              textStyle: {
+                color:
+                  this.$store.state.themeName === "dark"
+                    ? partten.getColor("gray")
+                    : "#000",
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.$nextTick(() => {
+      this.id = "pie-chart-" + util.newGUID();
+    });
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="scss">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 391 - 0
src/components/chart/line/simple-line-chart.vue

@@ -0,0 +1,391 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "double-line-chart",
+  componentName: "double-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "50px",
+    },
+    title: {
+      type: String,
+      default: "风机",
+    },
+    // 传入数据
+    data: {
+      type: Array,
+      default: () => {
+        return [
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          1,
+          0,
+          0,
+          0,
+          0,
+          0,
+          1,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          1,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+          0,
+        ];
+      },
+    },
+    // 单位
+    color: {
+      type: String,
+      default: "green",
+    },
+    lineTitle:{
+      type: Array,
+      default: () => [],
+    }
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      // 时间轴
+      xData: [
+        "00:00",
+        "00:15",
+        "00:30",
+        "00:45",
+        "01:00",
+        "01:15",
+        "01:30",
+        "01:45",
+        "02:00",
+        "02:15",
+        "02:30",
+        "02:45",
+        "03:00",
+        "03:15",
+        "03:30",
+        "03:45",
+        "04:00",
+        "04:15",
+        "04:30",
+        "04:45",
+        "05:00",
+        "05:15",
+        "05:30",
+        "05:45",
+        "06:00",
+        "06:15",
+        "06:30",
+        "06:45",
+        "07:00",
+        "07:15",
+        "07:30",
+        "07:45",
+        "08:00",
+        "08:15",
+        "08:30",
+        "08:45",
+        "09:00",
+        "09:15",
+        "09:30",
+        "09:45",
+        "10:00",
+        "10:15",
+        "10:30",
+        "10:45",
+        "11:00",
+        "11:15",
+        "11:30",
+        "11:45",
+        "12:00",
+        "12:15",
+        "12:30",
+        "12:45",
+        "13:00",
+        "13:15",
+        "13:30",
+        "13:45",
+        "14:00",
+        "14:15",
+        "14:30",
+        "14:45",
+        "15:00",
+        "15:15",
+        "15:30",
+        "15:45",
+        "16:00",
+        "16:15",
+        "16:30",
+        "16:45",
+        "17:00",
+        "17:15",
+        "17:30",
+        "17:45",
+        "18:00",
+        "18:15",
+        "18:30",
+        "18:45",
+        "19:00",
+        "19:15",
+        "19:30",
+        "19:45",
+        "20:00",
+        "20:15",
+        "20:30",
+        "20:45",
+        "21:00",
+        "21:15",
+        "21:30",
+        "21:45",
+        "22:00",
+        "22:15",
+        "22:30",
+        "22:45",
+        "23:00",
+        "23:15",
+        "23:30",
+        "23:45",
+      ],
+    };
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        title: {
+          text: this.title,
+          textStyle: {
+            color: "#ffffffcc",
+            fontSize: 14,
+          },
+          left: 16,
+          top: 0,
+        },
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: util.vh(16),
+          },
+        },
+        grid: {
+          top: 40,
+          left: 16,
+          right: 16,
+          bottom: 32,
+        },
+        xAxis: [
+          {
+            type: "category",
+            data: this.xData,
+            axisLine: {
+              show: false,
+              lineStyle: {
+                color: partten.getColor("gray"),
+              },
+            },
+            axisLabel: {
+              show: true,
+              margin: 16,
+              interval: 7,
+            },
+            axisTick: {
+              show: false,
+              lineStyle: {
+                color: partten.getColor("gray"),
+              },
+            },
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            splitNumber: 1,
+            min: 0,
+            max: 1,
+            axisLine: {
+              show: false,
+            },
+            axisLabel: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              lineStyle: {
+                color: partten.getColor("gray"),
+              },
+            },
+          },
+        ],
+        series: [
+          {
+            type: "line",
+            data: this.data,
+            showAllSymbol: true,
+            symbol: "circle",
+            symbolSize: 10,
+            lineStyle: {
+              normal: {
+                color: this.colorValue,
+                width: 1,
+              },
+            },
+            label: {
+              show: false,
+            },
+            itemStyle: {
+              color: this.colorValue,
+              shadowColor: this.colorValue,
+              shadowBlur: 4,
+            },
+          },
+        ],
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function() {
+        chart.resize();
+      };
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.xData = this.lineTitle;
+    this.$nextTick(()=>{
+      this.id = "pie-chart-" + util.newGUID();
+    });
+  },
+  mounted() {
+    this.xData = this.lineTitle;
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.xData = this.lineTitle;
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 312 - 0
src/components/chart/line/stright-line-chart.vue

@@ -0,0 +1,312 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "normal-line-chart",
+  componentName: "normal-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "日发电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+            {
+              text: "5",
+              value: 3,
+            },
+            {
+              text: "6",
+              value: 3,
+            },
+            {
+              text: "7",
+              value: 3,
+            },
+            {
+              text: "8",
+              value: 3,
+            },
+            {
+              text: "9",
+              value: 3,
+            },
+            {
+              text: "10",
+              value: 3,
+            },
+            {
+              text: "11",
+              value: 3,
+            },
+            {
+              text: "12",
+              value: 3,
+            },
+            {
+              text: "13",
+              value: 3,
+            },
+            {
+              text: "14",
+              value: 3,
+            },
+            {
+              text: "15",
+              value: 3,
+            },
+            {
+              text: "16",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "上网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["(MW)"],
+    },
+    showLegend: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b"],
+    };
+  },
+  computed: {
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      return this.list[0].value.map((t) => {
+        return t.text;
+      });
+    },
+    yAxis() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        result.push({
+          type: "value",
+          name: value,
+          axisLine: { show: false },
+          axisTick: { show: false },
+          axisLabel: { show: false },
+          splitLine: { show: false },
+        });
+      });
+
+      return result;
+    },
+    series() {
+      let result = [];
+
+      this.list.forEach((value, index) => {
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: false,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              color: this.color[3],
+              width: 1,
+            },
+          },
+          showSymbol: false,
+          symbol: "circle", //数据交叉点样式
+          areaStyle: {
+            normal: {
+              color: new echarts.graphic.LinearGradient(
+                0,
+                0,
+                0,
+                1,
+                [
+                  {
+                    offset: 0,
+                    color: this.hexToRgba(this.color[3], 0.3),
+                  },
+                  {
+                    offset: 1,
+                    color: this.hexToRgba(this.color[3], 0.1),
+                  },
+                ],
+                false
+              ),
+              shadowColor: this.hexToRgba(this.color[3], 0.1),
+              shadowBlur: 10,
+            },
+          },
+          yAxisIndex: value.yAxisIndex,
+          data: value.value.map((t) => {
+            return t.value;
+          }),
+        });
+      });
+
+      return result;
+    },
+  },
+  methods: {
+    hexToRgba(hex, opacity) {
+      let rgbaColor = "";
+      let reg = /^#[\da-f]{6}$/i;
+      if (reg.test(hex)) {
+        rgbaColor = `rgba(${parseInt("0x" + hex.slice(1, 3))},${parseInt(
+          "0x" + hex.slice(3, 5)
+        )},${parseInt("0x" + hex.slice(5, 7))},${opacity})`;
+      }
+      return rgbaColor;
+    },
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          textStyle: {
+            color: "#fff",
+            fontSize: util.vh(16),
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: partten.getColor("gray"),
+          textStyle: {
+            color: partten.getColor("grayl"),
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: util.vh(32),
+          left: util.vh(40),
+          right: util.vh(40),
+          bottom: util.vh(24),
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: util.vh(14),
+              textStyle: {
+                color: partten.getColor("gray"),
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function() {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        this.$el.style.width = this.width;
+        this.$el.style.height = this.height;
+        this.initChart();
+      }, 1000);
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 185 - 0
src/components/chart/line/table-line-chart.vue

@@ -0,0 +1,185 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "normal-line-chart",
+  componentName: "normal-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "280px",
+    },
+    height: {
+      type: String,
+      default: "24px",
+    },
+    // 数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          text: "1",
+          value: 3,
+        },
+        {
+          text: "2",
+          value: 2,
+        },
+        {
+          text: "3",
+          value: 1,
+        },
+      ],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    xdata() {
+      return this.list.map((t,index) => {
+        return t.text || index;
+      });
+    },
+    values() {
+      return this.list.map((t) => {
+        return t.value || t;
+      });
+    },
+  },
+  methods: {
+    hexToRgba(hex, opacity) {
+      let rgbaColor = "";
+      let reg = /^#[\da-f]{6}$/i;
+      if (reg.test(hex)) {
+        rgbaColor = `rgba(${parseInt("0x" + hex.slice(1, 3))},${parseInt("0x" + hex.slice(3, 5))},${parseInt("0x" + hex.slice(5, 7))},${opacity})`;
+      }
+      return rgbaColor;
+    },
+    initChart() {
+      let chart = echarts.init(this.$el);
+      let color = [partten.getColor("green")];
+
+      let option = {
+        color: color,
+        grid: {
+          top: 4,
+          bottom: 0,
+          left: 8,
+          right: 8,
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLine: {
+              show: true,
+              lineStyle: {
+                color: partten.getColor("gray"),
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            // 分割线
+            splitLine: {
+              show: false,
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+          },
+        ],
+        series: [
+          {
+            type: "line",
+            lineStyle: {
+              normal: {
+                color: color[0],
+              },
+            },
+            animation: false,
+            symbol: "circle", //数据交叉点样式
+            areaStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(
+                  0,
+                  0,
+                  0,
+                  1,
+                  [
+                    {
+                      offset: 0,
+                      color: this.hexToRgba(color[0], 0.3),
+                    },
+                    {
+                      offset: 1,
+                      color: this.hexToRgba(color[0], 0.1),
+                    },
+                  ],
+                  false
+                ),
+                shadowColor: this.hexToRgba(color[0], 0.1),
+                shadowBlur: 10,
+              },
+            },
+            data: this.values,
+          },
+        ],
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function() {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        this.$el.style.width = this.width;
+        this.$el.style.height = this.height;
+        this.initChart();
+      }, 1000);
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 201 - 0
src/components/chart/line/weather-line-chart.vue

@@ -0,0 +1,201 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "weather-line-chart",
+  componentName: "weather-line-char",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "270px",
+    },
+    list: {
+      type: Array,
+      default: [],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  methods: {
+    initChart() {
+      let that = this;
+      const chart = echarts.init(this.$el);
+      const xData = [];
+      const fsData = [];
+      this.list.forEach((element) => {
+        xData.push(new Date(element.time).formatDate("hh时"));
+        fsData.push(element.fs + 5);
+      });
+      let option = {
+        grid: {
+          top: 50,
+          bottom: 50,
+          left: 20,
+          right:20
+        },
+        tooltip: {
+          trigger: "axis",
+          formatter: function (params) {
+            const data = params[0]["data"];
+            new Date(data.time).formatDate("yyyy-MM-dd hh时");
+            return [
+              new Date(data.time).formatDate("yyyy-MM-dd hh时"),
+              "天气:" + data.tqmc + "",
+              "风速:" + data.fs + " m/s",
+              "风向:" + data.fx + " 度",
+              "气温:" + data.wd + " ℃",
+              "大气压强:" + data.dqyl + " pa",
+              "湿度:" + data.sd + " %",
+            ].join("<br>");
+          },
+        },
+        xAxis: {
+          type: "category",
+          data: xData,
+        },
+        yAxis: [
+          {
+            axisLine: { show: false },
+            axisTick: { show: false },
+            axisLabel: { show: false },
+            splitLine: { show: false },
+          },
+          {
+            type: "value",
+            // max: 25,
+            axisLine: { show: false },
+            axisTick: { show: false },
+            axisLabel: { show: false },
+            splitLine: { show: false },
+          },
+        ],
+
+        series: [
+          {
+            type: "custom",
+            renderItem: function (param, api) {
+              const spiltSize = 2;
+              if (param.dataIndex % spiltSize == 0 && that.list) {
+                const xx = param.coordSys.width / ((that.list.length / spiltSize) | 1);
+                const x = param.coordSys.x + xx * (param.dataIndex / spiltSize) * 1.05;
+                const y = param.coordSys.y - 30;
+                const image = require("@assets/icon/svg/weather/" + that.list[param.dataIndex]["tqtp"] + ".png");
+                return {
+                  type: "group",
+                  children: [
+                    {
+                      type: "image",
+                      style: {
+                        image: image,
+                        x: -5,
+                        y: 0,
+                        width: 30,
+                        height: 30,
+                      },
+                      position: [x, y],
+                    },
+                  ],
+                };
+              }
+            },
+            data: this.list,
+            yAxisIndex: 0,
+            z: 11,
+          },
+          {
+            type: "custom",
+            renderItem: function (param, api) {
+              const spiltSize = 2;
+              if (param.dataIndex % spiltSize == 0 && that.list) {
+                const xx = param.coordSys.width / ((that.list.length / spiltSize) | 1);
+                const x = param.coordSys.x + 8 + xx * (param.dataIndex / spiltSize) * 1.05;
+                const y = param.coordSys.y;
+                return {
+                  type: "path",
+                  shape: {
+                    pathData: "M31 16l-15-15v9h-26v12h26v9z",
+                    x: -15 / 2,
+                    y: -15 / 2,
+                    width: 15,
+                    height: 15,
+                  },
+                  rotation: (Math.PI / 180) * (that.list[param.dataIndex]["fx"] + 90),
+                  // rotation: (Math.PI / 180) * 45,
+                  position: [x, 200],
+                  style: api.style({
+                    stroke: "#555",
+                    lineWidth: 1,
+                  }),
+                };
+              }
+            },
+
+            data: that.list,
+            z: 10,
+          },
+          {
+            type: "line",
+            lineStyle: { normal: { color: "#303f6e" } },
+            data: fsData,
+            z: 1,
+          },
+        ],
+      };
+
+      chart.clear();
+      chart.setOption(option);
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        this.$el.style.width = this.width;
+        this.$el.style.height = this.height;
+        this.initChart();
+      }, 500);
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        this.$el.style.width = this.width;
+        this.$el.style.height = this.height;
+        this.initChart();
+      }, 1000);
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 333 - 0
src/components/chart/line/zoom-line-chart.vue

@@ -0,0 +1,333 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "normal-line-chart",
+  componentName: "normal-line-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "日发电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+            {
+              text: "5",
+              value: 3,
+            },
+            {
+              text: "6",
+              value: 3,
+            },
+            {
+              text: "7",
+              value: 3,
+            },
+            {
+              text: "8",
+              value: 3,
+            },
+            {
+              text: "9",
+              value: 3,
+            },
+            {
+              text: "10",
+              value: 3,
+            },
+            {
+              text: "11",
+              value: 3,
+            },
+            {
+              text: "12",
+              value: 3,
+            },
+            {
+              text: "13",
+              value: 3,
+            },
+            {
+              text: "14",
+              value: 3,
+            },
+            {
+              text: "15",
+              value: 3,
+            },
+            {
+              text: "16",
+              value: 3,
+            },
+          ],
+        },
+        {
+          title: "上网电量",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "4",
+              value: 3,
+            },
+          ],
+        },
+      ],
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["(MW)"],
+    },
+    showLegend: {
+      type: Boolean,
+      default: false,
+    },
+    smooth: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b"],
+    };
+  },
+  computed: {
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      return this.list[0].value.map((t) => {
+        return t.text;
+      });
+    },
+    yAxis() {
+      let result = [];
+      this.units.forEach((value, index) => {
+        result.push({
+          type: "value",
+          name: value,
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: util.vh(14),
+          },
+          //分格线
+          splitLine: {
+            lineStyle: {
+              color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000" + 55,
+              type: "dashed",
+            },
+          },
+        });
+      });
+
+      return result;
+    },
+    series() {
+      let result = [];
+
+      this.list.forEach((value, index) => {
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: this.smooth,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              color: this.color[index],
+              width: 1,
+            },
+          },
+          yAxisIndex: value.yAxisIndex,
+          data: value.value.map((t) => {
+            return t.value;
+          }),
+        });
+      });
+
+      return result;
+    },
+  },
+  methods: {
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: this.$store.state.themeName === "dark" ? "rgba(0,0,0,0.4)" : "rgba(255,255,255,0.5)",
+          borderColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: util.vh(16),
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? partten.getColor("grayl") : "#000",
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: 32,
+          left: 40,
+          right: 40,
+          bottom: 80,
+        },
+        dataZoom: [
+          {
+            type: "inside",
+            start: 0,
+            end: 100,
+          },
+          {
+            start: 0,
+            end: 100,
+            height: 40,
+            bottom: 8,
+            backgroundColor: "transparent",
+            // handleIcon: "path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z",
+            handleStyle: {
+              color: partten.getColor("yellow"),
+            },
+            moveHandleSize: 0,
+            dataBackground: {
+              lineStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+              },
+              areaStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+              },
+            },
+            selectedDataBackground: {
+              lineStyle: {
+                color: partten.getColor("yellow"),
+              },
+              areaStyle: {
+                color: partten.getColor("yellow"),
+              },
+            },
+            fillerColor: "transparent",
+            textStyle: {
+              color: this.$store.state.themeName === "dark" ? partten.getColor("grayl") : "#000",
+            },
+            borderColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+            brushSelect: false,
+          },
+        ],
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: util.vh(14),
+              textStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("grayl") : "#000",
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function() {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+  watch: {
+      "$store.state.themeName"() {
+        this.initChart();
+      },
+    },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 238 - 0
src/components/chart/other/Dashboard.vue

@@ -0,0 +1,238 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "Dashboard-chart",
+  componentName: "Dashboard-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "100%",
+    },
+    value: {
+      type: Number,
+      default: 50,
+    },
+    max: {
+      type: Number,
+      default: 100,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {},
+  methods: {
+    initChart() {
+      let chart = echarts.init(this.$el);
+      let option = {
+        tooltip: {
+          formatter: "{a} <br/>{b} : {c}%",
+        },
+        series: [
+          {
+            name: "内部进度条",
+            type: "gauge",
+            // center: ['50%', '50%'],
+            radius: "80%",
+            z: 4,
+            splitNumber: 10,
+            axisLine: {
+              lineStyle: {
+                color: [
+                  [this.value / 100, partten.getColor("green")],
+                  [1, partten.getColor("gray")],
+                ],
+                width: 8,
+              },
+            },
+            axisLabel: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+            itemStyle: {
+              show: false,
+            },
+            detail: {
+              formatter: function(value) {
+                if (value !== 0) {
+                  var num = Math.round(value);
+                  return parseInt(num).toFixed(0) + "";
+                } else {
+                  return 0;
+                }
+              },
+              offsetCenter: [0, "75%"],
+              textStyle: {
+                padding: [0, 0, 0, 0],
+                fontSize: 20,
+                fontWeight: "700",
+                color: partten.getColor("green"),
+              },
+            },
+            title: {
+              show: false,
+            },
+            data: [
+              {
+                name: this.value,
+                value: this.value,
+              },
+            ],
+            pointer: {
+              show: true,
+              length: "70%",
+              radius: "20%",
+              width: 2, //指针粗细
+              itemStyle: {
+                color: partten.getColor("green"),
+              },
+            },
+            animationDuration: 1500,
+          },
+          // 内圆
+          {
+            name: "内圆",
+            type: "pie",
+            hoverAnimation: false,
+            legendHoverLink: false,
+            radius: "8%",
+            z: 4,
+            labelLine: {
+              normal: {
+                show: false,
+              },
+            },
+            data: [
+              {
+                value: 0,
+              },
+              {
+                value: 10,
+                itemStyle: {
+                  normal: {
+                    color: "#161f1e",
+                  },
+                  emphasis: {
+                    color: "#161f1e",
+                  },
+                },
+              },
+            ],
+          },
+          // 圆环
+          {
+            name: "小圆形",
+            type: "pie",
+            hoverAnimation: false,
+            legendHoverLink: false,
+            radius: ["8%", "5%"],
+            z: 5,
+            labelLine: {
+              normal: {
+                show: false,
+              },
+            },
+            data: [
+              {
+                value: 0,
+              },
+              {
+                value: 10,
+                itemStyle: {
+                  normal: {
+                    color: partten.getColor("green"),
+                  },
+                },
+              },
+            ],
+          },
+          {
+            name: "外部刻度",
+            type: "gauge",
+            radius: "94%",
+            min: 0, //最小刻度
+            max: this.max, //最大刻度
+            splitNumber: 4, //刻度数量
+            startAngle: 225,
+            endAngle: -45,
+            axisLine: {
+              show: false,
+            },
+            //仪表盘轴线
+            axisLabel: {
+              show: true,
+              distance: 16,
+              fontSize: 12,
+            },
+            //刻度标签。
+            axisTick: {
+              show: true,
+              splitNumber: 4,
+              lineStyle: {
+                color: partten.getColor("gray"), //用颜色渐变函数不起作用
+                width: 1,
+              },
+              length: 4,
+            },
+            //刻度样式
+            splitLine: {
+              show: false,
+            },
+            //分隔线样式
+            detail: {
+              show: false,
+            },
+            pointer: {
+              show: true,
+            },
+          },
+        ],
+      };
+
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 171 - 0
src/components/chart/other/Dashboard2.vue

@@ -0,0 +1,171 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "Dashboard-chart",
+  componentName: "Dashboard-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "100%",
+    },
+    name: {
+      type: String,
+      default: "万kWh",
+    },
+    value: {
+      type: Number,
+      default: 50,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {},
+  methods: {
+    initChart() {
+		let themeName = '';
+		this.$store.state.themeName === "dark" ? themeName = true : themeName = false;
+		 
+      let chart = echarts.init(this.$el);
+      let value = this.value;
+      let option = {
+        grid: {
+          top: 8,
+          bottom: -16,
+          left: 8,
+          right: 8,
+        },
+        series: [
+          {
+            type: "gauge", //刻度轴表盘
+            radius: "115%", //刻度盘的大小
+            center: ["50%", "75%"],
+            startAngle: 180, //开始刻度的角度
+            endAngle: 0, //结束刻度的角度
+            axisLine: {
+              show: true,
+              lineStyle: {
+                width: 8,
+                color: [
+                  [0, partten.getColor("gray") + "33"],
+                  [value / 100,themeName ? partten.getColor("green") : partten.getColor("blue")],
+                  [1, partten.getColor("gray") + "33"],
+                ],
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+            axisLabel: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            pointer: {
+              show: false,
+            },
+            title: {
+              show: true,
+              offsetCenter: [0, "-40%"],
+              textStyle: {
+                color: partten.getColor("gray"),
+                fontSize: util.vh(12),
+              },
+            },
+            detail: {
+              show: true,
+              offsetCenter: [0, "0%"],
+              color: "#ffffff",
+              formatter: function(params) {
+                return params;
+              },
+              textStyle: {
+                color: themeName ? partten.getColor("green") : partten.getColor("blue"),
+                fontSize: util.vh(16),
+              },
+            },
+            data: [
+              {
+                name: "万kWh",
+                value: value,
+              },
+            ],
+          },
+          {
+            type: "gauge",
+            radius: "115%",
+            center: ["50%", "75%"],
+            startAngle: 180,
+            endAngle: 0,
+            axisLine: {
+              show: true,
+              lineStyle: {
+                width: 1,
+                color: [
+                  [this.value / 100, themeName ? partten.getColor("green") : partten.getColor("blue")],
+                  [1, "#fff5"],
+                ],
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+            axisLabel: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            detail: { show: false },
+          },
+        ],
+      };
+
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  watch: {
+      "$store.state.themeName"() {
+        this.initChart();
+      },
+    },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 194 - 0
src/components/chart/other/thermometer-chart.vue

@@ -0,0 +1,194 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "thermometer-chart",
+  componentName: "thermometer-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "100%",
+    },
+    value: {
+      type: Number,
+      default: 80,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    barValue() {
+      return [this.value * 0.8 + 16];
+    },
+  },
+  methods: {
+    hexToRgba(hex, opacity) {
+      let rgbaColor = "";
+      let reg = /^#[\da-f]{6}$/i;
+      if (reg.test(hex)) {
+        rgbaColor = `rgba(${parseInt("0x" + hex.slice(1, 3))},${parseInt("0x" + hex.slice(3, 5))},${parseInt("0x" + hex.slice(5, 7))},${opacity})`;
+      }
+      return rgbaColor;
+    },
+    initChart() {
+      var mercuryColor = "#05BB4C";
+      var borderColor = partten.getColor("gray");
+
+      let option = {
+        grid: {
+          top: 8,
+          bottom: 8,
+          left: 8,
+          right: 8,
+        },
+        yAxis: [
+          {
+            show: false,
+            position: "left",
+          },
+          {
+            show: false,
+            data: [],
+            min: 0,
+            max: 9,
+          },
+        ],
+        xAxis: [
+          {
+            show: false,
+            data: [],
+            max: 3,
+          },
+          {
+            show: false,
+            data: [],
+            max: 3,
+          },
+          {
+            show: false,
+            data: [],
+            max: 4,
+          },
+          {
+            show: false,
+            min: -35, //根据容器大小调整此处最小值和最大值,以正常显示刻度
+            max: 80,
+          },
+        ],
+        series: [
+          {
+            name: "条",
+            type: "bar",
+            xAxisIndex: 0,
+            data: this.barValue,
+            barWidth: 16,
+            itemStyle: {
+              normal: {
+                color: mercuryColor,
+                barBorderRadius: 100,
+                borderWidth: 8,
+                borderType: "dashed",
+                borderColor: "transparent",
+              },
+            },
+            z: 2,
+          },
+          {
+            name: "外框",
+            type: "bar",
+            xAxisIndex: 2,
+            barGap: "-100%",
+            data: [100],
+            barWidth: 18,
+            itemStyle: {
+              normal: {
+                color: "transparent",
+                barBorderRadius: 50,
+                borderWidth: 1,
+                borderColor: borderColor,
+              },
+            },
+            z: 0,
+          },
+          {
+            name: "刻度",
+            type: "bar",
+            yAxisIndex: 1,
+            xAxisIndex: 3,
+            label: {
+              normal: {
+                show: true,
+                position: "right",
+                distance: 8,
+                color: borderColor,
+                fontSize: 12,
+                formatter: function(params) {
+                  if (params.dataIndex == 1) {
+                    return "0%";
+                  } else if (params.dataIndex == 5) {
+                    return "50%";
+                  } else if (params.dataIndex == 9) {
+                    return "100%";
+                  } else {
+                    return "";
+                  }
+                },
+              },
+            },
+            barGap: "-100%",
+            data: [0, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5],
+            barWidth: 2,
+            itemStyle: {
+              normal: {
+                color: borderColor,
+                barBorderRadius: 10,
+              },
+            },
+            z: 0,
+          },
+        ],
+      };
+
+      this.chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.chart = echarts.init(this.$el);
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 197 - 0
src/components/chart/other/thermometer-v-chart.vue

@@ -0,0 +1,197 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "thermometer-chart",
+  componentName: "thermometer-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "60px",
+    },
+    value: {
+      type: Number,
+      default: 80,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    barValue() {
+      return [this.value * 0.8 + 16];
+    },
+  },
+  methods: {
+    hexToRgba(hex, opacity) {
+      let rgbaColor = "";
+      let reg = /^#[\da-f]{6}$/i;
+      if (reg.test(hex)) {
+        rgbaColor = `rgba(${parseInt("0x" + hex.slice(1, 3))},${parseInt("0x" + hex.slice(3, 5))},${parseInt("0x" + hex.slice(5, 7))},${opacity})`;
+      }
+      return rgbaColor;
+    },
+    initChart() {
+      var borderColor = partten.getColor("gray");
+		let themeName = '';
+		this.$store.state.themeName === "dark" ? themeName = true : themeName = false;
+      let option = {
+        grid: {
+          top: 0,
+          bottom: 24,
+          left: 16,
+          right: 16,
+        },
+        xAxis: [
+          {
+            show: false,
+            position: "left",
+          },
+          {
+            show: false,
+            data: [],
+            min: 0,
+            max: 9,
+          },
+        ],
+        yAxis: [
+          {
+            show: false,
+            data: [],
+            max: 0,
+          },
+          {
+            show: false,
+            data: [],
+            max: 0,
+          },
+          {
+            show: false,
+            data: [],
+            max: 0,
+          },
+          {
+            show: false,
+            min: -5, //根据容器大小调整此处最小值和最大值,以正常显示刻度
+            max: 100,
+          },
+        ],
+        series: [
+          {
+            name: "条",
+            type: "bar",
+            yAxisIndex: 0,
+            data: this.barValue,
+            barWidth: 16,
+            itemStyle: {
+              normal: {
+                color: themeName ? partten.getColor("green") : partten.getColor("deepblue"),
+                barBorderRadius: 100,
+                borderWidth: 8,
+                borderType: "dashed",
+                borderColor: "transparent",
+              },
+            },
+            z: 2,
+          },
+          {
+            name: "外框",
+            type: "bar",
+            yAxisIndex: 2,
+            barGap: "-100%",
+            data: [100],
+            barWidth: 18,
+            itemStyle: {
+              normal: {
+                color: "transparent",
+                barBorderRadius: 50,
+                borderWidth: 1,
+                borderColor: borderColor,
+              },
+            },
+            z: 0,
+          },
+          {
+            name: "刻度",
+            type: "bar",
+            xAxisIndex: 1,
+            yAxisIndex: 3,
+            label: {
+              normal: {
+                show: true,
+                position: "bottom",
+                distance: 8,
+                color: borderColor,
+                fontSize: 12,
+                formatter: function(params) {
+                  if (params.dataIndex == 1) {
+                    return "0%";
+                  } else if (params.dataIndex == 5) {
+                    return "50%";
+                  } else if (params.dataIndex == 9) {
+                    return "100%";
+                  } else {
+                    return "";
+                  }
+                },
+              },
+            },
+            barGap: "-100%",
+            data: [0, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5],
+            barWidth: 2,
+            itemStyle: {
+              normal: {
+                color: borderColor,
+                barBorderRadius: 10,
+              },
+            },
+            z: 0,
+          },
+        ],
+      };
+
+      this.chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.chart = echarts.init(this.$el);
+      this.initChart();
+    });
+  },
+  updated() {
+    this.initChart();
+  },
+  watch: {
+      "$store.state.themeName"() {
+        this.initChart();
+      },
+    },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 392 - 0
src/components/chart/pie/dash-pie-chart.vue

@@ -0,0 +1,392 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+import $ from "jquery";
+
+export default {
+  name: "dsah-pie",
+  componentName: "dsah-pie",
+  props: {
+    // 宽度 默认9.722vh
+    width: {
+      type: String,
+      default: "85%",
+    },
+    // 高度 默认9.722vh
+    height: {
+      type: String,
+      default: "7.4074vh",
+    },
+    // 标题
+    title: {
+      type: String,
+      default: "标题",
+    },
+    // 值
+    value: {
+      type: Number,
+      default: 42.1,
+    },
+    // 最小值
+    min: {
+      type: Number,
+      default: 0,
+    },
+    // 最大值
+    max: {
+      type: Number,
+      default: 100,
+    },
+    // 颜色 传入 green yellow等 (partten中支持的颜色)
+    color: {
+      type: String,
+      default: "green",
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      let chart = echarts.init(this.$el);
+      let option = {
+        title: {
+          show: true,
+          text: this.title,
+          x: "45%",
+          y: "80%",
+          z: 8,
+          textAlign: "center",
+          textStyle: {
+            color: $("#appBody").is(".dark")
+              ? partten.getColor("gray")
+              : "#000",
+            fontSize: util.vh(12),
+            fontWeight: "normal",
+          },
+        },
+        series: [
+          // 进度条
+          {
+            z: 1,
+            name: "内部(环形)进度条",
+            type: "gauge",
+            radius: "100%",
+            splitNumber: 5,
+            axisLine: {
+              lineStyle: {
+                color: [
+                  [
+                    this.value / this.max,
+                    new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+                      {
+                        offset: 0,
+                        color: $("#appBody").is(".dark")
+                          ? partten.getColor(this.color) + "01"
+                          : partten.getColor('deepblue') + "01",
+                      },
+                      {
+                        offset: 1,
+                        color: $("#appBody").is(".dark")
+                          ? partten.getColor(this.color) + "ff"
+                          : partten.getColor('deepblue') + "ff",
+                      },
+                    ]),
+                  ],
+                  [1, "transparent"],
+                ],
+                width: util.vh(12),
+              },
+            },
+            axisLabel: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+            pointer: {
+              show: false,
+            },
+          },
+          // 指针
+          {
+            name: "指针",
+            type: "gauge",
+            z: 2,
+            min: this.min,
+            max: this.max,
+            radius: "100%",
+            axisLine: {
+              show: false,
+            },
+            tooltip: {
+              show: false,
+            },
+            axisLabel: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+            detail: {
+              show: false,
+            },
+            title: {
+              //标题
+              show: false,
+            },
+            data: [
+              {
+                value: this.value,
+              },
+            ],
+            itemStyle: {
+              normal: {
+                color: $("#appBody").is(".dark") ? "#fff" : "#000",
+              },
+            },
+            pointer: {
+              show: true,
+              length: "35%",
+              radius: "20%",
+              width: 1, //指针粗细
+              offsetCenter: ["0%", "-40%"],
+            },
+            animationDuration: 0,
+          },
+          // 刻度
+          {
+            name: "外部刻度",
+            type: "gauge",
+            //  center: ['20%', '50%'],
+            radius: "100%",
+            min: this.min, //最小刻度
+            max: this.max, //最大刻度
+            splitNumber: 10, //刻度数量
+            startAngle: 225,
+            endAngle: -45,
+            axisLine: {
+              show: true,
+              // 仪表盘刻度线
+              lineStyle: {
+                width: util.vh(1),
+                color: [
+                  [
+                    1,
+                    $("#appBody").is(".dark")
+                      ? partten.getColor(this.color)
+                      : "rgb(57, 54, 143)",
+                  ],
+                ],
+              },
+            },
+            //仪表盘文字
+            axisLabel: {
+              show: false,
+            },
+            //刻度标签。
+            axisTick: {
+              show: true,
+              distance: 6,
+              splitNumber: 2,
+              lineStyle: {
+                color: $("#appBody").is(".dark")
+                  ? partten.getColor("green")
+                  : "rgb(57, 54, 143)", //用颜色渐变函数不起作用
+                width: util.vh(1),
+              },
+              length: util.vh(4),
+            }, //刻度样式
+            splitLine: {
+              show: false,
+            }, //分隔线样式
+            detail: {
+              show: false,
+            },
+            pointer: {
+              show: false,
+            },
+          },
+          // 显示数字
+          {
+            type: "pie",
+            radius: ["0", "40%"],
+            center: ["50%", "50%"],
+            z: 8,
+            animation: false,
+            hoverAnimation: false,
+            data: [
+              {
+                value: this.value,
+                itemStyle: {
+                  normal: {
+                    color: "transition",
+                  },
+                },
+                label: {
+                  normal: {
+                    formatter: function (params) {
+                      return params.value;
+                    },
+                    color: $("#appBody").is(".dark")
+                  ? partten.getColor(this.color)
+                  : "rgb(57, 54, 143)",
+                    fontSize: util.vh(12),
+                    fontWeight: "bold",
+                    position: "center",
+                    show: true,
+                  },
+                },
+                labelLine: {
+                  show: false,
+                },
+              },
+            ],
+          },
+          {
+            name: "内部阴影",
+            type: "gauge",
+            radius: "90%",
+            splitNumber: 10,
+            axisLine: {
+              lineStyle: {
+                color: [
+                  // [
+                  //   1,
+                  //   new echarts.graphic.LinearGradient(0, 1, 0, 0, [
+                  //     {
+                  //       offset: 0,
+                  //       color: "rgba(45,230,150,0)",
+                  //     },
+                  //     {
+                  //       offset: 0.5,
+                  //       color: "rgba(45,230,150,0.2)",
+                  //     },
+                  //     {
+                  //       offset: 1,
+                  //       color: "rgba(45,230,150,1)",
+                  //     },
+                  //   ]),
+                  // ],
+                  [
+                    1,
+                    $("#appBody").is(".dark")
+                      ? "rgba(45,230,150,0.1)"
+                      : "rgba(57, 54, 143, 0.1)",
+                  ],
+                  // [1, "rgba(45,230,150,0)"],
+                ],
+                width: 3,
+              },
+            },
+            axisLabel: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+            itemStyle: {
+              show: false,
+            },
+          },
+          // 光环
+          {
+            type: "pie",
+            radius: "40%",
+            center: ["50%", "50%"],
+            animationType: "scale",
+            animation: false,
+            label: {
+              show: false,
+            },
+            labelLine: {
+              show: false,
+            },
+            emphasis: {
+              scale: false,
+            },
+            data: [
+              {
+                value: 1,
+                itemStyle: {
+                  color: "transparent",
+                  borderColor: $("#appBody").is(".dark")
+                    ? partten.getColor(this.color)
+                    : "rgb(57, 54, 143)",
+                  opacity: 0.3,
+                  shadowColor: $("#appBody").is(".dark")
+                    ? partten.getColor(this.color)
+                    : "rgb(57, 54, 143)",
+                  shadowBlur: util.vh(20),
+                },
+              },
+            ],
+          },
+        ],
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.removeEventListener("resize", this.resize);
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$el.style.width = this.width;
+    this.$el.style.height = this.height;
+    this.initChart();
+  },
+  updated() {
+    this.initChart();
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+
+  watch: {
+    "$store.state.themeName"() {
+      this.initChart();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: block;
+  margin: auto;
+}
+</style>

+ 248 - 0
src/components/chart/pie/dual-pie-chart.vue

@@ -0,0 +1,248 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "dsah-pie",
+  componentName: "dsah-pie",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "18.519vh",
+    },
+    // 内部饼图数据
+    innerData: {
+      type: Array,
+      default: () => [
+        {
+          value: 700,
+          unit: "个",
+          name: "行业大类1",
+        },
+        {
+          value: 679,
+          unit: "个",
+          name: "行业大类2",
+        },
+        {
+          value: 1548,
+          unit: "个",
+          name: "行业大类3",
+        },
+      ],
+    },
+    // 外部饼图数据
+    outerData: {
+      type: Array,
+      default: () => [
+        {
+          value: 310,
+          unit: "个",
+          name: "邮件营销",
+        },
+        {
+          value: 234,
+          unit: "个",
+          name: "联盟广告",
+        },
+        {
+          value: 335,
+          unit: "个",
+          name: "视频广告",
+        },
+        {
+          value: 548,
+          unit: "个",
+          name: "百度",
+        },
+        {
+          value: 351,
+          unit: "个",
+          name: "谷歌",
+        },
+      ],
+    },
+    // 颜色
+    color: {
+      type: String,
+      default: "green",
+    },
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {},
+  methods: {
+    initChart() {
+      let that = this;
+      let legend1 = this.innerData.map((v) => v.name);
+      let legend2 = this.outerData.map((v) => v.name);
+      let legendData = [...legend1, ...legend2];
+
+      let option = {
+        color: ["#1893ce", "#edbf00", "#039178", "#ae4802", "#ea8b00"],
+        tooltip: {
+          trigger: "item",
+          backgroundColor: this.$store.state.themeName === "dark"
+              ? "rgba(0,0,0,0.4)"
+              : "rgba(255,255,255,0.5)",
+          borderColor: this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: util.vh(16),
+          },
+        },
+        grid: {
+          top: 32,
+          left: 60,
+          right: 40,
+          bottom: 24,
+        },
+        legend: {
+          show: this.showLegend,
+          orient: "vertical", //纵向图例
+          right: "16",
+          bottom: 32,
+          itemWidth: 15,
+          itemHeight: 15,
+          formatter: (name) => {
+            if (that.innerData.length) {
+              const item = that.innerData.filter((item) => item.name === name)[0];
+              return `{name|${name}:}{value| ${item.value}}`;
+            }
+          },
+          //icon: 'circle',
+          itemGap: 12, //图例item间距
+          textStyle: {
+            color: this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+            fontSize: util.vh(14),
+            rich: {
+              name: {
+                color: this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+                fontSize: 12,
+              },
+              value: {
+                color: this.$store.state.themeName === "dark"
+                ? partten.getColor("grayl")
+                : "#000",
+                fontSize: 12,
+              },
+            },
+          },
+          data: legend1,
+        },
+        series: [
+          {
+            name: "",
+            type: "pie",
+            center: ["40%", "50%"],
+            radius: [0, "35%"],
+            itemStyle: {
+              normal: {},
+            },
+            label: {
+              normal: {
+                show: false,
+              },
+            },
+            labelLine: {
+              normal: {
+                show: false,
+              },
+            },
+            data: this.innerData,
+          },
+          {
+            name: "",
+            type: "pie",
+            center: ["40%", "50%"],
+            radius: ["55%", "95%"],
+            data: this.outerData,
+            labelLine: {
+              normal: {
+                // length: 40,
+                // length2: 120,
+                lineStyle: {
+                  color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+                  fontSize: util.vh(14),
+                },
+              },
+            },
+            itemStyle: {
+              normal: {
+                borderWidth:this.$store.state.themeName === "dark" ? util.vh(14): util.vh(8),
+                borderColor: this.$store.state.themeName === "dark" ? "#071812" : '#fff',
+              },
+            },
+            label: {
+              normal: {
+                formatter: (params) => {
+                  return "{percent|" + params.percent.toFixed(2) + "%}";
+                },
+                padding: [0, 0, 0, 0],
+                rich: {
+                  color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+                  percent: {
+                    fontSize: util.vh(14),
+                    color: this.$store.state.themeName === "dark" ? "#FFFFFF" : "#000000" ,
+                  },
+                },
+              },
+            },
+          },
+        ],
+      };
+
+      this.chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$el.style.width = this.width;
+    this.$el.style.height = this.height;
+    this.chart = echarts.init(this.$el);
+    this.initChart();
+  },
+  updated() {
+    this.initChart();
+  },
+  watch: {
+    "$store.state.themeName"() {
+      this.initChart();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: block;
+  margin: auto;
+}
+</style>

+ 134 - 0
src/components/chart/pie/normal-pie-chart.vue

@@ -0,0 +1,134 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "percent-pie",
+  componentName: "percent-pie",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "18.519vh",
+    },
+    // 百分比值
+    // 外部饼图数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          value: 310,
+          name: "邮件营销",
+        },
+        {
+          value: 234,
+          name: "联盟广告",
+        },
+        {
+          value: 335,
+          name: "视频广告",
+        },
+        {
+          value: 548,
+          name: "百度",
+        },
+        {
+          value: 351,
+          name: "谷歌",
+        },
+      ],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {},
+  methods: {
+    initChart() {
+      let option = {
+        color: ["#05bb4c", "#4b55ae", "#fa8c16", "#f8de5b", "#1a93cf", "#c531c7", "#bd3338"],
+        tooltip: {
+          trigger: "item",
+          backgroundColor: this.$store.state.themeName === "dark" ? "rgba(0,0,0,0.4)" : "rgba(255,255,255,0.5)",
+          borderColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: util.vh(16),
+          },
+        },
+        grid: {
+          top: 8,
+          left: 8,
+          right: 8,
+          bottom: 8,
+        },
+        legend: {
+          icon: "circle",
+          orient: "vertical",
+          top: "center",
+          right: "0",
+          align: "left",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+          },
+          itemGap: 8,
+        },
+        series: [
+          {
+            type: "pie",
+            radius: "70%",
+            center: ["35%", "50%"],
+            data: this.list,
+            labelLine: {
+              show: false,
+            },
+            label: {
+              show: false,
+            },
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: "rgba(0, 0, 0, 0.5)",
+              },
+            },
+          },
+        ],
+      };
+
+      this.chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$el.style.width = this.width;
+    this.$el.style.height = this.height;
+    this.chart = echarts.init(this.$el);
+    this.initChart();
+  },
+  updated() {
+    this.initChart();
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 132 - 0
src/components/chart/pie/percent-pie-chart.vue

@@ -0,0 +1,132 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "percent-pie",
+  componentName: "percent-pie",
+  props: {
+    width: {
+      type: String,
+      default: "18.519vh",
+    },
+    height: {
+      type: String,
+      default: "18.519vh",
+    },
+    // 百分比值
+    value: {
+      type: Number,
+      default: 10,
+    },
+    max: {
+      type: Number,
+      default: 100,
+    },
+    // 颜色 green yellow 等 partten支持的颜色
+    color: {
+      type: String,
+      default: "green",
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {
+    colorValue() {
+      return partten.getColor(this.color);
+    },
+  },
+  methods: {
+    initChart() {
+      let option = {
+        calculable: true,
+        series: [
+          {
+            name: "",
+            type: "pie",
+            radius: ["0%", "100%"],
+            center: ["50%", "50%"],
+            data: [
+              {
+                value: this.value,
+                name: "",
+                itemStyle: {
+                  color: this.colorValue,
+                },
+              },
+              {
+                value: this.max - this.value,
+                name: "",
+                itemStyle: {
+                  color: "transparent",
+                },
+              },
+            ],
+            label: {
+              show: false,
+              position: "center",
+            },
+          },
+          {
+            name: "",
+            type: "pie",
+            radius: ["0%", "95%"],
+            center: ["50%", "50%"],
+            data: [
+              {
+                value: this.value,
+                name: "",
+                itemStyle: {
+                  color: "transparent",
+                },
+              },
+              {
+                value: this.max - this.value,
+                name: "",
+                itemStyle: {
+                  color: "#5f6769",
+                },
+              },
+            ],
+            label: {
+              show: false,
+              position: "center",
+            },
+          },
+        ],
+      };
+
+      this.chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$el.style.width = this.width;
+    this.$el.style.height = this.height;
+    this.chart = echarts.init(this.$el);
+    this.initChart();
+  },
+  updated() {
+    this.initChart();
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 291 - 0
src/components/chart/pie/radar-pie-chart.vue

@@ -0,0 +1,291 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "radar-pie",
+  componentName: "radar-pie",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "18.519vh",
+    },
+    // 百分比值
+    // 外部饼图数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          value: 310,
+          name: "邮件营销",
+        },
+        {
+          value: 234,
+          name: "联盟广告",
+        },
+        {
+          value: 335,
+          name: "视频广告",
+        },
+        {
+          value: 548,
+          name: "百度",
+        },
+        {
+          value: 351,
+          name: "谷歌",
+        },
+      ],
+    },
+    title: {
+      type: String,
+      default: "title",
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  computed: {},
+  methods: {
+    initChart() {
+      let option = {
+        color: [
+          "#05bb4c",
+          "#4b55ae",
+          "#fa8c16",
+          "#f8de5b",
+          "#1a93cf",
+          "#c531c7",
+          "#bd3338",
+        ],
+        tooltip: {
+          trigger: "item",
+          backgroundColor:
+            this.$store.state.themeName === "dark"
+              ? "rgba(0,0,0,0.4)"
+              : "rgba(255,255,255,0.4)",
+          borderColor:
+            this.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: util.vh(16),
+          },
+        },
+        grid: {
+          top: 8,
+          left: 8,
+          right: 8,
+          bottom: 8,
+          containLabel: true,
+        },
+        legend: {
+          icon: "circle",
+          orient: "vertical",
+          top: "center",
+          right: "0",
+          align: "left",
+          textStyle: {
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+          },
+          itemGap: 8,
+        },
+        radar: {
+          center: ["25%", "50%"],
+          radius: "80%",
+          startAngle: 90,
+          splitNumber: 8,
+          shape: "circle",
+          splitArea: {
+            areaStyle: {
+              color: ["transparent"],
+            },
+          },
+          axisLabel: {
+            show: false,
+            fontSize: 18,
+            color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontStyle: "normal",
+            fontWeight: "normal",
+          },
+          axisLine: {
+            show: true,
+            lineStyle: {
+              color: "#606769", //
+            },
+          },
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "#606769", //
+            },
+          },
+          indicator: [
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+            {
+              name: "",
+              max: 100,
+            },
+          ],
+        },
+        series: [
+          {
+            name: this.title,
+            type: "pie",
+            clockwise: false,
+            startAngle: 90,
+            radius: "70%",
+            center: ["25%", "50%"],
+            hoverAnimation: false,
+            roseType: "radius", //area
+            data: this.list,
+            label: {
+              show: false,
+            },
+            labelLine: {
+              normal: {
+                length: 20,
+                length2: 30,
+                lineStyle: {
+                  width: 1,
+                },
+              },
+            },
+          },
+        ],
+      };
+
+      this.chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$el.style.width = this.width;
+    this.$el.style.height = this.height;
+    this.chart = echarts.init(this.$el);
+    this.initChart();
+  },
+  updated() {
+    this.initChart();
+  },
+  watch: {
+    "$store.state.themeName"() {
+      this.initChart();
+    },
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 387 - 0
src/components/chart/radar/direction-radar-chart.vue

@@ -0,0 +1,387 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "dsah-pie",
+  componentName: "dsah-pie",
+  props: {
+    // 宽度 默认9.722vh
+    width: {
+      type: String,
+      default: "100%",
+    },
+    // 高度 默认9.722vh
+    height: {
+      type: String,
+      default: "7.4074vh",
+    },
+    // 标题
+    title: {
+      type: String,
+      default: "标题",
+    },
+    // 值
+    value: {
+      type: Number,
+      default: 90,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      indicator: [
+        {
+          name: "北",
+          max: 100,
+        },
+        {
+          name: "北北西",
+          max: 100,
+        },
+        {
+          name: "北西",
+          max: 100,
+        },
+        {
+          name: "西北西",
+          max: 100,
+        },
+        {
+          name: "西",
+          max: 100,
+        },
+        {
+          name: "西南西",
+          max: 100,
+        },
+        {
+          name: "南西",
+          max: 100,
+        },
+        {
+          name: "南南西",
+          max: 100,
+        },
+        {
+          name: "南",
+          max: 100,
+        },
+        {
+          name: "南南东",
+          max: 100,
+        },
+        {
+          name: "东南",
+          max: 100,
+        },
+        {
+          name: "东南东",
+          max: 100,
+        },
+        {
+          name: "东",
+          max: 100,
+        },
+        {
+          name: "东北东",
+          max: 100,
+        },
+        {
+          name: "北东",
+          max: 100,
+        },
+        {
+          name: "北北东",
+          max: 100,
+        },
+      ],
+    };
+  },
+  computed: {},
+  methods: {
+    initChart() {
+      let option = {
+        grid: {
+          left: 40,
+          right: 40,
+          bottom: "40%",
+          top: "40%",
+          containLabel: false,
+        },
+        radar: [
+          // 最低层 80
+          {
+            radius: "70%",
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            nameGap: "10",
+            name: {
+              textStyle: {
+                color: partten.getColor("gray") + 99,
+                fontSize: 12,
+              },
+            },
+            axisLine: {
+              lineStyle: {
+                color: partten.getColor("gray") + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: partten.getColor("gray") + 40,
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                color: "transparent",
+              },
+            },
+            indicator: this.indicator,
+          },
+          // 次外层 70 - 80
+          {
+            radius: ["60%", "70%"],
+            center: ["50%", "50%"],
+            startAngle: 90,
+            splitNumber: 2,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: partten.getColor("gray") + 40,
+                shadowBlur: 1,
+                shadowColor: "#fff",
+                shadowOffsetX: 0.5,
+                shadowOffsetY: 1,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: partten.getColor("gray") + 40,
+                shadowColor: "#fff",
+                shadowBlur: 0,
+                shadowOffsetX: 0.5,
+                shadowOffsetY: 0.5,
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                color: "transparent",
+              },
+            },
+            indicator: this.indicator,
+          },
+          // 渐变层 40 - 70
+          {
+            radius: ["30%", "60%"],
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: partten.getColor("gray") + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: partten.getColor("gray"),
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                shadowBlur: 4,
+                color: {
+                  type: "radial",
+                  x: 0.5,
+                  y: 0.5,
+                  r: 0.5,
+                  colorStops: [
+                    {
+                      offset: 0.5,
+                      color: "transparent", // 0% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: this.$store.state.themeName === "dark" ? partten.getColor("green") : partten.getColor("deepblue") + 60, // 100% 处的颜色
+                    },
+                  ],
+                  global: false, // 缺省为 false
+                },
+              },
+            },
+            indicator: this.indicator,
+          },
+          // 内层 0 - 40
+          {
+            radius: "30%",
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: partten.getColor("gray") + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: partten.getColor("gray"),
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                shadowBlur: 4,
+                color: "transparent",
+              },
+            },
+            indicator: this.indicator,
+          },
+        ],
+        series: [
+          // 进度条
+          {
+            z: 1,
+            name: "内部(环形)进度条",
+            type: "gauge",
+            radius: "70%",
+            splitNumber: 5,
+            axisLine: {
+              lineStyle: {
+                color: [
+                  [
+                    this.value / 360,
+                    new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+                      {
+                        offset: 0,
+                        color: this.$store.state.themeName === "dark" ? partten.getColor(this.color) + 10 : partten.getColor("deepblue") + 10,
+                      },
+                      {
+                        offset: 1,
+                        color: this.$store.state.themeName === "dark" ? partten.getColor(this.color) + 99 : partten.getColor("deepblue") + 99,
+                      },
+                    ]),
+                  ],
+                  [1, "transparent"],
+                ],
+                width: 40,
+              },
+            },
+            startAngle: 90,
+            endAngle: 450,
+            clockwise: true,
+            axisLabel: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+            pointer: {
+              show: false,
+            },
+          },
+          // 指针
+          {
+            name: "指针",
+            type: "gauge",
+            z: 2,
+            min: 0,
+            max: 360,
+            radius: "100%",
+            startAngle: 90,
+            endAngle: 360 + 90,
+            clockwise: false,
+            axisLine: {
+              show: false,
+            },
+            tooltip: {
+              show: false,
+            },
+            axisLabel: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+            detail: {
+              show: false,
+            },
+            title: {
+              //标题
+              show: false,
+            },
+            data: [
+              {
+                value: this.value,
+              },
+            ],
+            itemStyle: {
+              normal: {
+                color: "#fff",
+              },
+            },
+            pointer: {
+              show: true,
+              length: "70%",
+              radius: "0%",
+              width: util.vh(3), //指针粗细
+              offsetCenter: ["0%", "0%"],
+            },
+            animationDuration: 1000,
+          },
+        ],
+      };
+
+      this.chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.chart = echarts.init(this.$el);
+      this.initChart();
+    });
+  },
+  updated() {
+    this.initChart();
+  },
+  watch: {
+    "$store.state.themeName"() {
+      this.initChart();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: block;
+  margin: auto;
+}
+</style>

+ 445 - 0
src/components/chart/radar/normal-radar-chart.vue

@@ -0,0 +1,445 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "radar-chart",
+  componentName: "radar-chart",
+  props: {
+    // 宽度 默认9.722vh
+    width: {
+      type: String,
+      default: "100%",
+    },
+    // 高度 默认9.722vh
+    height: {
+      type: String,
+      default: "7.4074vh",
+    },
+    // 标题
+    title: {
+      type: Array,
+      default: () => ["-", "-"],
+    },
+    // 值
+    value: {
+      type: Array,
+      default: () => {
+        return [
+          {
+            indicator: ["N0", "N1", "N2", "N3", "N4", "N5"],
+            data: [
+              {
+                value: [44200, 14200, 20000, 35000, 50000, 38000],
+                name: "风机一号",
+              },
+            ],
+          },
+        ];
+      },
+    },
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      lineStyles: [],
+	  green:{
+          areaStyle: {
+            color: "rgba(165,228,175, 0.9)",
+          },
+          lineStyle: {
+            color: "rgba(255,255,255, 0.85)",
+          },
+          itemStyle: {
+            color: "rgba(165,228,175, 0.5)",
+            borderColor: "rgba(255,255,255, 0.5)",
+            borderWidth: 0.5,
+          },
+        },
+	blue:{
+          areaStyle: {
+            color: 'rgba(75,85,174, 0.9)',
+          },
+          lineStyle: {
+            color: "rgba(255,255,255, 0.85)",
+          },
+          itemStyle: {
+            color:'rgba(75,85,174, 0.9)',
+            borderColor: "rgba(255,255,255, 0.5)",
+            borderWidth: 0.5,
+          },
+        }
+    };
+  },
+  methods: {
+    renderValue() {
+      let result = [];
+      this.value.forEach((value, index) => {
+        result.push({
+          name: this.title[index],
+          type: "radar",
+          data: value.data,
+        });
+      });
+      return result;
+    },
+    initChart() {
+		let themeName = '';
+		let theme = this.$store.state.themeName;
+		if(theme == 'dark' || theme == 'light'){
+			themeName = theme;
+		}else{
+			themeName = theme.split(' ')[1];
+		}
+      let chart = echarts.init(this.$el);
+      let maxValue = -1;
+		
+		if(themeName === "dark"){
+			this.lineStyles = [this.green,this.blue];
+		}else{
+			this.lineStyles = [this.blue,this.green];
+		}
+		
+      if (this.value.length > 0)
+        this.value[0].data.forEach((item, index) => {
+          item.value.forEach((value) => {
+            if (value > maxValue) {
+              maxValue = value;
+            }
+          });
+          item.areaStyle =
+            this.lineStyles[index % this.lineStyles.length].areaStyle;
+          item.lineStyle =
+            this.lineStyles[index % this.lineStyles.length].lineStyle;
+          item.itemStyle =
+            this.lineStyles[index % this.lineStyles.length].itemStyle;
+        });
+      maxValue *= 1.5;
+
+      let indicator = [];
+      if (this.value.length > 0)
+        this.value[0].indicator.forEach((item) => {
+          indicator.push({ name: item, max: maxValue });
+        });
+
+      let option = {
+        grid: {
+          left: 150,
+          right: 150,
+          bottom: 150,
+          top: 150,
+        },
+        tooltip: {
+          trigger: "item",
+          backgroundColor:
+            themeName === "dark"
+              ? "rgba(0,0,0,0.4)"
+              : "rgba(255,255,255,0.5)",
+          borderColor:
+            themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color: themeName === "dark" ? "#fff" : "#000",
+            fontSize: util.vh(16),
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          bottom: 16,
+          inactiveColor:
+            themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            fontSize: 12,
+            color:
+              themeName === "dark"
+                ? partten.getColor("grayl")
+                : "#000",
+          },
+        },
+        radar: [
+          // 最低层 80
+          {
+            radius: "70%",
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            nameGap: "16",
+            name: {
+              textStyle: {
+                color: themeName === "dark"
+              ? partten.getColor("gray") + 99
+              : "#000",
+                fontSize: 12,
+              },
+            },
+            axisLine: {
+              lineStyle: {
+                color: themeName === "dark"
+              ? partten.getColor("gray") + 40
+              : "#000" + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: themeName === "dark"
+              ? partten.getColor("gray") + 40
+              : "#000" + 40,
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                color: "transparent",
+              },
+            },
+            indicator: indicator,
+          },
+          // 次外层 70 - 80
+          {
+            radius: ["60%", "70%"],
+            center: ["50%", "50%"],
+            startAngle: 90,
+            splitNumber: 2,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: themeName === "dark"
+              ? partten.getColor("gray") + 40
+              : "#000" + 40,
+                shadowBlur: 1,
+                shadowColor: "#fff",
+                shadowOffsetX: 0.5,
+                shadowOffsetY: 1,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: themeName === "dark"
+              ? partten.getColor("gray") + 40
+              : "#000" + 40,
+                shadowColor: "#fff",
+                shadowBlur: 0,
+                shadowOffsetX: 0.5,
+                shadowOffsetY: 0.5,
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                color: "transparent",
+              },
+            },
+            indicator: indicator,
+          },
+          // 渐变层 40 - 70
+          {
+            radius: ["35%", "60%"],
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: themeName === "dark"
+              ? partten.getColor("gray") + 40
+              : "#000" + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                shadowBlur: 4,
+                color: {
+                  type: "radial",
+                  x: 0.5,
+                  y: 0.5,
+                  r: 0.5,
+                  colorStops: [
+                    {
+                      offset: 0.5,
+                      color: "transparent", // 0% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: themeName === "dark"
+              ? partten.getColor("green") + 60
+              : partten.getColor("deepblue") + 60, // 100% 处的颜色
+                    },
+                  ],
+                  global: false, // 缺省为 false
+                },
+              },
+            },
+            indicator: indicator,
+          },
+          // 渐变层 0 - 40
+          {
+            radius: ["0%", "35%"],
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: themeName === "dark"
+              ? partten.getColor("gray") + 40
+              : "#000" + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                shadowBlur: 4,
+                color: {
+                  type: "radial",
+                  x: 0.5,
+                  y: 0.5,
+                  r: 0.5,
+                  colorStops: [
+                    {
+                      offset: 0.5,
+                      color: "transparent", // 0% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: themeName === "dark"
+              ? partten.getColor("green") + 60
+              : partten.getColor("deepblue") + 60, // 100% 处的颜色
+                    },
+                  ],
+                  global: false, // 缺省为 false
+                },
+              },
+            },
+            indicator: indicator,
+          },
+          // 内层 0 - 50
+          {
+            radius: "35%",
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: themeName === "dark"
+              ? partten.getColor("gray") + 40
+              : "#000" + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                shadowBlur: 4,
+                color: "transparent",
+              },
+            },
+            indicator: indicator,
+          },
+          // 内层 0 - 45
+          {
+            radius: "35%",
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: themeName === "dark"
+              ? partten.getColor("gray") + 40
+              : "#000" + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                shadowBlur: 4,
+                color: "transparent",
+              },
+            },
+            indicator: indicator,
+          },
+        ],
+        series: this.renderValue(),
+      };
+
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  watch: {
+    "$store.state.themeName"() {
+      this.initChart();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: block;
+  margin: auto;
+}
+</style>

+ 409 - 0
src/components/chart/radar/radar-chart.vue

@@ -0,0 +1,409 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "radar-chart",
+  componentName: "radar-chart",
+  props: {
+    // 宽度 默认9.722vh
+    width: {
+      type: String,
+      default: "100%",
+    },
+    // 高度 默认9.722vh
+    height: {
+      type: String,
+      default: "7.4074vh",
+    },
+    // 标题
+    title: {
+      type: String,
+      default: "",
+    },
+    // 值
+    value: {
+      type: Object,
+      default: () => {
+        return {
+          indicator: [
+            "北(0.0/0.0)",
+            "北北西(0.0/0.0)",
+            "北西(0.0/0.0)",
+            "西北西(0.0/0.0)",
+            "西(0.0/0.0)",
+            "西南西(0.0/0.0)",
+            "南西(0.0/0.0)",
+            "南南西(0.0/0.0)",
+            "南(0.0/0.0)",
+            "南南东(0.0/0.0)",
+            "东南(0.0/0.0)",
+            "东南东(0.0/0.0)",
+            "东(0.0/0.0)",
+            "东北东(0.0/0.0)",
+            "北东(0.0/0.0)",
+            "北北东(0.0/0.0)",
+          ],
+          data: [
+            {
+              value: [44200, 14200, 20000, 35000, 50000, 38000, 44200, 14200, 20000, 35000, 50000, 38000, 44200, 14200, 20000, 35000, 50000, 38000, 20000, 35000, 50000, 38000],
+              name: "NAME",
+            },
+          ],
+        };
+      },
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      lineStyles: [],
+	  green:{
+	        areaStyle: {
+	          color: "rgba(165,228,175, 0.9)",
+	        },
+	        lineStyle: {
+	          color: "rgba(255,255,255, 0.85)",
+	        },
+	        itemStyle: {
+	          color: "rgba(165,228,175, 0.5)",
+	          borderColor: "rgba(255,255,255, 0.5)",
+	          borderWidth: 0.5,
+	        },
+	      },
+	  blue:{
+	        areaStyle: {
+	          color: 'none',
+	        },
+	        lineStyle: {
+	          color: "rgba(75,85,174, 0.9)",
+	        },
+	        itemStyle: {
+	          color:'rgba(75,85,174, 0.9)',
+	          borderColor: "rgba(75,85,174, 0.9)",
+	          borderWidth: 0.5,
+	        },
+	      }
+    };
+  },
+  computed: {},
+  methods: {
+    initChart() {
+		let themeName = '';
+		let theme = this.$store.state.themeName;
+		if(theme == 'dark' || theme == 'light'){
+			themeName = theme;
+		}else{
+			themeName = theme.split(' ')[1];
+		}
+      let chart = echarts.init(this.$el);
+
+      let maxValue = -1;
+	  if(themeName === "dark"){
+	  	this.lineStyles = [this.green,this.blue];
+	  }else{
+	  	this.lineStyles = [this.blue,this.green];
+	  }
+      if (this.value.data)
+        this.value.data.forEach((item, index) => {
+          item.value.forEach((value) => {
+            if (value > maxValue) {
+              maxValue = value;
+            }
+          });
+          item.areaStyle = this.lineStyles[index % this.lineStyles.length].areaStyle;
+          item.lineStyle = this.lineStyles[index % this.lineStyles.length].lineStyle;
+          item.itemStyle = this.lineStyles[index % this.lineStyles.length].itemStyle;
+        });
+      maxValue *= 1.5;
+
+      let indicator = [];
+      if (this.value.indicator)
+        this.value.indicator.forEach((item) => {
+          indicator.push({ name: item, max: maxValue });
+        });
+
+      let baseSize = 65;
+
+      let option = {
+        grid: {
+          left: 0,
+          right: 0,
+          bottom: 0,
+          top: 0,
+        },
+        tooltip: {
+          trigger: "item",
+          backgroundColor: this.$store.state.themeName === "dark" ? "rgba(0,0,0,0.4)" : "rgba(255,255,255,0.5)",
+			borderColor: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+			textStyle: {
+			  color: this.$store.state.themeName === "dark" ? "#fff" : "#000",
+            fontSize: util.vh(16),
+          },
+          position: function(pos, params, dom, rect, size) {
+            // 鼠标在左侧时 tooltip 显示到右侧,鼠标在右侧时 tooltip 显示到左侧。
+            var obj = { top: 60 };
+            obj[["left", "right"][+(pos[0] < size.viewSize[0] / 2)]] = 5;
+            return obj;
+          },
+          extraCssText: "position: absolute; margin-top:-20%;",
+          // extraCssText: "max-width:140px;position:sticky;top:0;left:0"
+        },
+        radar: [
+          // 最低层 90
+          {
+            radius: baseSize + "%",
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            nameGap: "4",
+            name: {
+              textStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : "#000",
+                fontSize: 12,
+                padding: [0, 16],
+              },
+            },
+            axisLine: {
+              lineStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") + 40 : partten.getColor("grayl")  + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") + 40 : partten.getColor("grayl")  + 40,
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                color: "transparent",
+              },
+            },
+            indicator: indicator,
+          },
+          // 次外层 80 - 90
+          {
+            radius: ["55%", "65%"],
+            center: ["50%", "50%"],
+            startAngle: 90,
+            splitNumber: 2,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") + 40 : partten.getColor("grayl")  + 40,
+                shadowBlur: 1,
+                shadowColor: "#fff",
+                shadowOffsetX: 0.5,
+                shadowOffsetY: 1,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") + 40 : partten.getColor("grayl")  + 40,
+                shadowColor: "#fff",
+                shadowBlur: 0,
+                shadowOffsetX: 0.5,
+                shadowOffsetY: 0.5,
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                color: "transparent",
+              },
+            },
+            indicator: indicator,
+          },
+          // 渐变层 40 - 80
+          {
+            radius: ["30%", "55%"],
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") + 40 : partten.getColor("grayl")  + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : partten.getColor("deepblue")	,
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                shadowBlur: 4,
+                color: {
+                  type: "radial",
+                  x: 0.5,
+                  y: 0.5,
+                  r: 0.5,
+                  colorStops: [
+                    {
+                      offset: 0.5,
+                      color: "transparent", // 0% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: this.$store.state.themeName === "dark" ? partten.getColor("green") + 60 : partten.getColor("deepblue") + 20, // 100% 处的颜色
+                    },
+                  ],
+                  global: false, // 缺省为 false
+                },
+              },
+            },
+            indicator: indicator,
+          },
+          // 渐变层 0 - 40
+          {
+            radius: ["0%", "30%"],
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") + 40 : partten.getColor("grayl")  + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: this.$store.state.themeName === "dark" ? partten.getColor("gray") : partten.getColor("grayl"),
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                shadowBlur: 4,
+                color: {
+                  type: "radial",
+                  x: 0.5,
+                  y: 0.5,
+                  r: 0.5,
+                  colorStops: [
+                    {
+                      offset: 0.5,
+                      color: "transparent", // 0% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: this.$store.state.themeName === "dark" ? partten.getColor("green") + 60 : partten.getColor("deepblue") + 20, // 100% 处的颜色
+                    },
+                  ],
+                  global: false, // 缺省为 false
+                },
+              },
+            },
+            indicator: indicator,
+          },
+          // 内层 0 - 50
+          {
+            radius: "50%",
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: partten.getColor("gray") + 40,
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: partten.getColor("gray"),
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                shadowBlur: 4,
+                color: "transparent",
+              },
+            },
+            indicator: indicator,
+          },
+          // 内层 0 - 45
+          {
+            radius: "35%",
+            center: ["50%", "50%"],
+            splitNumber: 1,
+            name: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: partten.getColor("grayl"),
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 1,
+                color: partten.getColor("grayl"),
+              },
+            },
+            splitArea: {
+              areaStyle: {
+                shadowBlur: 4,
+                color: "transparent",
+              },
+            },
+            indicator: indicator,
+          },
+        ],
+        series: [
+          {
+            name: this.title,
+            type: "radar",
+            data: this.value.data,
+          },
+        ],
+      };
+
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  watch: {
+      "$store.state.themeName"() {
+        this.initChart();
+      },
+    },
+};
+</script>
+
+<style lang="less" scoped>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: block;
+  margin: auto;
+  position: relative;
+}
+</style>

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

@@ -0,0 +1,344 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  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 [];
+      },
+    },
+    // 图表核心数据
+    seriesData: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    // 是否显示图表图例
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 是否默认采用笔刷模式
+    brushSelected: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: [
+        "#05bb4c",
+        "#4b55ae",
+        "#fa8c16",
+        "#f8de5b",
+        "#1a93cf",
+        "#c531c7",
+        "#bd3338",
+      ],
+    };
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      const that = this;
+      let myChart = echarts.init(document.getElementById(this.id));
+
+      //指定图表的配置项和数据
+      const option = {
+        //标题
+        title: {
+          text: that.chartTitle,
+          textStyle: {
+            fontSize: util.vh(16),
+            color: that.$store.state.themeName === "dark" ? "#fff" : "#000",
+          },
+        },
+        backgroundColor:
+          that.$store.state.themeName === "dark"
+            ? "rgba(0,0,0,0.4)"
+            : "rgba(255,255,255,0.5)",
+        //工具箱
+        toolbox: {
+          show: true,
+          x: "right",
+          position: [10, 10],
+          backgroundColor:
+            that.$store.state.themeName === "dark"
+              ? "rgba(0,0,0,0.4)"
+              : "rgba(255,255,255,0.5)",
+          borderColor:
+            that.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            fontSize: util.vh(16),
+            color: that.$store.state.themeName === "dark" ? "#fff" : "#000",
+          },
+          iconStyle: {
+            borderColor:
+              that.$store.state.themeName === "dark" ? "#fff" : "#000",
+          },
+          emphasis: {
+            iconStyle: {
+              borderColor:
+                that.$store.state.themeName === "dark" ? "#fff" : "#000",
+            },
+          },
+          // feature: {
+          //   dataZoom: {
+          //     yAxisIndex: "none",
+          //   },
+          //   dataView: { readOnly: false },
+          //   magicType: { type: ["line", "bar"] },
+          //   restore: {},
+          //   saveAsImage: {},
+          // },
+        },
+        tooltip: {
+          trigger: "item",
+          axisPointer: {
+            type: "cross",
+          },
+          backgroundColor:
+            that.$store.state.themeName === "dark"
+              ? "rgba(0,0,0,0.4)"
+              : "rgba(255,255,255,0.5)",
+          borderColor:
+            that.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            fontSize: util.vh(16),
+            color: that.$store.state.themeName === "dark" ? "#fff" : "#000",
+          },
+          formatter(params) {
+            return params.name
+              ? `${params.seriesName}<br />风速:${params.name}米/s<br />功率:${params.value}kW`
+              : `${params.seriesName}<br />风速:${params.data[0]}米/s<br />功率:${params.data[1]}kW`;
+          },
+        },
+        brush: {
+          // xAxisIndex: "all",
+          // yAxisIndex: "all",
+          transformable: true,
+          throttleType: "debounce",
+          throttleDelay: 600,
+          removeOnClick: false,
+          brushType: "polygon",
+          brushMode: "multiple",
+          brushStyle: {
+            borderWidth: 1,
+            color: "rgba(255,36,36,0.2)",
+            borderColor: "#ff2424",
+          },
+          // outOfBrush: {
+          //   colorAlpha: 0.5,
+          // },
+        },
+        dataZoom: [
+          {
+            type: "inside", //图表下方的伸缩条
+            show: true, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+          {
+            type: "slider", //图表下方的伸缩条
+            show: true, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+        ],
+        textStyle: {
+          fontSize: util.vh(16),
+          color: that.$store.state.themeName === "dark" ? "#fff" : "#000",
+        },
+        //图例-每一条数据的名字
+        legend: {
+          show: that.showLegend,
+          data: ["风速功率", "实际功率", "最优功率"],
+          right: "120",
+          top: "5",
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor:
+            that.$store.state.themeName === "dark"
+              ? partten.getColor("gray")
+              : "#000",
+          textStyle: {
+            color:
+              that.$store.state.themeName === "dark"
+                ? partten.getColor("grayl")
+                : "#000",
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: 32,
+          left: 40,
+          right: 40,
+          bottom: 24,
+        },
+        //x轴
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            data: that.xAxisData || [
+              "0",
+              "1",
+              "2",
+              "3",
+              "4",
+              "5",
+              "6",
+              "7",
+              "8",
+              "9",
+              "10",
+              "11",
+              "12",
+              "13",
+              "14",
+              "15",
+              "16",
+              "17",
+              "18",
+              "19",
+              "20",
+              "21",
+              "22",
+              "23",
+              "24",
+              "25",
+            ],
+            min: 0,
+            axisLabel: {
+              formatter: "{value}",
+              fontSize: util.vh(14),
+            },
+            textStyle: {
+              color:
+                this.$store.state.themeName === "dark"
+                  ? partten.getColor("gray")
+                  : "#000",
+            },
+          },
+          {
+            // name: this.xTitle,
+            show: false,
+            type: "value",
+            boundaryGap: false,
+            // min: that?.xAxisData[0],
+            min: 0,
+            max: that?.xAxisData[that?.xAxisData?.length - 1],
+            scale: true,
+            axisLabel: {
+              formatter: "{value}",
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        //y轴没有显式设置,根据值自动生成y轴
+        yAxis: {
+          splitLine: { show: false },
+        },
+        //数据-data是最终要显示的数据
+        series: that.seriesData,
+      };
+
+      that.resize = function () {
+        myChart.resize();
+      };
+
+      window.addEventListener("resize", that.resize);
+
+      myChart.setOption(option);
+
+      if (that.brushSelected) {
+        myChart.off("brushSelected");
+        myChart.on("brushSelected", (params) => {
+          that.$emit("getSelected", params.batch || []);
+        });
+        myChart.dispatchAction({
+          type: "takeGlobalCursor",
+          // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+          key: "brush",
+          brushOption: {
+            // 参见 brush 组件的 brushType。如果设置为 false 则关闭“可刷选状态”。
+            brushType: "polygon",
+            // 参见 brush 组件的 brushMode。如果不设置,则取 brush 组件的 brushMode 设置。
+            brushMode: "multiple",
+          },
+        });
+      }
+    },
+  },
+  created() {
+    this.id = "chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    let myChart = echarts.init(document.getElementById(this.id));
+    myChart.dispose();
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="scss">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 462 - 0
src/components/chart/scatter/normal-scatter-chart.vue

@@ -0,0 +1,462 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "350px",
+    },
+    // 传入数据
+    data: {
+      type: Array,
+      default: () => [
+       
+        {
+          title: "女",
+          value: [
+            [174.0, 65.6],
+            [175.3, 71.8],
+            [193.5, 80.7],
+            [186.5, 72.6],
+            [187.2, 78.8],
+            [181.5, 74.8],
+            [184.0, 86.4],
+            [184.5, 78.4],
+            [175.0, 62.0],
+            [184.0, 81.6],
+            [180.0, 76.6],
+            [177.8, 83.6],
+            [192.0, 90.0],
+            [176.0, 74.6],
+            [174.0, 71.0],
+            [184.0, 79.6],
+            [192.7, 93.8],
+            [171.5, 70.0],
+            [173.0, 72.4],
+            [176.0, 85.9],
+            [176.0, 78.8],
+            [180.5, 77.8],
+            [172.7, 66.2],
+            [176.0, 86.4],
+            [173.5, 81.8],
+            [178.0, 89.6],
+            [180.3, 82.8],
+            [180.3, 76.4],
+            [164.5, 63.2],
+            [173.0, 60.9],
+            [183.5, 74.8],
+            [175.5, 70.0],
+            [188.0, 72.4],
+            [189.2, 84.1],
+            [172.8, 69.1],
+            [170.0, 59.5],
+            [182.0, 67.2],
+            [170.0, 61.3],
+            [177.8, 68.6],
+            [184.2, 80.1],
+            [186.7, 87.8],
+            [171.4, 84.7],
+            [172.7, 73.4],
+            [175.3, 72.1],
+            [180.3, 82.6],
+            [182.9, 88.7],
+            [188.0, 84.1],
+            [177.2, 94.1],
+            [172.1, 74.9],
+            [167.0, 59.1],
+            [169.5, 75.6],
+            [174.0, 86.2],
+            [172.7, 75.3],
+            [182.2, 87.1],
+            [164.1, 55.2],
+            [163.0, 57.0],
+            [171.5, 61.4],
+            [184.2, 76.8],
+            [174.0, 86.8],
+            [174.0, 72.2],
+            [177.0, 71.6],
+            [186.0, 84.8],
+            [167.0, 68.2],
+            [171.8, 66.1],
+            [182.0, 72.0],
+            [167.0, 64.6],
+            [177.8, 74.8],
+            [164.5, 70.0],
+            [192.0, 101.6],
+            [175.5, 63.2],
+            [171.2, 79.1],
+            [181.6, 78.9],
+            [167.4, 67.7],
+            [181.1, 66.0],
+            [177.0, 68.2],
+            [174.5, 63.9],
+            [177.5, 72.0],
+            [170.5, 56.8],
+            [182.4, 74.5],
+            [197.1, 90.9],
+            [180.1, 93.0],
+            [175.5, 80.9],
+            [180.6, 72.7],
+            [184.4, 68.0],
+            [175.5, 70.9],
+            [180.6, 72.5],
+            [177.0, 72.5],
+            [177.1, 83.4],
+            [181.6, 75.5],
+            [176.5, 73.0],
+            [175.0, 70.2],
+            [174.0, 73.4],
+            [165.1, 70.5],
+            [177.0, 68.9],
+            [192.0, 102.3],
+            [176.5, 68.4],
+            [169.4, 65.9],
+            [182.1, 75.7],
+            [179.8, 84.5],
+            [175.3, 87.7],
+            [184.9, 86.4],
+            [177.3, 73.2],
+            [167.4, 53.9],
+            [178.1, 72.0],
+            [168.9, 55.5],
+            [157.2, 58.4],
+            [180.3, 83.2],
+            [170.2, 72.7],
+            [177.8, 64.1],
+            [172.7, 72.3],
+            [165.1, 65.0],
+            [186.7, 86.4],
+            [165.1, 65.0],
+            [174.0, 88.6],
+            [175.3, 84.1],
+            [185.4, 66.8],
+            [177.8, 75.5],
+            [180.3, 93.2],
+            [180.3, 82.7],
+            [177.8, 58.0],
+            [177.8, 79.5],
+            [177.8, 78.6],
+            [177.8, 71.8],
+            [177.8, 116.4],
+            [163.8, 72.2],
+            [188.0, 83.6],
+            [198.1, 85.5],
+            [175.3, 90.9],
+            [166.4, 85.9],
+            [190.5, 89.1],
+            [166.4, 75.0],
+            [177.8, 77.7],
+            [179.7, 86.4],
+            [172.7, 90.9],
+            [190.5, 73.6],
+            [185.4, 76.4],
+            [168.9, 69.1],
+            [167.6, 84.5],
+            [175.3, 64.5],
+            [170.2, 69.1],
+            [190.5, 108.6],
+            [177.8, 86.4],
+            [190.5, 80.9],
+            [177.8, 87.7],
+            [184.2, 94.5],
+            [176.5, 80.2],
+            [177.8, 72.0],
+            [180.3, 71.4],
+            [171.4, 72.7],
+            [172.7, 84.1],
+            [172.7, 76.8],
+            [177.8, 63.6],
+            [177.8, 80.9],
+            [182.9, 80.9],
+            [170.2, 85.5],
+            [167.6, 68.6],
+            [175.3, 67.7],
+            [165.1, 66.4],
+            [185.4, 102.3],
+            [181.6, 70.5],
+            [172.7, 95.9],
+            [190.5, 84.1],
+            [179.1, 87.3],
+            [175.3, 71.8],
+            [170.2, 65.9],
+            [193.0, 95.9],
+            [171.4, 91.4],
+            [177.8, 81.8],
+            [177.8, 96.8],
+            [167.6, 69.1],
+            [167.6, 82.7],
+            [180.3, 75.5],
+            [182.9, 79.5],
+            [176.5, 73.6],
+            [186.7, 91.8],
+            [188.0, 84.1],
+            [188.0, 85.9],
+            [177.8, 81.8],
+            [174.0, 82.5],
+            [177.8, 80.5],
+            [171.4, 70.0],
+            [185.4, 81.8],
+            [185.4, 84.1],
+            [188.0, 90.5],
+            [188.0, 91.4],
+            [182.9, 89.1],
+            [176.5, 85.0],
+            [175.3, 69.1],
+            [175.3, 73.6],
+            [188.0, 80.5],
+            [188.0, 82.7],
+            [175.3, 86.4],
+            [170.5, 67.7],
+            [179.1, 92.7],
+            [177.8, 93.6],
+            [175.3, 70.9],
+            [182.9, 75.0],
+            [170.8, 93.2],
+            [188.0, 93.2],
+            [180.3, 77.7],
+            [177.8, 61.4],
+            [185.4, 94.1],
+            [168.9, 75.0],
+            [185.4, 83.6],
+            [180.3, 85.5],
+            [174.0, 73.9],
+            [167.6, 66.8],
+            [182.9, 87.3],
+            [160.0, 72.3],
+            [180.3, 88.6],
+            [167.6, 75.5],
+            [186.7, 101.4],
+            [175.3, 91.1],
+            [175.3, 67.3],
+            [175.9, 77.7],
+            [175.3, 81.8],
+            [179.1, 75.5],
+            [181.6, 84.5],
+            [177.8, 76.6],
+            [182.9, 85.0],
+            [177.8, 102.5],
+            [184.2, 77.3],
+            [179.1, 71.8],
+            [176.5, 87.9],
+            [188.0, 94.3],
+            [174.0, 70.9],
+            [167.6, 64.5],
+            [170.2, 77.3],
+            [167.6, 72.3],
+            [188.0, 87.3],
+            [174.0, 80.0],
+            [176.5, 82.3],
+            [180.3, 73.6],
+            [167.6, 74.1],
+            [188.0, 85.9],
+            [180.3, 73.2],
+            [167.6, 76.3],
+            [183.0, 65.9],
+            [183.0, 90.9],
+            [179.1, 89.1],
+            [170.2, 62.3],
+            [177.8, 82.7],
+            [179.1, 79.1],
+            [190.5, 98.2],
+            [177.8, 84.1],
+            [180.3, 83.2],
+            [180.3, 83.2],
+          ],
+        },
+      ],
+    },
+    xTitle: {
+      type: String,
+      default: "x轴标题",
+    },
+    yTitle: {
+      type: String,
+      default: "Y轴标题",
+    },
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data () {
+    return {
+      id: "",
+      chart: null,
+      color: ["#05bb4c", "#f8de5b", "#4b55ae", "#fa8c16"],
+    };
+  },
+  computed: {
+    series () {
+      let result = [];
+      this.data.forEach((element, index) => {
+        result.push({
+          name: element.title,
+          type: "scatter",
+          emphasis: {
+            focus: "series",
+          },
+          data: element.value,
+          markLine: {
+            data: [
+              {
+                type: "max",
+                name: "最大值",
+                label: {
+                  color: partten.getColor("gray"),
+                },
+              },
+              {
+                type: "min",
+                name: "最小值",
+                label: {
+                  color: partten.getColor("gray"),
+                },
+              },
+            ],
+          },
+        });
+      });
+      return result;
+    },
+    legend() {
+      if (this.data && this.data.length > 0)
+        return this.data.map((t) => {
+          return t.title;
+        });
+
+      return [];
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      let that = this;
+      const chart = echarts.init(this.$el);
+
+      let option = {
+        color: this.color,
+        grid: {
+          top: 40,
+          left: 40,
+          right: 40,
+          bottom: 24,
+          containLabel: true,
+        },
+        tooltip: {
+          trigger: "item",
+          showDelay: 0,
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            fontSize: util.vh(16),
+            color: "#fff",
+          },
+          formatter: function(params) {
+            if (params.componentType == "markLine") {
+              return params.name + "<br />" + params.value;
+            }
+
+            var msg = params.seriesName + "<br />";
+            msg += params.marker + that.xTitle + ":" + params.value[0] + "<br />";
+            msg += params.marker + that.yTitle + ":" + params.value[1] + "<br />";
+            return msg;
+          },
+          axisPointer: {
+            show: true,
+            type: "cross",
+            lineStyle: {
+              type: "dashed",
+              width: 1,
+            },
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          right: "40",
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: partten.getColor("gray"),
+          textStyle: {
+            color: partten.getColor("grayl"),
+            fontSize: 12,
+          },
+        },
+        xAxis: [
+          {
+            name: this.xTitle,
+            type: "value",
+            scale: true,
+            axisLabel: {
+              formatter: "{value}",
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            name: this.yTitle,
+            scale: true,
+            axisLabel: {
+              formatter: "{value}",
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        series: this.series,
+      };
+
+      chart.clear();
+      chart.setOption(option);
+
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+  },
+  created () {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted () {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated () {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted () {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="scss">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 44 - 0
src/components/excel.vue

@@ -0,0 +1,44 @@
+<script setup lang="ts" name="excel">
+import { ref, watch } from 'vue';
+const props = withDefaults(defineProps<{
+	data: { name: string, id: string }[],
+	height?: string | number,
+	showCheckbox?: boolean,
+	checkIds?: string[]
+}>(), {
+	data: () => [],
+	height: '400px',
+	showCheckbox: false,
+	checkIds: () => []
+})
+const excelCheckIds = ref<string[]>([])
+const currentId = ref('')
+const emits = defineEmits(['excelChange', 'checkChange'])
+const funExcelChange = (obj: any) => {
+	currentId.value = obj.id
+	emits('excelChange', obj)
+}
+watch(() => props.checkIds, (newVal, oldVal) => {  //监听外部checkIds 赋值当前全选
+	excelCheckIds.value = newVal
+})
+const funCheckChange = (checkArr) => {
+	emits('checkChange', { checkArr, data: props.data })  //抛出当前选择checkIds,  和当前的childs数据项
+}
+</script>
+<template>
+	<div class="overflow-auto shadow rounded-[6px] shadow-blue-500 pl-[6px] pt-[6px] pb-[6px]"
+		:style="{ height: typeof props.height === 'string' ? props.height : props.height + 'px' }">
+		<el-empty v-if="!props.data.length" description="暂无数据" />
+		<el-checkbox-group size="small" v-model="excelCheckIds" v-if="props.showCheckbox" @change="funCheckChange">
+			<el-checkbox :class="{'!bg-[rgb(236,245,255)]': currentId === item.id}" size="small" class="hover:bg-[rgb(245,247,250)] !mr-0 py-[3px]" :label="item.id" v-for="item in props.data" :key="item.name">
+				<span class="whitespace-nowrap cursor-pointer font-bold text-[12px] align-middle inline-flex items-center"
+					@click.stop="funExcelChange(item)"><el-icon class="mr-[4px] !text-[rgb(71,179,71)]"><Document /></el-icon>{{ item.name }}</span>
+			</el-checkbox>
+		</el-checkbox-group>
+		<div v-else>
+			<div
+				class="hover:bg-[rgb(245,247,250)] font-bold whitespace-nowrap text-[#606266] px-[8px] py-[3px] w-full cursor-pointer leading-[10px] inline-flex items-center h-[24px] text-[12px]"
+				v-for="item in props.data" :key="item.name" :class="{'!bg-[rgb(236,245,255)]': currentId === item.id}" @click="funExcelChange(item)"><el-icon class="mr-[4px] !text-[rgb(71,179,71)]"><Document /></el-icon>{{ item.name }}</div>
+		</div>
+	</div>
+</template>

+ 239 - 0
src/components/tree.vue

@@ -0,0 +1,239 @@
+<template>
+	<div class="shadow rounded-[6px] shadow-blue-500" :style="{
+		height:
+			typeof props.height === 'string' ? props.height : props.height + 'px', 
+		overflowY: 'hidden'
+	}">
+		<el-input class="pb-[10px]" v-model="filterText" placeholder="输入关键字过滤" @input="funfilterChange" />
+		<el-tree ref="treeRef" :style="{height: `calc(${props.height} - 46px)`, overflow: 'auto'}" icon="" :data="props.data" :show-checkbox="props.showCheckbox" default-expand-all node-key="id"
+			highlight-current :props="defaultProps" :current-node-key="''" @check="funCheckChange"
+			:expand-on-click-node="false" @node-click="funCurrentChange" :filter-node-method="funTreeFilter">
+			<template #default="{ node, data }">
+				<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)]" size="14" title="刷新" @click.stop="emits('refresh')">
+						<RefreshRight />
+					</el-icon>
+				</p>
+				<el-dropdown ref="dropdown1" v-else size="small" trigger="contextmenu" @command="funCommand"
+					style="margin-right: 30px">
+					<span class="el-dropdown-link text-[12px] flex items-center">
+						<el-icon class="mr-[4px] !text-[#E6A23C]">
+							<Folder v-if="!node.expanded || (node.isLeaf && !node.isCurrent)" />
+							<FolderOpened v-else />
+						</el-icon>
+						{{ node.label }}
+					</span>
+					<template #dropdown>
+						<el-dropdown-menu>
+							<el-dropdown-item class="text-[#409EFF]" v-if="props.dropdownMenu.includes('save')" :command="{ type: 'save', data, node }">保存</el-dropdown-item>
+							<el-dropdown-item class="text-[#409EFF]" v-if="data.childs && data.childs.length && props.dropdownMenu.includes('export')" :command="{ type: 'export', data, node }">导出
+							</el-dropdown-item>
+							<el-dropdown-item class="text-[#F56C6C]" v-if="props.dropdownMenu.includes('delete')" :command="{ type: 'delete', data, node }">删除</el-dropdown-item>
+						</el-dropdown-menu>
+					</template>
+				</el-dropdown>
+			</template>
+		</el-tree>
+
+		<!--
+			   <div class="buttons">
+				   <el-button @click="getCheckedNodes">get by node</el-button>
+				   <el-button @click="getCheckedKeys">get by key</el-button>
+				   <el-button @click="setCheckedNodes">set by node</el-button>
+				   <el-button @click="setCheckedKeys">set by key</el-button>
+				   <el-button @click="resetChecked">reset</el-button>
+			   </div>
+		   -->
+	</div>
+</template>
+<script lang="ts" setup name="search">
+import { ref } from "vue";
+import type Node from "element-plus/es/components/tree/src/model/node";
+import { ElMessage, ElMessageBox } from "element-plus";
+import config from "../api/config";
+import request from "../api/axios.js";
+const emits = defineEmits(["currentChange", "checkChange", "refresh"]);
+interface Tree {
+	id: string;
+	label: string;
+	children?: Tree[];
+}
+const props = withDefaults(
+	defineProps<{
+		data: Tree[];
+		height?: number | string;
+		showCheckbox?: boolean;
+		type?: string;
+		dropdownMenu?: string[]
+	}>(),
+	{
+		data: () => [],
+		height: 400,
+		showCheckbox: false,
+		type: 'wind',
+		dropdownMenu: () => [
+			'export',
+			'delete',
+		]
+	}
+);
+
+const treeRef = ref();
+const filterText = ref("");
+/**输入框过滤 */
+const funfilterChange = () => {
+	treeRef.value!.filter(filterText.value);
+};
+const funTreeFilter = (value: string, data: Tree) => {
+	if (!value) return true;
+	return data.label.includes(value);
+};
+/**选中节点变化 */
+const funCurrentChange = (current: Tree, currentNode: Node) => {
+	emits("currentChange", { current, currentNode });
+};
+/**复选框选中变化 */
+const funCheckChange = (
+	current: Tree,
+	{ checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys }
+) => {
+	emits("checkChange", {
+		current,
+		checkedNodes,
+		checkedKeys,
+		halfCheckedNodes,
+		halfCheckedKeys,
+	});
+};
+//右键时, command菜单
+const funCommand = async ({ type, data, node }) => {
+	switch (type) {
+		case 'save': 
+			/**该保存功能目前暂用于风电场, combine页 */
+			if(props.type !== 'wind'){
+				return false
+			}
+			ElMessageBox.confirm("确认保存当前节点的拟合功率?", "保存", {
+				confirmButtonText: "确认",
+				cancelButtonText: "取消",
+				type: "warning",
+			}).then(async () => {
+				let saveArr = [];
+				const repeatArr = (arr, saveArr) => {
+					for (const unit of arr) {
+						if (unit.childs?.length) {
+							saveArr.push(...unit.childs.map((o) => o.id));
+						} else if (unit.children?.length) {
+							repeatArr(unit.children, saveArr);
+						}
+					}
+				};
+				if (data.childs?.length) {
+					saveArr = data.childs.map((o) => o.id);
+				} else if (data.children?.length) {
+					repeatArr(data.children, saveArr);
+				}
+				let res = {code: 500}
+				res = await request.get("/power/fitting/curve/save", {
+					params: { ids: saveArr.join(",") },
+				}); //删除当前节点
+				
+				if (res.code === 200) {
+					ElMessage.success(res.msg);
+				}
+			});
+			break;
+		case "export":
+			ElMessageBox.confirm("确认导出当前节点的所有数据?", "导出", {
+				confirmButtonText: "确认",
+				cancelButtonText: "取消",
+				type: "warning",
+			}).then(() => {
+				const a = document.createElement("a");
+				let childs = []
+				childs = props.type==='wind'? data.childs.map((o) => o.id): data.childs.map((o) => o.path)
+				const url = props.type==='wind'? '/data/option/download?ids=': '/export/files?filename='
+				a.href =
+					config.baseURL + url + childs.join(",");
+				a.download = "";
+				a.target='_blank'
+				a.click();
+			});
+			break;
+		case "delete":
+			ElMessageBox.confirm("确认删除当前节点的所有数据?", "删除", {
+				confirmButtonText: "确认",
+				cancelButtonText: "取消",
+				type: "warning",
+			}).then(async () => {
+				let deleteArr = [];
+				const repeatArr = (arr, deleteArr) => {
+					for (const unit of arr) {
+						if (unit.childs?.length) {
+							deleteArr.push(...unit.childs.map((o) => props.type==='wind'? o.id : o.path));
+						} else if (unit.children?.length) {
+							repeatArr(unit.children, deleteArr);
+						}
+					}
+				};
+				if (data.childs?.length) {
+					deleteArr = data.childs.map((o) => props.type==='wind'? o.id : o.path);
+				} else if (data.children?.length) {
+					repeatArr(data.children, deleteArr);
+				}
+				let res = {code: 500}
+				if(props.type==='wind'){
+					res = await request.get("/data/option/delete", {
+						params: { ids: deleteArr.join(",") },
+					}); //删除当前节点
+				}else{
+					res = await request.delete("/delete/files", {
+						data: { filename: deleteArr.join(",") },
+					}); //删除当前节点
+				}
+				if (res.code === 200) {
+					ElMessage.success(res.msg);
+					emits("refresh");
+				}
+			});
+
+			break;
+	}
+};
+
+const getCheckedNodes = () => {
+	// // console.log(treeRef.value!.getCheckedNodes(false, false));
+};
+const getCheckedKeys = () => {
+	// // console.log(treeRef.value!.getCheckedKeys(false));
+};
+const setCheckedNodes = () => {
+	treeRef.value!.setCheckedNodes(
+		[
+			{
+				id: 5,
+				label: "Level two 2-1",
+			},
+			{
+				id: 9,
+				label: "Level three 1-1-1",
+			},
+		],
+		false
+	);
+};
+const setCheckedKeys = (keyArr) => {
+	treeRef.value!.setCheckedKeys(keyArr, false);
+};
+const resetChecked = () => {
+	treeRef.value!.setCheckedKeys([], false);
+};
+
+const defaultProps = {
+	children: "children",
+	label: "label",
+};
+defineExpose({setCheckedKeys})
+</script>

+ 20 - 0
src/components/vpro-materials/basic-container/BasicContainer.vue

@@ -0,0 +1,20 @@
+<template>
+  <div class="basic-container">
+    <slot></slot>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'basic-container',
+}
+</script>
+
+<style>
+  .basic-container {
+    padding: 20px;
+    margin-bottom: 20px;
+    background-color: #fff;
+    border-radius: 6px;
+  }
+</style>

+ 3 - 0
src/components/vpro-materials/basic-container/index.js

@@ -0,0 +1,3 @@
+import BasicContainer from './BasicContainer.vue';
+
+export default BasicContainer;

+ 3 - 0
src/components/vpro-materials/vpro-form/index.js

@@ -0,0 +1,3 @@
+import vProForm from './vProForm.vue'
+
+export default vProForm

文件差異過大導致無法顯示
+ 1004 - 0
src/components/vpro-materials/vpro-form/vProForm.vue


+ 3 - 0
src/components/vpro-materials/vpro-table/index.js

@@ -0,0 +1,3 @@
+import vProTable from './vProTable.vue'
+
+export default vProTable

+ 628 - 0
src/components/vpro-materials/vpro-table/vProTable.vue

@@ -0,0 +1,628 @@
+<template>
+  <!-- <el-main> -->
+  <div>
+    <el-table
+      ref="YxTable"
+      border
+      :row-key="getRowKey"
+      :data="data"
+      :span-method="spanMethod"
+      :highlight-current-row="highlightCcurrentRow"
+      :row-class-name="rowClassName"
+      :default-expand-all="defaultExpandAll"
+      :tree-props="treeProps"
+      :filter-method="filterMethod"
+      :expand-row-keys="expandRowKeys"
+      :reserve-selection="reserveSelection"
+      @current-change="changeRow"
+      @selection-change="selectionChange"
+      :height="height"
+    >
+      <el-table-column v-if="select" type="selection"></el-table-column>
+      <template v-for="(item, index) in columns">
+        <template v-if="!item.type || item.type == 'string'">
+          <el-table-column
+            :key="index"
+            v-if="!item.hide"
+            :fixed="item.fixed"
+            :prop="item.dataIndex"
+            :label="item.title"
+            :width="item.width"
+            :sortable="item.sorter || false"
+            :align="item.align || 'center'"
+            :render-header="item.renderHeader"
+            :header-align="item.headerAlign"
+            :formatter="item.customRender ? item.customRender : null"
+          >
+          </el-table-column>
+        </template>
+        <template v-if="item.type == 'map'">
+          <el-table-column
+            :key="index"
+            v-if="!item.hide"
+            :fixed="item.fixed"
+            :prop="item.dataIndex"
+            :label="item.title"
+            :width="item.width"
+            :align="item.align || 'center'"
+            :render-header="item.renderHeader"
+            :header-align="item.headerAlign"
+          >
+            <template v-slot:default="scope">
+              <div :class="item.class">{{ formatterMap(item, scope.row) }}</div>
+            </template>
+          </el-table-column>
+        </template>
+        <template v-if="item.type == 'newMap'">
+          <el-table-column
+            :key="index"
+            v-if="!item.hide"
+            :fixed="item.fixed"
+            :prop="item.dataIndex"
+            :label="item.title"
+            :width="item.width"
+            :align="item.align || 'center'"
+            :render-header="item.renderHeader"
+            :header-align="item.headerAlign"
+          >
+            <template v-slot:default="scope">
+              <div :class="item.class">
+                {{ formatterNewMap(item, scope.row) }}
+              </div>
+            </template>
+          </el-table-column>
+        </template>
+        <!-- 时间类型 -->
+        <template v-if="item.type == 'data'">
+          <el-table-column
+            :key="index"
+            v-if="!item.hide"
+            :fixed="item.fixed"
+            :prop="item.dataIndex"
+            :label="item.title"
+            :width="item.width"
+            :align="item.align || 'center'"
+            :header-align="item.headerAlign"
+            :render-header="item.renderHeader"
+            :formatter="formatterData"
+          >
+            <template v-slot:default="scope">
+              <div :class="item.class">
+                {{ formatterData(item, scope.row) }}
+              </div>
+            </template>
+          </el-table-column>
+        </template>
+        <template v-if="item.type == 'date'">
+          <el-table-column
+            :key="index"
+            v-if="!item.hide"
+            :fixed="item.fixed"
+            :prop="item.dataIndex"
+            :label="item.title"
+            :width="item.width"
+            :align="item.align || 'center'"
+            :render-header="item.renderHeader"
+            :header-align="item.headerAlign"
+            :formatter="formatterData"
+          >
+            <template v-slot:default="scope">
+              <div :class="item.class">
+                {{ formatterData(item, scope.row) }}
+              </div>
+            </template>
+          </el-table-column>
+        </template>
+        <!-- 金额 -->
+        <template v-if="item.type == 'amount'">
+          <el-table-column
+            :key="index"
+            v-if="!item.hide"
+            :fixed="item.fixed"
+            :prop="item.dataIndex"
+            :label="item.title"
+            :width="item.width"
+            :align="item.align || 'center'"
+            :render-header="item.renderHeader"
+            :header-align="item.headerAlign"
+            :formatter="formatterData"
+          >
+            <template v-slot:default="scope">
+              <div :class="item.class">
+                ¥{{ getNumberFormat(scope.row, item) }}
+              </div>
+            </template>
+          </el-table-column>
+        </template>
+        <template v-else-if="item.type == 'image'">
+          <el-table-column
+            :key="index"
+            v-if="!item.hide"
+            :fixed="item.fixed"
+            :label="item.title"
+            :width="item.width"
+            :align="item.align || 'center'"
+            :render-header="item.renderHeader"
+            :header-align="item.headerAlign"
+          >
+            <template v-slot:default="scope">
+              <el-image
+                :class="item.class || 'c_image'"
+                fit="cover"
+                :src="scope.row[item.dataIndex]"
+                :preview-src-list="[scope.row[item.dataIndex]]"
+              >
+                <template v-slot:error class="image-slot">
+                  <i class="el-icon-picture-outline"></i>
+                </template>
+              </el-image>
+            </template>
+          </el-table-column>
+        </template>
+        <template v-else-if="item.type == 'action'">
+          <el-table-column
+            :key="index"
+            v-if="!item.hide"
+            :fixed="item.fixed"
+            :label="item.title"
+            :width="item.width"
+            :align="item.align || 'center'"
+            :render-header="item.renderHeader"
+            :header-align="item.headerAlign"
+          >
+            <template v-slot:default="data">
+              <template v-for="(action, actionIndex) in item.actions" :key="actionIndex">
+                <el-button
+                  v-show="
+                    !getAtionFormatter(action, actionIndex, data).hide &&
+                    action.copyFormatter
+                  "
+                  type="text"
+                  size="small"
+                  @click="onCopyClick(action, data)"
+                >
+                  {{ getAtionFormatter(action, actionIndex, data).title }}
+                </el-button>
+                <el-button
+                  v-show="
+                    !getAtionFormatter(action, actionIndex, data).hide &&
+                    !getAtionFormatter(action, actionIndex, data)
+                      .popconfirm
+                  "
+                  :type="
+                    getAtionFormatter(action, actionIndex, data).type
+                      ? getAtionFormatter(action, actionIndex, data).type
+                      : 'text'
+                  "
+                  size="small"
+                  @click="itemClick($event, action, data)"
+                  >{{ getAtionFormatter(action, actionIndex, data).title }}
+                </el-button>
+                <!-- <el-popconfirm
+                  class="popconfirm-btn"
+                  v-show="
+                    !getAtionFormatter(action, actionIndex, data).hide &&
+                    getAtionFormatter(action, actionIndex, data).popconfirm
+                  "
+                  :confirmButtonText="
+                    getAtionFormatter(action, actionIndex, data)
+                      .confirmButtonText
+                  "
+                  :confirmButtonType="
+                    getAtionFormatter(action, actionIndex, data)
+                      .confirmButtonType
+                  "
+                  :cancelButtonText="
+                    getAtionFormatter(action, actionIndex, data)
+                      .cancelButtonText
+                  "
+                  :cancelButtonType="
+                    getAtionFormatter(action, actionIndex, data)
+                      .cancelButtonType
+                  "
+                  :icon="getAtionFormatter(action, actionIndex, data).icon"
+                  :iconColor="
+                    getAtionFormatter(action, actionIndex, data).iconColor
+                  "
+                  :hideIcon="
+                    getAtionFormatter(action, actionIndex, data).hideIcon
+                  "
+                  :title="
+                    getAtionFormatter(action, actionIndex, data)
+                      .popconfirmTitle
+                  "
+                  @confirm="itemClick($event, data, 'confirm')"
+                  @cancel="itemClick($event, data, 'cancel')"
+                >
+                  <template v-slot:reference>
+                    <el-button
+                      :type="
+                        getAtionFormatter(action, actionIndex, data).type
+                          ? getAtionFormatter(action, actionIndex, data).type
+                          : 'text'
+                      "
+                      size="small"
+                      >{{
+                        getAtionFormatter(action, actionIndex, data).title
+                      }}</el-button
+                    >
+                  </template>
+                </el-popconfirm> -->
+              </template>
+            </template>
+          </el-table-column>
+        </template>
+        <template v-else-if="item.type == 'custom'">
+          <el-table-column
+            :key="index"
+            v-if="!item.hide"
+            :fixed="item.fixed"
+            :label="item.title"
+            :width="item.width"
+            :align="item.align || 'center'"
+            :render-header="item.renderHeader"
+            :header-align="item.headerAlign"
+          >
+            <template v-slot:default="scope">
+              <slot
+                :name="item.dataIndex"
+                :row="scope.row"
+                :index="scope.$index"
+              ></slot>
+            </template>
+          </el-table-column>
+        </template>
+      </template>
+    </el-table>
+    <template v-if="pagination && pagination.count">
+      <el-pagination
+        background
+        @size-change="sizeChange"
+        @current-change="currentChange"
+        :current-page="pagination.currentPage"
+        :page-sizes="getPageSizes(pagination.pageSizes)"
+        :page-size="getpageSize(pagination)"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="pagination.count"
+      ></el-pagination>
+    </template>
+  </div>
+  <!-- </el-main> -->
+</template>
+
+<script>
+/**
+ * @Description: 使用例子:
+ * <div>
+		<vpro-table :select="true"
+      :columns="tableColumns"
+      :selectionChange="selectionChange"
+      :pagination="page"
+      :data="tableData"></vpro-table>
+	</div>
+ * @property {boolean} select 是否显示勾选列
+ * @property {array} items 组件使用数据的配置
+ * @property {object} data 组件渲染所使用的数据
+ * @property {Function} selectionChange 勾选回调
+ * @property {array} selectedRowKeys 默认选中列
+ * @property {object} pagination 分页对象
+ *
+ */
+import moment from "moment";
+export default {
+  name: "vpro-table",
+  props: {
+    rowKey: {
+      type: String,
+      default: "",
+    },
+    // 仅对 type=selection 的列有效,类型为 Boolean,为 true 则会在数据更新之后保留之前选中的数据(需指定 row-key)
+    reserveSelection: {
+      type: Boolean,
+      default: false,
+    },
+    // 是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效
+    defaultExpandAll: {
+      type: Boolean,
+      default: false,
+    },
+    // 渲染嵌套数据的配置选项
+    treeProps: {
+      type: Object,
+      default: () => {},
+    },
+    // 数据过滤使用的方法,如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 true 就会显示。
+    filterMethod: {
+      type: Function,
+      default: () => {},
+    },
+    // 行的 className
+    rowClassName: {
+      type: Function,
+      default: () => {},
+    },
+    select: {
+      type: Boolean,
+      default: false,
+    },
+    highlightCcurrentRow: {
+      type: Boolean,
+      default: false,
+    },
+    spanMethod: {
+      type: Function,
+      default: () => {},
+    },
+    // 可以通过该属性设置 Table 目前的展开行,需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。
+    expandRowKeys: {
+      type: Array,
+      default: () => [],
+    },
+    data: {
+      type: Array,
+      default: () => [],
+    },
+    columns: {
+      type: Array,
+      default: () => [],
+    },
+    selectionChange: {
+      type: Function,
+      default: () => {},
+    },
+    changeRow: {
+      type: Function,
+      default: () => {},
+    },
+    selectedRowKeys: {
+      type: Array,
+      default: () => [],
+    },
+    pagination: {
+      type: Object,
+      default: () => {},
+    },
+    currentInfo: {
+      type: Object,
+      default: () => {},
+    },
+    height: {
+      type: [String, Number, Boolean],
+			default: false,
+    },
+  },
+  data() {
+    return {
+      currentRow: {},
+    };
+  },
+  created() {
+    this.toggleSelectedRowKeys();
+  },
+  watch: {
+    currentInfo() {
+      this.$refs.YxTable.setCurrentRow(this.currentInfo);
+      this.currentRow = this.currentInfo;
+    },
+    selectedRowKeys() {
+      this.toggleSelectedRowKeys();
+    },
+  },
+  methods: {
+    getRowKey() {
+			return this.rowKey
+		},
+    /**
+     *  金额处理方法
+     *
+     * @number 要格式化的数字
+     * @decimals 保留几位小数
+     * @dec_point 小数点符号
+     * @thousands_sep 千分位符号
+     * @roundtag 舍入参数,默认 "ceil" 向上取,"floor"向下取,"round" 四舍五入
+     *
+     *  @return 返回视图标题
+     */
+    numberFormat(number, decimals, dec_point, thousands_sep, roundtag) {
+      /*
+       * 参数说明:
+       * number:要格式化的数字
+       * decimals:保留几位小数
+       * dec_point:小数点符号
+       * thousands_sep:千分位符号
+       * roundtag:舍入参数,默认 "ceil" 向上取,"floor"向下取,"round" 四舍五入
+       * */
+      number = (number + "").replace(/[^0-9+-Ee.]/g, "");
+      roundtag = roundtag || "floor"; //"ceil","floor","round"
+      let n = !isFinite(+number) ? 0 : +number,
+        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
+        sep = typeof thousands_sep === "undefined" ? "," : thousands_sep,
+        dec = typeof dec_point === "undefined" ? "." : dec_point,
+        s = "",
+        toFixedFix = function (ns, precs) {
+          let k = Math.pow(10, prec);
+
+          return (
+            "" +
+            parseFloat(
+              Math[roundtag](parseFloat((ns * k).toFixed(precs * 2))).toFixed(
+                precs * 2
+              )
+            ) /
+              k
+          );
+        };
+      s = (prec ? toFixedFix(n, prec) : "" + Math.round(n)).split(".");
+      let re = /(-?\d+)(\d{3})/;
+      while (re.test(s[0])) {
+        s[0] = s[0].replace(re, "$1" + sep + "$2");
+      }
+
+      if ((s[1] || "").length < prec) {
+        s[1] = s[1] || "";
+        s[1] += new Array(prec - s[1].length + 1).join("0");
+      }
+      return s.join(dec);
+    },
+    getNumberFormat(row, item) {
+      let {
+        decimals = 2,
+        decPoint = ".",
+        thousandsSep = ",",
+        roundtag = "floor",
+      } = item;
+      return this.numberFormat(
+        row[item.dataIndex],
+        decimals,
+        decPoint,
+        thousandsSep,
+        roundtag
+      );
+    },
+    getCopyFormatter(action, row) {
+      if (action.copyFormatter) {
+        return action.copyFormatter(row);
+      }
+    },
+    onCopyClick(action, row) {
+      /** 复制粘贴点击事件 **/
+      let copyStr = this.getCopyFormatter(action, row);
+      if (!copyStr) {
+        this.$message.error("复制失败");
+      }
+      if (action.click) {
+        action.click(row);
+      }
+    },
+    onCopyError(event, action, row) {
+      /** 复制粘贴-失败 **/
+      // // console.log('复制失败', event)
+      this.$message.error("复制失败");
+      if (action.copyError) {
+        action.copyError(event, row);
+      }
+    },
+    onCopySuccess(event, action, row) {
+      /** 复制粘贴-成功 **/
+      // // console.log('复制成功', event)
+      this.$message.success("复制成功");
+      if (action.copySuccess) {
+        action.copySuccess(event, row);
+      }
+    },
+    formatterNewMap(item, row) {
+      const map = new Map(item.options);
+      let key = row[item.dataIndex];
+      if (Number.isInteger(key)) {
+        key = key.toString();
+			}
+			if (!map.get(key)) {
+				return '-'
+			}
+      return map.get(key);
+    },
+    formatterMap(item, row) {
+      for (let key in item.options) {
+        if (item.options[key] == row[item.dataIndex]) {
+          return key;
+        }
+      }
+      return item.options[row[item.dataIndex]];
+    },
+    formatterData(item, row) {
+      let format = item.format ? item.format : "YYYY-MM-DD HH:mm:ss";
+      return row[item.dataIndex]
+        ? moment(row[item.dataIndex]).format(format)
+        : "-";
+    },
+    toggleSelectedRowKeys() {
+      this.$nextTick(() => {
+        if (this.selectedRowKeys && this.selectedRowKeys.length) {
+          this.selectedRowKeys.forEach((row) => {
+            this.$refs.YxTable.toggleRowSelection(row);
+          });
+        }
+      });
+    },
+    itemClick(e, action, scope, Events) {
+      let { row, $index } = scope;
+      if (action.click && !action.popconfirm) {
+        action.click(row, e, $index);
+      } else if (action.popconfirm && action[Events]) {
+        action.popconfirm && action[Events](row, e, $index);
+      }
+    },
+    getAtionFormatter(action, actionIndex, row) {
+      if (action.customRender) {
+        let newAction = action.customRender(Object.assign({}, action), row);
+        if (newAction) {
+          if (!newAction.hide) {
+            action.hide = false;
+          } else {
+            action.hide = true;
+          }
+        }
+        return newAction;
+      }
+      return action;
+    },
+    getpageSize(data) {
+      /** 获取没也长度 **/
+      let sizeArr = this.getPageSizes(data.pageSizes);
+      if (data.length) {
+        let isHas = false;
+        sizeArr.map((item) => {
+          if (data.length === item) {
+            isHas = true;
+          }
+        });
+        if (isHas) {
+          return data.length;
+        }
+      }
+      return sizeArr[0];
+    },
+    getPageSizes(data) {
+      /** 页码类型 **/
+      let sizes = [10, 30, 50, 100];
+      if (
+        data &&
+        Object.prototype.toString.call(data) === "[object Array]" &&
+        data.length > 0
+      ) {
+        return data;
+      } else {
+        return sizes;
+      }
+    },
+    sizeChange(data) {
+      /** 页码长度变化回调 **/
+      this.pagination.length = data;
+      if (this.pagination.tableChange) {
+        this.pagination.tableChange();
+      }
+    },
+    currentChange(data) {
+      /** 选中页码下标变化回调 **/
+      this.pagination.currentPage = data;
+      if (this.pagination.tableChange) {
+        this.pagination.tableChange();
+      }
+    },
+  },
+};
+</script>
+
+<style scoped>
+.el-pagination {
+  padding: 22px 10px;
+  text-align: center;
+}
+.popconfirm-btn{
+  margin-left: 10px;
+}
+.c_image{
+  width: 120px;
+  height: auto;
+}
+</style>

+ 471 - 0
src/components/warningCom/multiple-y-line-chart-normal.vue

@@ -0,0 +1,471 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "/@/tools/util.js";
+import partten from "/@/tools/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-y-line-chart-normal",
+  componentName: "multiple-y-line-chart-normal",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "13.889vh",
+    },
+    // 数据
+    list: {
+      type: Array,
+      default: () => [
+        {
+          title: "机舱震动x方向",
+          yAxisIndex: 0,
+          value: [
+            {
+              text: "-0.003",
+              value: -0.003,
+            },
+            {
+              text: "-0.002",
+              value: -0.002,
+            },
+            {
+              text: "-0.003",
+              value: -0.006,
+            },
+            {
+              text: "-0.003",
+              value: -0.003,
+            },
+            {
+              text: "-0.002",
+              value: -0.002,
+            },
+            {
+              text: "-0.003",
+              value: -0.006,
+            },
+            {
+              text: "-0.003",
+              value: -0.003,
+            },
+            {
+              text: "-0.002",
+              value: -0.002,
+            },
+            {
+              text: "-0.003",
+              value: -0.006,
+            },
+          ],
+        },
+        {
+          title: "机舱震动y方向",
+          yAxisIndex: 1,
+          value: [
+            {
+              text: "-0.01",
+              value: -0.01,
+            },
+            {
+              text: "-0.005",
+              value: -0.005,
+            },
+            {
+              text: "-0.008",
+              value: -0.008,
+            },
+            {
+              text: "-0.01",
+              value: -0.01,
+            },
+            {
+              text: "-0.005",
+              value: -0.005,
+            },
+            {
+              text: "-0.008",
+              value: -0.008,
+            },
+            {
+              text: "-0.01",
+              value: -0.01,
+            },
+            {
+              text: "-0.005",
+              value: -0.005,
+            },
+            {
+              text: "-0.008",
+              value: -0.008,
+            },
+          ],
+        },
+        {
+          title: "机舱震动最大偏移值",
+          yAxisIndex: 2,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "0.05",
+              value: 0.05,
+            },
+            {
+              text: "0.5",
+              value: 0.5,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "0.05",
+              value: 0.05,
+            },
+            {
+              text: "0.5",
+              value: 0.5,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "0.05",
+              value: 0.05,
+            },
+            {
+              text: "0.5",
+              value: 0.5,
+            },
+          ],
+        },
+        {
+          title: "风速1",
+          yAxisIndex: 3,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "5",
+              value: 5,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "5",
+              value: 5,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "5",
+              value: 5,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+          ],
+        },
+        {
+          title: "风速2",
+          yAxisIndex: 4,
+          value: [
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+            {
+              text: "1",
+              value: 1,
+            },
+            {
+              text: "2",
+              value: 2,
+            },
+            {
+              text: "3",
+              value: 1,
+            },
+          ],
+        },
+      ],
+    },
+    showLegend: {
+      type: Boolean,
+      default: false,
+    },
+    // 轴
+    yAxises: {
+      type: Array,
+      default: () => [
+        {
+          name: "机舱震动x方向",
+          min: -0.01,
+          max: 0,
+          unit: "",
+          position: "left",
+        },
+        {
+          name: "机舱震动y方向",
+          min: -0.01,
+          max: 0,
+          unit: "",
+          position: "right",
+        },
+        {
+          name: "机舱震动最大偏移值",
+          min: 0,
+          max: 1,
+          unit: "",
+          position: "left",
+        },
+        {
+          name: "风速1",
+          min: 0,
+          max: 10,
+          unit: "",
+          position: "right",
+        },
+        {
+          name: "风速2",
+          min: 0,
+          max: 10,
+          unit: "",
+          position: "left",
+        },
+      ],
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: ["#323E6F", "#1DA0D7", "#05BB4C", "#EDB32F", "#DB5520"],
+    };
+  },
+  computed: {
+    legend() {
+      return this.list.map((t) => {
+        return t.title;
+      });
+    },
+    xdata() {
+      if (this.list.length > 1) {
+        return this.list[1]?.value.map((t) => {
+          return t.text;
+        });
+      } else if (this.list.length == 1) {
+        return this.list[0]?.value.map((t) => {
+          return t.text;
+        });
+      }
+    },
+    yAxis() {
+      let result = [];
+      let p = { left: 0, right: 0 };
+      this.yAxises.forEach((item, index) => {
+        result.push({
+          type: "value",
+          name: `${item.name}${item.unit}`,
+          nameLocation: p[item.position] % 2 == 0 ? "end" : "start",
+          nameGap: 10,
+          min: item.min,
+          max: item.max,
+          position: item.position,
+          offset: p[item.position] * 50,
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: 12,
+          },
+          //分格线
+          splitLine: {
+            lineStyle: {
+              color: partten.getColor("gray"),
+              type: "dashed",
+            },
+          },
+          axisLine: {
+            show: true,
+          },
+          axisTick: {
+            show: true,
+          },
+        });
+        p[item.position]++;
+      });
+      return result;
+    },
+    series() {
+      let result = [];
+      this.list.forEach((value, index) => {
+        result.push({
+          name: value.title,
+          type: "line",
+          smooth: true,
+          zlevel: index,
+          lineStyle: {
+            normal: {
+              color: this.color[index],
+              width: 1,
+            },
+          },
+          showSymbol: false,
+          yAxisIndex: value.yAxisIndex,
+          data: value.value.map((t) => {
+            return t.value;
+          }),
+        });
+      });
+
+      return result;
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      const chart = echarts.init(this.$el);
+
+      let option = this.option();
+      chart.clear();
+
+      chart.setOption(option);
+      this.resize = function () {
+        chart.resize();
+      };
+
+      window.addEventListener("resize", this.resize);
+    },
+    option: function () {
+      return {
+        color: this.color,
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("gray"),
+          textStyle: {
+            color: "#fff",
+            fontSize: 12,
+          },
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.legend,
+          top: "top",
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: partten.getColor("gray"),
+          textStyle: {
+            color: partten.getColor("grayl"),
+            fontSize: 12,
+          },
+        },
+        grid: {
+          top: 27,
+          left: 16,
+          right: 16,
+          bottom: 0,
+          containLabel: true,
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              interval:
+                Number((this.xdata.length / 8).toFixed(0)) > 2
+                  ? Number((this.xdata.length / 8).toFixed(0))
+                  : 0,
+              showMinLabel: true,
+              showMaxLabel: true,
+              formatter: "{value}",
+              fontSize: 12,
+              textStyle: {
+                color: partten.getColor("gray"),
+              },
+            },
+            data: this.xdata,
+          },
+        ],
+        yAxis: this.yAxis,
+        series: this.series,
+      };
+    },
+    reload: function () {
+      const chart = echarts.getInstanceByDom(this.$el);
+      chart.clear();
+      let option = this.option();
+      chart.setOption(option);
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+<style lang="scss" scoped>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 50 - 0
src/components/warningCom/panel3.vue

@@ -0,0 +1,50 @@
+<template>
+  <div class="com-panel-3">
+    <span class="dot top-left"></span>
+    <span class="dot bottom-left"></span>
+    <span class="dot top-rignt"></span>
+    <span class="dot bottom-right"></span>
+    <slot></slot>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "com-panel-3",
+  componentName: "com-panel-3",
+};
+</script>
+<style lang="scss" scoped>
+.com-panel-3 {
+  position: relative;
+  background: rgba(255, 255, 255, 0.1);
+  padding: 1.4815vh;
+  display: inline-block;
+  .dot {
+    position: absolute;
+    width: 0.370vh;
+    height: 0.370vh;
+    background: #fff;
+
+    &.top-left {
+      top: 0.556vh;
+      left: 0.556vh;
+    }
+
+    &.bottom-left {
+      bottom: 0.556vh;
+      left: 0.556vh;
+    }
+
+    &.top-rignt {
+      top: 0.556vh;
+      right: 0.556vh;
+    }
+
+    &.bottom-right {
+      bottom: 0.556vh;
+      right: 0.556vh;
+    }
+  }
+}
+</style>

+ 288 - 0
src/components/warningCom/table3.vue

@@ -0,0 +1,288 @@
+<template>
+  <el-table
+    class="custom-table"
+    stripe
+    :data="data.data"
+    :height="height"
+    style="width: 100%"
+    @cell-click="onClick"
+    v-if="data && data.data"
+  >
+    <el-table-column
+      v-for="col in data.column"
+      :key="col"
+      :prop="col.field"
+      :label="col.name"
+      :width="col.width"
+      :min-width="col.minWidth"
+      :sortable="col.sortable"
+      :sort-orders="sortOrder"
+      :sort-by="col.field + '.time'"
+      :show-overflow-tooltip="!col.slot"
+      :fixed="col.fixed"
+      :resizable="col.resizable"
+    >
+      <template v-if="col.slot == true" #default="item">
+        <slot
+          :name="col.field"
+          :column="col"
+          :row="item.row"
+          :all="item"
+          :data="item.row[col.field]"
+        ></slot>
+      </template>
+    </el-table-column>
+  </el-table>
+  <el-pagination
+    class="mg-t-8"
+    v-if="pageable"
+    @current-change="handleCurrentChange"
+    :current-page="currentPage"
+    v-model:page-size="selfPageSize"
+    :total="data.total"
+    v-bind="elPaggingProps"
+  >
+  </el-pagination>
+</template>
+
+<script>
+export default {
+  // 名称
+  name: "ComTable",
+  // 使用组件
+  components: {},
+  // 传入参数
+  props: {
+    /**
+             * {
+                    column: [{
+                        name: "风机名称",
+                        field: "name",
+                        width:'', // 宽度
+                        click:function(){} // 点击事件
+                        sortable:fasle,
+                        slot:false,
+                        fixed:false,
+                        align:'center',
+                        resizable :false,
+                    }],
+                    total:200
+                }
+             */
+    data: Object,
+    height: {
+      type: String,
+      default: "",
+    },
+    pageSize: {
+      type: Number,
+      default: 0,
+    },
+    elPaggingProps: {
+      type: Object,
+      default: () => {
+        return {
+          layout: "total, sizes, prev, pager, next, jumper",
+          // "page-sizes": [100, 200, 300, 400],
+        };
+      },
+    },
+    sortOrder: {
+      type: Array,
+      default: () => {
+        return ["descending", "ascending", null];
+      },
+    },
+  },
+  // 自定义事件
+  emits: {
+    // 分页事件
+    onPagging: null,
+  },
+  // 数据
+  data() {
+    return {
+      currentPage: 1,
+    };
+  },
+  computed: {
+    tableData() {
+      let that = this;
+      if (this.sortCol == "") {
+        return this.data.data;
+      } else {
+        let data = this.data.data;
+
+        data.sort((a, b) => {
+          let rev = 1;
+          if (that.sortType == "ASC") rev = 1;
+          else if (that.sortType == "DESC") rev = -1;
+
+          if (a[that.sortCol] > b[that.sortCol]) return rev * 1;
+          if (a[that.sortCol] < b[that.sortCol]) return rev * -1;
+          return 0;
+        });
+        return data;
+      }
+    },
+    pageable() {
+      return this.pageSize != 0;
+    },
+    pages() {
+      if (this.pageable) return parseInt(this.data.total / this.pageSize) + 1;
+      else return 0;
+    },
+    startRow() {
+      if (this.pageable) return (this.currentPage - 1) * this.pageSize;
+      else return 0;
+    },
+    endRow() {
+      if (this.pageable) return this.currentPage * this.pageSize;
+      else return this.data.data.length;
+    },
+    // sortOrder: {
+    //   type: Array,
+    //   default: () => {
+    //     return ["descending", "ascending", null];
+    //   },
+    // },
+  },
+  // 函数
+  methods: {
+    onClick(row, column, cell, event) {
+      // if (column.rawColumnKey.click) column.rawColumnKey.click(event, row);
+    },
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.$emit("onPagging", {
+        pageIndex: this.currentPage,
+        pageSize: this.pageSize,
+        start: this.startRow,
+        end: this.endRow,
+      });
+    },
+  },
+  // 生命周期钩子
+  beforeCreate() {
+    // 创建前
+  },
+  created() {
+    // 创建后
+    this.selfPageSize = this.pageSize;
+  },
+  beforeMount() {
+    // 渲染前
+  },
+  mounted() {
+    // 渲染后
+  },
+  beforeUpdate() {},
+  updated() {},
+};
+</script>
+
+<style lang="scss" scoped>
+$titleGray: #9ca5a8;
+$rowGray: #606769;
+$darkBack: #536268;
+$green:#606769;
+$gray:#606769;
+$gray-l:#606769;
+.com-table {
+  width: 100%;
+  border-collapse: collapse;
+
+  thead {
+    tr {
+      display: table;
+      table-layout: fixed;
+      width: 100%;
+
+      th {
+        background-color: fade($darkBack, 20%);
+        height: 30px;
+        line-height: 30px;
+        color: $titleGray;
+        font-weight: 400;
+        font-size: 16px;
+        position: sticky;
+        top: 0;
+        cursor: pointer;
+
+        &.light,
+        &.always-light {
+          color: #606769;
+        }
+      }
+    }
+  }
+
+  tbody {
+    display: block;
+
+    tr {
+      display: table;
+      table-layout: fixed;
+      width: 100%;
+
+      &:nth-child(2n) {
+        background-color: fade($rowGray, 20%);
+      }
+
+      td {
+        padding: 0.556vh 0;
+        color: $rowGray;
+        text-align: center;
+        font-size: 16px;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+
+        &.light,
+        &.always-light {
+          color: $green !important;
+        }
+
+        &.num {
+          font-family: "Bicubik";
+          font-weight: 400;
+        }
+      }
+    }
+  }
+
+  .el-pagination {
+    color: $gray;
+    .el-pagination__total {
+      color: $gray;
+    }
+
+    button {
+      &.btn-next,
+      &.btn-prev {
+        background: center center no-repeat fade($gray, 20);
+        color: $gray-l;
+      }
+      &:disabled {
+        color: $gray-l;
+        background-color: fade($gray, 20);
+        cursor: not-allowed;
+      }
+    }
+
+    .el-pager li {
+      color: $gray-l;
+      background: fade($gray, 20);
+      &.active {
+        color: $green;
+      }
+    }
+
+    .el-input__inner {
+      color: $gray-l;
+      background: fade($gray, 20);
+      border: 1px solid fade($gray, 20);
+    }
+  }
+}
+</style>

+ 10 - 0
src/data/areaData.json

@@ -0,0 +1,10 @@
+{
+    "msg": "成功",
+    "code": 200,
+    "data": {
+	"pcl5": 0.65,
+	"pcl10": 0.65,
+	"pcl12": 0.65,
+	"pcl25": 0.65
+     }   
+}

文件差異過大導致無法顯示
+ 1 - 0
src/data/dot.json


+ 33 - 0
src/data/flower.json

@@ -0,0 +1,33 @@
+{
+	"msg": "成功",
+	"code": 200,
+	"data": [{
+		"count": [
+			[13, 8, 10, 13, 21, 41, 105, 129, 138, 102, 50, 11, 20, 14, 22, 16],
+			[16, 20, 10, 7, 6, 16, 126, 720, 1062, 262, 46, 10, 5, 12, 8, 7],
+			[0, 0, 0, 0, 0, 4, 30, 390, 448, 88, 4, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 9, 69, 99, 19, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 1, 1, 30, 31, 4, 1, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 2, 7, 11, 2, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+		],
+		"wt": "NG01_01",
+		"roses": [
+			[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+			[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+			[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+			[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+		]
+	}]
+}

文件差異過大導致無法顯示
+ 14211 - 0
src/data/lineNew.json


文件差異過大導致無法顯示
+ 1512 - 0
src/data/table.json


+ 0 - 0
src/helper/README.md


部分文件因文件數量過多而無法顯示