rui.jiang 1 jaar geleden
bovenliggende
commit
9fdf4027f1
65 gewijzigde bestanden met toevoegingen van 25261 en 728 verwijderingen
  1. 22276 20
      package-lock.json
  2. 2 0
      package.json
  3. 115 0
      sever/index.js
  4. 20 0
      sever/package.json
  5. 26 1
      src/api/dataManage.js
  6. 15 0
      src/api/dragChart.js
  7. 215 0
      src/assets/js/constants/color.js
  8. 20 5
      src/assets/js/constants/echarts-config/Cp.js
  9. 11 6
      src/assets/js/constants/echarts-config/Heatmap.js
  10. 2 0
      src/assets/js/constants/echarts-config/bar.js
  11. 2 2
      src/assets/js/constants/echarts-config/barandline.js
  12. 19 1
      src/assets/js/constants/echarts-config/boxPlot.js
  13. 3 1
      src/assets/js/constants/echarts-config/hexbin.js
  14. 3 1
      src/assets/js/constants/echarts-config/histogram.js
  15. 2 0
      src/assets/js/constants/echarts-config/line.js
  16. 41 2
      src/assets/js/constants/echarts-config/pareto.js
  17. 2 2
      src/assets/js/constants/echarts-config/pie.js
  18. 2 0
      src/assets/js/constants/echarts-config/radar.js
  19. 5 1
      src/assets/js/constants/echarts-config/roseChart.js
  20. 4 2
      src/assets/js/constants/echarts-config/sankeyDiagram.js
  21. 7 0
      src/assets/js/constants/echarts-config/scatter.js
  22. 2 0
      src/assets/js/constants/echarts-config/stackedBar.js
  23. 3 1
      src/assets/js/constants/echarts-config/timeSeries.js
  24. 2 0
      src/assets/js/constants/echarts-config/waterfall.js
  25. 0 1
      src/icons/svg/Cp.svg
  26. 1 0
      src/icons/svg/Cp1.svg
  27. 0 1
      src/icons/svg/Heatmap.svg
  28. 1 1
      src/icons/svg/bar.svg
  29. 1 0
      src/icons/svg/bar1.svg
  30. 0 0
      src/icons/svg/boxPlot.svg
  31. 0 0
      src/icons/svg/line.svg
  32. 0 0
      src/icons/svg/pareto.svg
  33. 0 0
      src/icons/svg/pareto1.svg
  34. 1 1
      src/icons/svg/pie.svg
  35. 0 0
      src/icons/svg/roseChart.svg
  36. 1 0
      src/icons/svg/roseChart1.svg
  37. 0 0
      src/icons/svg/sankeyDiagram.svg
  38. 0 0
      src/icons/svg/scatter.svg
  39. 0 0
      src/icons/svg/stackedBar.svg
  40. 1 1
      src/icons/svg/waterfall.svg
  41. 11 4
      src/main.js
  42. 14 20
      src/store/dragChart.js
  43. 9 0
      src/store/index.js
  44. 69 2
      src/utils/indexedDb.js
  45. 105 0
      src/utils/vuexIndexedDBPlugin.js
  46. 169 239
      src/views/dataAdministration/vibration/index.vue
  47. 0 1
      src/views/performance/components/custonAsCom/AssociatedFields.vue
  48. 136 96
      src/views/performance/components/custonAsCom/DatabaseTable.vue
  49. 1 3
      src/views/performance/components/custonAsCom/dataTable.vue
  50. 15 2
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/index.js
  51. 127 0
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/Heatmap.js
  52. 1 1
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/barAndLine.js
  53. 116 0
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/boxPlot.js
  54. 127 86
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/cp.js
  55. 246 0
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/pareto.js
  56. 89 0
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/pie.js
  57. 97 0
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/roseChart.js
  58. 124 0
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/sankeyDiagram.js
  59. 199 31
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/scatter.js
  60. 113 0
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/stackedBar.js
  61. 397 119
      src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartTitle.vue
  62. 32 30
      src/views/performance/components/custonAsCom/dragChart/components/chartsAttributes.vue
  63. 17 13
      src/views/performance/components/custonAsCom/dragChart/components/chartsData.vue
  64. 222 24
      src/views/performance/customAnalysis.vue
  65. 20 7
      vue.config.js

File diff suppressed because it is too large
+ 22276 - 20
package-lock.json


+ 2 - 0
package.json

@@ -20,10 +20,12 @@
     "el-tree-select": "^3.1.14",
     "element-ui": "^2.15.14",
     "file-saver": "^2.0.5",
+    "flatted": "^3.3.2",
     "happypack": "^5.0.1",
     "jszip": "^3.10.1",
     "luckysheet": "^2.1.13",
     "ol": "^9.2.3",
+    "pako": "^2.1.0",
     "papaparse": "^5.4.1",
     "plotly.js-dist": "^2.34.0",
     "plotly.js-dist-min": "^2.34.0",

+ 115 - 0
sever/index.js

@@ -0,0 +1,115 @@
+import express from "express";
+import mysql from "mysql2/promise";
+import timeout from "connect-timeout";
+import bodyParser from "body-parser";
+const app = express();
+const PORT = 3000;
+
+// 设置请求超时,单位为毫秒(比如:设置 30 秒超时)
+app.use(timeout("30s"));
+app.use(bodyParser.json()); // 在请求处理之前,先解析JSON
+// 处理超时请求
+app.use((req, res, next) => {
+  if (req.timedout) {
+    return res.status(408).send("Request Timeout");
+  }
+  next();
+});
+
+// 获取表和字段信息
+app.get("/tables", async (req, res) => {
+  let pool;
+  try {
+    const { IP, host, baseName, username, password } = req.query;
+    // 数据库连接配置
+    pool = mysql.createPool({
+      host: IP,
+      user: username,
+      password: password,
+      database: baseName,
+      port: host,
+    });
+    const connection = await pool.getConnection();
+    const [tables] = await connection.query("SHOW TABLES");
+    const tableFieldMap = {};
+    for (const table of tables) {
+      const tableName = Object.values(table)[0];
+      const [fields] = await connection.query(`DESCRIBE ${tableName}`);
+      tableFieldMap[tableName] = fields.map((field) => field.Field);
+    }
+    connection.release();
+    res.json(tableFieldMap);
+  } catch (error) {
+    // console.error("Error fetching database structure:", error);
+    res.status(500).send("请检查填写的数据库数据是否有误" + error);
+  } finally {
+    // 确保关闭数据库连接池
+    if (pool) {
+      await pool.end();
+    }
+  }
+});
+app.post("/filterTablesData", async (req, res) => {
+  try {
+    console.log(req.params, req.body, "req.query.filterData");
+    const { IP, host, baseName, username, password } = req.body.database;
+    const filterData = req.body.filterData;
+    // 数据库连接配置
+    const pool = mysql.createPool({
+      host: IP,
+      user: username,
+      password: password,
+      database: baseName,
+      port: host,
+    });
+    // 获取数据库连接;
+    const connection = await pool.getConnection();
+    // 用于存储最终查询结果
+    const resultData = {};
+    // 遍历 filterData
+    for (const item of filterData) {
+      const parentNode = item.parentNode; // 数据表名
+      const checkChildNode = item.checkChildNode; // 要查询的字段
+
+      // 检查表是否存在
+      const [tables] = await connection.query("SHOW TABLES");
+      const tableNames = tables.map((row) => Object.values(row)[0]);
+      if (!tableNames.includes(parentNode)) {
+        continue; // 如果表不存在,跳过
+      }
+
+      // 获取表字段信息
+      const [columns] = await connection.query(
+        `SHOW COLUMNS FROM ${parentNode}`
+      );
+      const tableFields = columns.map((column) => column.Field);
+
+      // 过滤存在的字段
+      const validFields = checkChildNode.filter((field) =>
+        tableFields.includes(field)
+      );
+      if (validFields.length === 0) {
+        continue; // 如果没有匹配的字段,跳过
+      }
+
+      // 动态查询字段的数据
+      const sqlQuery = `SELECT ${validFields.join(
+        ", "
+      )} FROM ${parentNode} LIMIT 100`; // 限制查询 100 条数据
+      const [rows] = await connection.query(sqlQuery);
+
+      // 保存结果
+      resultData[parentNode] = rows;
+    }
+    // 释放连接
+    connection.release();
+    // 返回最终数据
+    res.json(resultData);
+  } catch (error) {
+    console.error(error);
+    res.status(500).send("Error fetching data from database");
+  }
+});
+app.listen(PORT, () => {
+  console.log(`Server is running on http://localhost:${PORT}`);
+});

+ 20 - 0
sever/package.json

@@ -0,0 +1,20 @@
+{
+  "name": "sever",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "type": "module",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "start": "nodemon index.js"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "body-parser": "^1.20.3",
+    "connect-timeout": "^1.9.0",
+    "express": "^4.21.1",
+    "mysql2": "^3.11.5"
+  }
+}

+ 26 - 1
src/api/dataManage.js

@@ -1,12 +1,37 @@
 /*
  * @Author: your name
  * @Date: 2024-06-04 09:48:21
- * @LastEditTime: 2024-07-18 09:31:19
+ * @LastEditTime: 2024-12-06 14:34:47
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /dashengmag/performance-test/src/api/dataManage.js
  */
 import request from "@/utils/request";
+// /waveDatatransfer/dataTransfer
+//查询振动数据转换数组
+export function getDataTransfer(data) {
+  return request({
+    url: "/energy-manage-service/waveDataTransfer/queryDataTransfer",
+    method: "get",
+    params: data,
+  });
+}
+// 转换、重新转换/energy-manage-service/waveDatatransfer/dataTransfer
+export function DataTransfer(data) {
+  return request({
+    url: "/energy-manage-service/waveDataTransfer/dataTransfer",
+    method: "post",
+    data,
+  });
+}
+//新增振动数据转换/energy-manage-service/waveDataTransfer/addDataTransfer
+export function addDataTransfer(data) {
+  return request({
+    url: "/energy-manage-service/waveDataTransfer/addDataTransfer",
+    method: "post",
+    data,
+  });
+}
 //查询转换数组
 export function queryDataTransferGroup(data) {
   return request({

+ 15 - 0
src/api/dragChart.js

@@ -0,0 +1,15 @@
+/*
+ * @Author: your name
+ * @Date: 2024-11-29 14:33:04
+ * @LastEditTime: 2024-11-29 14:36:00
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/api/dragChart.js
+ */
+// export function DataTransfer(data) {
+//   return request({
+//     url: "/apiAlgorithm/calculate-features",
+//     method: "post",
+//     data,
+//   });
+// }

+ 215 - 0
src/assets/js/constants/color.js

@@ -0,0 +1,215 @@
+/*
+ * @Author: your name
+ * @Date: 2024-11-27 14:40:15
+ * @LastEditTime: 2024-11-27 15:12:50
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/assets/js/constants/color.js
+ */
+//蓝绿色
+// export const colorPalette = [
+//   "#0a74b7",
+//   "#1f7a57",
+//   "#0a6f6f",
+//   "#4e9f99",
+//   "#5d8d7e",
+//   "#008080",
+//   "#338f96",
+//   "#3b9b8e",
+//   "#4b8e8d",
+//   "#007f5f",
+//   "#2d5d74",
+//   "#396b86",
+//   "#005a66",
+//   "#3d7287",
+//   "#009977",
+//   "#107d67",
+//   "#71b7b1",
+//   "#238f8f",
+//   "#4d918e",
+//   "#8db38d",
+//   "#1e7f7f",
+//   "#45818e",
+//   "#6a7b8e",
+//   "#567f7f",
+//   "#487c68",
+//   "#3a9d9d",
+//   "#2e8c85",
+//   "#006d5b",
+//   "#61bfa5",
+//   "#4a8c7d",
+//   "#348d8d",
+//   "#5d9b91",
+//   "#005a5a",
+//   "#4a7377",
+//   "#288e8e",
+//   "#3c9b9b",
+//   "#009e7b",
+//   "#197b7b",
+//   "#2c6872",
+//   "#3b716b",
+//   "#6b8d7a",
+//   "#41766b",
+//   "#32775c",
+//   "#33805e",
+//   "#3d7b6f",
+//   "#0f3a4f",
+//   "#2a5377",
+//   "#557f7f",
+//   "#2f748c",
+//   "#458687",
+//   "#1c4f68",
+//   "#359b98",
+//   "#2b8d8d",
+//   "#4d91a4",
+//   "#3a6770",
+//   "#469f9b",
+//   "#54898f",
+//   "#5b928f",
+//   "#3a8186",
+//   "#337d80",
+//   "#486775",
+//   "#567b77",
+//   "#3f9d92",
+//   "#7e9e9e",
+//   "#3c8c8c",
+//   "#58998d",
+//   "#388f7f",
+//   "#458f85",
+//   "#4a837b",
+//   "#347e6e",
+//   "#4c6f7b",
+//   "#33657f",
+//   "#35879b",
+//   "#417e80",
+//   "#3d6575",
+//   "#47665b",
+//   "#2c6b7b",
+//   "#548a7d",
+//   "#2a6470",
+//   "#1d6c6c",
+//   "#397d6d",
+//   "#316c69",
+//   "#417d7e",
+//   "#328a8e",
+//   "#397a6d",
+//   "#366c8f",
+//   "#24675c",
+//   "#417e8f",
+//   "#276d72",
+//   "#3a7c8a",
+//   "#467f81",
+//   "#246775",
+//   "#356c6b",
+//   "#29867c",
+//   "#327b80",
+//   "#568f77",
+//   "#3a6f5e",
+//   "#4b756d",
+//   "#316f8e",
+//   "#557c8f",
+//   "#53847a",
+//   "#357479",
+//   "#3a6b6c",
+//   "#2f737d",
+//   "#397d6b",
+//   "#307e7b",
+//   "#447a7d",
+//   "#1b4f77",
+//   "#357f7f",
+//   "#3c7b77",
+//   "#5a9179",
+//   "#4b7a7b",
+//   "#347c78",
+//   "#358d6b",
+//   "#487d8f",
+//   "#397d8d",
+//   "#43757d",
+//   "#306b8e",
+//   "#2e6e8c",
+//   "#2f7c8d",
+//   "#437a7b",
+//   "#38767f",
+//   "#36767b",
+//   "#2f7f6e",
+//   "#468b8e",
+// ];
+//蓝紫色
+export const colorPalette = [
+  "#5167a2",
+  "#687db0",
+  "#8597c0",
+  "#ccd5e3", // 给定的基础颜色
+  "#3e4d76",
+  "#7f98b5",
+  "#9da9b8",
+  "#b3c1d1", // 更深、稍带灰色的蓝色系列
+  "#4f5f8d",
+  "#5c73a0",
+  "#728ab8",
+  "#92a9c7", // 增加深浅对比的蓝色系列
+  "#3c4f78",
+  "#556e96",
+  "#6b88b0",
+  "#7b9fc3", // 增加对比度的蓝色系列
+  "#2e3b5c",
+  "#3e5376",
+  "#4e6a90",
+  "#6e8bb1", // 深蓝色系列和淡蓝色过渡
+  "#1f2b47",
+  "#2f3c61",
+  "#406a8d",
+  "#5a84a8", // 更加深沉的蓝色系列
+  "#547d94",
+  "#6c96b1",
+  "#8fa7c2",
+  "#c0d0e0", // 从深到浅的渐变系列
+  "#4b5e7c",
+  "#6f8099",
+  "#8a9bb4",
+  "#b8c7d9", // 更加鲜明的蓝色系列
+  "#40618d",
+  "#537ba3",
+  "#6a92b9",
+  "#90adc7", // 饱和度提高的蓝色系列
+  "#305079",
+  "#417f98",
+  "#5b98b3",
+  "#76adc6", // 淡蓝色与深蓝色相结合
+  "#274c68",
+  "#3c6481",
+  "#558ea3",
+  "#6db4c7", // 更加突出的对比
+  "#3e4e7b",
+  "#547b98",
+  "#748da9",
+  "#a1bbd4", // 深蓝至淡蓝的渐变
+  "#2c3b5a",
+  "#3d4d73",
+  "#54798d",
+  "#7498b6", // 深浅变化的蓝色
+  "#2f3f65",
+  "#41597f",
+  "#5b799a",
+  "#7f9fc7", // 不同深度的蓝色
+  "#35476a",
+  "#487f9e",
+  "#5f9bb6",
+  "#84b7d2", // 蓝色渐变系列
+  "#1a2b43",
+  "#2b3f5a",
+  "#3e5779",
+  "#51768f", // 更加沉稳的蓝色系
+  "#263d56",
+  "#3b5079",
+  "#4c6c97",
+  "#6885b4", // 中性蓝系列
+  "#1e2e4b",
+  "#2f3f62",
+  "#41567b",
+  "#567b9e", // 清晰的蓝色渐变
+  "#283c54",
+  "#3a4f73",
+  "#4c698f",
+  "#6486b0", // 蓝色的温暖渐变
+];

+ 20 - 5
src/assets/js/constants/echarts-config/Cp.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2024-11-19 16:22:48
- * @LastEditTime: 2024-11-22 14:43:53
+ * @LastEditTime: 2024-11-27 14:50:45
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/assets/js/constants/echarts-config/Cp.js
@@ -9,7 +9,10 @@
 // 风能利用系数图 散点折线图
 // 用途:分析风能利用系数(Cp)与风速或叶尖速比的关系。
 // 适用场景:风机效率优化。
+
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风速与功率输出对比",
   },
@@ -83,7 +86,10 @@ export const option = {
         [0, 0],
         [30, 120], // 假设风速为30 m/s时功率输出为120 kW
       ],
-      lineStyle: { color: "#144464" }, // 折线颜色
+      itemStyle: {
+        color: colorPalette[0], // 为风机A的散点设置单独的颜色
+      },
+      // lineStyle: { color: "#144464" }, // 折线颜色
       renderMode: "webgl", // 启用 WebGL 渲染
     },
     {
@@ -93,13 +99,16 @@ export const option = {
         [0, 0],
         [30, 100], // 假设风速为30 m/s时功率输出为100 kW
       ],
-      lineStyle: { color: "#e4641c" }, // 折线颜色
+      itemStyle: {
+        color: colorPalette[1], // 为风机A的散点设置单独的颜色
+      },
+      // lineStyle: { color: "#e4641c" }, // 折线颜色
       renderMode: "webgl", // 启用 WebGL 渲染
     },
     {
       name: "风机A 散点",
       symbolSize: 8,
-      color: "#348ccc",
+      // color: "#348ccc",
       data: [
         [3, 2], // 风速为3 m/s时的功率输出为2 kW
         [6, 5], // 风速为6 m/s时的功率输出为5 kW
@@ -107,13 +116,16 @@ export const option = {
         [15, 35], // 风速为15 m/s时的功率输出为35 kW
         [18, 60], // 风速为18 m/s时的功率输出为60 kW
       ],
+      itemStyle: {
+        color: colorPalette[2], // 为风机A的散点设置单独的颜色
+      },
       type: "scatter",
       renderMode: "webgl", // 启用 WebGL 渲染
     },
     {
       name: "风机B 散点",
       symbolSize: 10,
-      color: "#e4bc2c",
+      // color: "#e4bc2c",
       data: [
         [4, 3], // 风速为4 m/s时的功率输出为3 kW
         [8, 8], // 风速为8 m/s时的功率输出为8 kW
@@ -121,6 +133,9 @@ export const option = {
         [16, 50], // 风速为16 m/s时的功率输出为50 kW
         [20, 80], // 风速为20 m/s时的功率输出为80 kW
       ],
+      itemStyle: {
+        color: colorPalette[3], // 为风机A的散点设置单独的颜色
+      },
       type: "scatter",
       renderMode: "webgl", // 启用 WebGL 渲染
     },

+ 11 - 6
src/assets/js/constants/echarts-config/Heatmap.js

@@ -1,14 +1,16 @@
 /*
  * @Author: your name
  * @Date: 2024-11-20 09:13:21
- * @LastEditTime: 2024-11-25 09:43:16
+ * @LastEditTime: 2024-11-27 17:39:46
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/assets/js/constants/echarts-config/Heatmap.js
  */
 //Heatmap-热力图
 // 风速随时间和风向的分布
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette, // 使用 colorPalette 作为颜色设置
   title: {
     text: "风速随时间和风向的分布",
   },
@@ -31,23 +33,20 @@ export const option = {
     name: "时间",
   },
   yAxis: {
-    type: "category",
     data: ["0°", "90°", "180°", "270°"], // 风向
     name: "风向",
   },
   visualMap: {
-    // min: 0,
-    // max: 20, // 风速范围
     calculable: true,
     realtime: false,
     orient: "vertical",
     right: 20,
     top: "center",
-    // bottom: "15%",
+    color: ["#0d59b7", "#bee8ff"],
   },
   series: [
     {
-      name: "风速",
+      // name: "风速",
       type: "heatmap",
       data: [
         [0, 0, 5],
@@ -57,6 +56,12 @@ export const option = {
         [1, 1, 8],
         [2, 1, 12],
       ], // [x, y, 风速值]
+      emphasis: {
+        itemStyle: {
+          shadowBlur: 10,
+          shadowColor: "rgba(0, 0, 0, 0.5)",
+        },
+      },
     },
   ],
 };

+ 2 - 0
src/assets/js/constants/echarts-config/bar.js

@@ -1,4 +1,6 @@
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "额定风速间隔数据计数",
   },

+ 2 - 2
src/assets/js/constants/echarts-config/barandline.js

@@ -1,6 +1,6 @@
-const colors = ["#5470C6", "#91CC75", "#EE6666"];
+import { colorPalette } from "../color";
 export const option = {
-  color: colors,
+  color: colorPalette,
   tooltip: {
     trigger: "axis",
     axisPointer: {

+ 19 - 1
src/assets/js/constants/echarts-config/boxPlot.js

@@ -1,14 +1,16 @@
 /*
  * @Author: your name
  * @Date: 2024-11-20 09:14:10
- * @LastEditTime: 2024-11-25 09:49:28
+ * @LastEditTime: 2024-11-27 17:06:24
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/assets/js/constants/echarts-config/boxPlot.js
  */
 //箱线图-boxPlot
 //不同季节的风速分布
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "季节的风速分布",
   },
@@ -26,6 +28,22 @@ export const option = {
       saveAsImage: { show: true },
     },
   },
+  dataZoom: [
+    {
+      type: "inside",
+      xAxisIndex: [0, 1],
+      start: 0,
+      end: 100,
+    },
+    {
+      show: true,
+      xAxisIndex: [0, 1],
+      type: "slider",
+      bottom: 10,
+      start: 0,
+      end: 100,
+    },
+  ],
   xAxis: {
     type: "category",
     data: ["春季", "夏季", "秋季", "冬季"],

+ 3 - 1
src/assets/js/constants/echarts-config/hexbin.js

@@ -1,14 +1,16 @@
 /*
  * @Author: your name
  * @Date: 2024-11-20 09:17:31
- * @LastEditTime: 2024-11-25 09:43:28
+ * @LastEditTime: 2024-11-27 15:04:43
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/assets/js/constants/echarts-config/hexbin.js
  */
 // 蜂巢图-Hexbin
 // 风速和风向的联合分布
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风速和风向的联合分布",
   },

+ 3 - 1
src/assets/js/constants/echarts-config/histogram.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2024-11-19 16:24:20
- * @LastEditTime: 2024-11-25 09:43:57
+ * @LastEditTime: 2024-11-27 15:04:49
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/assets/js/constants/echarts-config/histogram.js
@@ -11,7 +11,9 @@
 // 适用场景:风速频率统计、资源分布分析。
 // 实现建议:
 // 使用 ECharts 的直方图。
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风速分布直方图",
   },

+ 2 - 0
src/assets/js/constants/echarts-config/line.js

@@ -4,7 +4,9 @@
 // 实现建议:
 // 使用 ECharts 的折线图。
 // xAxis 为风速,yAxis 为功率。
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风速-功率曲线图",
   },

+ 41 - 2
src/assets/js/constants/echarts-config/pareto.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2024-11-20 09:19:45
- * @LastEditTime: 2024-11-25 09:44:44
+ * @LastEditTime: 2024-11-27 15:05:13
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/assets/js/constants/echarts-config/pareto.js
@@ -9,7 +9,32 @@
 // 帕累托图-pareto
 // 风电场设备故障类型及累积影响
 // 帕累托图通常用于显示数据的分类贡献和累积比例。
+
+import * as echarts from "echarts/core";
+import { BarChart, LineChart } from "echarts/charts";
+import {
+  GridComponent,
+  TooltipComponent,
+  LegendComponent,
+  ToolboxComponent,
+} from "echarts/components";
+import { CanvasRenderer } from "echarts/renderers";
+import { GraphicComponent } from "echarts/components"; // 引入 graphic 模块
+
+echarts.use([
+  BarChart,
+  LineChart,
+  GridComponent,
+  TooltipComponent,
+  LegendComponent,
+  ToolboxComponent,
+  CanvasRenderer,
+  GraphicComponent,
+]);
+
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "设备故障类型及累积",
   },
@@ -53,8 +78,22 @@ export const option = {
       name: "故障频率",
       type: "bar",
       data: [50, 30, 10, 5, 5],
+      showBackground: true,
       itemStyle: {
-        color: "#5793f3",
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          { offset: 0, color: "#83bff6" },
+          { offset: 0.5, color: "#188df0" },
+          { offset: 1, color: "#188df0" },
+        ]),
+      },
+      emphasis: {
+        itemStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            { offset: 0, color: "#2378f7" },
+            { offset: 0.7, color: "#2378f7" },
+            { offset: 1, color: "#83bff6" },
+          ]),
+        },
       },
     },
     {

+ 2 - 2
src/assets/js/constants/echarts-config/pie.js

@@ -1,18 +1,18 @@
 // 风电场发电量来源占比
 // 饼图用于显示不同类别占比,直观展现数据的构成情况。
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风电场发电量来源占比",
     left: "center",
   },
   tooltip: {
     trigger: "item",
-    formatter: "{b}: {c} MWh ({d}%)",
   },
   toolbox: {
     feature: {
       dataView: { show: true, readOnly: false },
-      // magicType: { show: true, type: ["line", "bar"] },
       restore: { show: true },
       saveAsImage: { show: true },
     },

+ 2 - 0
src/assets/js/constants/echarts-config/radar.js

@@ -8,7 +8,9 @@
  */
 // 雷达图-radar
 // 示例:不同风电场的性能评价
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风电场性能",
   },

+ 5 - 1
src/assets/js/constants/echarts-config/roseChart.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2024-11-19 16:18:07
- * @LastEditTime: 2024-11-25 09:45:34
+ * @LastEditTime: 2024-11-27 15:05:30
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/assets/js/constants/echarts-config/roseChart.js
@@ -12,7 +12,9 @@
 // 实现建议:
 // ECharts 的极坐标 + 柱状图。
 // 使用 polar 和 radiusAxis 配置。
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风速或风力分布",
   },
@@ -37,6 +39,8 @@ export const option = {
   series: [
     {
       type: "bar",
+      radius: [50, 250],
+      center: ["50%", "50%"],
       data: [15, 25, 30, 20, 10, 5, 8, 12], // 风速数据
       coordinateSystem: "polar",
       name: "风速",

+ 4 - 2
src/assets/js/constants/echarts-config/sankeyDiagram.js

@@ -1,15 +1,17 @@
 /*
  * @Author: your name
  * @Date: 2024-11-20 09:20:45
- * @LastEditTime: 2024-11-20 17:22:11
- * @LastEditors: milo-MacBook-Pro.local
+ * @LastEditTime: 2024-11-28 09:24:40
+ * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/assets/js/constants/echarts-config/sankeyDiagram.js
  */
 // 流图-sankeyDiagram
 // 示例:风能转化过程的能量流 -流图用于分析风能利用效率及能量流失情况。
 // 流图用于显示能量或资源在不同阶段的流动和分配。
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风能转化过程的能量流失情况",
   },

+ 7 - 0
src/assets/js/constants/echarts-config/scatter.js

@@ -1,4 +1,6 @@
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风速分布",
   },
@@ -33,6 +35,11 @@ export const option = {
       ], // [风向, 风速, 数据点大小]
       // symbolSize: (data) => data[2], // 根据大小调整气泡尺寸
       renderMode: "webgl", // 启用 WebGL 渲染
+      itemStyle: {
+        shadowBlur: 10,
+        shadowColor: "rgba(25, 100, 150, 0.5)",
+        shadowOffsetY: 5,
+      },
     },
   ],
   tooltip: {

+ 2 - 0
src/assets/js/constants/echarts-config/stackedBar.js

@@ -11,7 +11,9 @@
 // 适用场景:风机运行监控。
 // 实现建议:
 // 使用堆叠柱状图。
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风机状态",
   },

+ 3 - 1
src/assets/js/constants/echarts-config/timeSeries.js

@@ -1,14 +1,16 @@
 /*
  * @Author: your name
  * @Date: 2024-11-20 09:16:47
- * @LastEditTime: 2024-11-25 09:46:47
+ * @LastEditTime: 2024-11-27 15:05:51
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/assets/js/constants/echarts-config/timeSeries.js
  */
 //时间序列图 timeSeries
 //风速变化趋势
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风速变化趋势",
   },

+ 2 - 0
src/assets/js/constants/echarts-config/waterfall.js

@@ -8,7 +8,9 @@
  */
 // 瀑布图-Waterfall
 // 示例:风速到发电量的损耗分析
+import { colorPalette } from "../color";
 export const option = {
+  color: colorPalette,
   title: {
     text: "风速到发电量的损耗分析",
   },

File diff suppressed because it is too large
+ 0 - 1
src/icons/svg/Cp.svg


+ 1 - 0
src/icons/svg/Cp1.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1732600138141" class="icon" viewBox="0 0 1056 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="88507" xmlns:xlink="http://www.w3.org/1999/xlink" width="132" height="128"><path d="M48 64h64v928h-64z" fill="#59697C" p-id="88508"></path><path d="M80 928h928v64h-928z" fill="#59697C" p-id="88509"></path><path d="M208 806.4l-3.2-44.8c182.4-12.8 294.4-89.6 348.8-236.8 9.6-28.8 19.2-54.4 25.6-76.8 54.4-160 64-163.2 313.6-246.4l22.4-6.4 12.8 41.6-22.4 6.4c-240 80-240 80-284.8 217.6-6.4 22.4-16 48-25.6 76.8-57.6 166.4-188.8 256-387.2 268.8z" fill="#0070CC" p-id="88510"></path><path d="M608 736c0 54.4 41.6 96 96 96s96-41.6 96-96-41.6-96-96-96-96 41.6-96 96z" fill="#6FA8D6" p-id="88511"></path><path d="M224 608c0 35.2 28.8 64 64 64s64-28.8 64-64-28.8-64-64-64-64 28.8-64 64zM384 336c0 25.6 22.4 48 48 48s48-22.4 48-48S457.6 288 432 288s-48 22.4-48 48zM800 352c0 35.2 28.8 64 64 64s64-28.8 64-64-28.8-64-64-64-64 28.8-64 64z" fill="#B2D4EF" p-id="88512"></path></svg>

File diff suppressed because it is too large
+ 0 - 1
src/icons/svg/Heatmap.svg


+ 1 - 1
src/icons/svg/bar.svg

@@ -1 +1 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1730425074944" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="25213" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M180.906667 798.72V126.293333H105.813333v747.52l808.96 3.413334v-78.506667z" fill="#5DA1FD" p-id="25214"></path><path d="M529.066667 180.906667c0-17.066667-17.066667-30.72-30.72-30.72H477.866667c-17.066667 0-27.306667 13.653333-27.306667 27.306666V750.933333h78.506667V180.906667z" fill="#5DA1FD" p-id="25215"></path><path d="M348.16 351.573333c0-17.066667-10.24-30.72-23.893333-30.72H307.2c-17.066667 0-34.133333 17.066667-34.133333 30.72V750.933333h75.093333V351.573333zM706.56 508.586667c0-17.066667-10.24-30.72-23.893333-30.72h-17.066667c-17.066667 0-30.72 17.066667-30.72 30.72V750.933333h75.093333v-242.346666z" fill="#F87D06" p-id="25216"></path><path d="M863.573333 641.706667h-17.066666c-17.066667 0-30.72 17.066667-30.72 30.72V750.933333H887.466667v-78.506666c0-13.653333-6.826667-30.72-23.893334-30.72z" fill="#5DA1FD" p-id="25217"></path></svg>
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1732005686328" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11713" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M229.333333 341.333333v480h-160V341.333333h160z m181.333334-106.666666v586.666666h-160V234.666667h160z m362.666666 53.333333v533.333333h-160V288h160z m181.333334 138.666667v394.666666h-160V426.666667h160z" fill="#001E59" fill-opacity=".3" p-id="11714"></path><path d="M981.333333 864v32H42.666667v-32h938.666666zM592 128v693.333333h-160V128h160z" fill="#00102F" fill-opacity=".75" p-id="11715"></path></svg>

+ 1 - 0
src/icons/svg/bar1.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1730425074944" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="25213" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M180.906667 798.72V126.293333H105.813333v747.52l808.96 3.413334v-78.506667z" fill="#5DA1FD" p-id="25214"></path><path d="M529.066667 180.906667c0-17.066667-17.066667-30.72-30.72-30.72H477.866667c-17.066667 0-27.306667 13.653333-27.306667 27.306666V750.933333h78.506667V180.906667z" fill="#5DA1FD" p-id="25215"></path><path d="M348.16 351.573333c0-17.066667-10.24-30.72-23.893333-30.72H307.2c-17.066667 0-34.133333 17.066667-34.133333 30.72V750.933333h75.093333V351.573333zM706.56 508.586667c0-17.066667-10.24-30.72-23.893333-30.72h-17.066667c-17.066667 0-30.72 17.066667-30.72 30.72V750.933333h75.093333v-242.346666z" fill="#F87D06" p-id="25216"></path><path d="M863.573333 641.706667h-17.066666c-17.066667 0-30.72 17.066667-30.72 30.72V750.933333H887.466667v-78.506666c0-13.653333-6.826667-30.72-23.893334-30.72z" fill="#5DA1FD" p-id="25217"></path></svg>

File diff suppressed because it is too large
+ 0 - 0
src/icons/svg/boxPlot.svg


File diff suppressed because it is too large
+ 0 - 0
src/icons/svg/line.svg


File diff suppressed because it is too large
+ 0 - 0
src/icons/svg/pareto.svg


File diff suppressed because it is too large
+ 0 - 0
src/icons/svg/pareto1.svg


+ 1 - 1
src/icons/svg/pie.svg

@@ -1 +1 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1730425168814" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="31707" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M509.827 514.31m-449.06 0a449.06 449.06 0 1 0 898.12 0 449.06 449.06 0 1 0-898.12 0Z" fill="#E0E0D1" p-id="31708"></path><path d="M832.589 500.276c0-155.006-125.657-280.662-280.662-280.662v280.662h280.662z" fill="#231F20" p-id="31709"></path><path d="M832.589 472.21c0-155.006-125.657-280.662-280.662-280.662V472.21h280.662z" fill="#4F5D73" p-id="31710"></path><path d="M495.794 247.68c-170.506 0-308.729 138.222-308.729 308.729s138.223 308.729 308.729 308.729c79.882 0 152.677-30.341 207.493-80.125L495.794 556.409V247.68z" fill="#231F20" p-id="31711"></path><path d="M495.794 219.614c-170.506 0-308.729 138.222-308.729 308.729s138.223 308.729 308.729 308.729c79.882 0 152.677-30.341 207.493-80.125L495.794 528.343V219.614z" fill="#76C2AF" p-id="31712"></path><path d="M804.523 528.343H495.794v28.066l207.493 228.604c62.187-56.478 101.236-166.046 101.236-256.67z" fill="#231F20" p-id="31713"></path><path d="M804.523 528.343H495.794l207.493 228.604c62.187-56.478 101.236-137.98 101.236-228.604z" fill="#C75C5C" p-id="31714"></path></svg>
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1732599138661" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="59985" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M183.92 520.22l369.1 73.82V186.37C714.9 206.55 840.17 344.65 840.17 512c0 181.25-146.93 328.17-328.17 328.17-178.5 0-323.71-142.5-328.08-319.95z" fill="#2E3133" opacity=".3" p-id="59986"></path><path d="M145.28 430.45c19.97-162.13 158.17-287.65 325.7-287.65v352.79l-325.7-65.14z" fill="#2E3133" p-id="59987"></path></svg>

File diff suppressed because it is too large
+ 0 - 0
src/icons/svg/roseChart.svg


+ 1 - 0
src/icons/svg/roseChart1.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1732599077680" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="56997" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 256a256 256 0 1 0 256 256 256 256 0 0 0-256-256z m0 384a128 128 0 1 1 128-128 128 128 0 0 1-128 128z" fill="#9BA1B5" p-id="56998"></path><path d="M768 320l-153.6 115.84A128 128 0 0 1 640 512a128 128 0 0 1-37.44 90.56l135.68 135.68A320 320 0 0 0 768 320z" fill="#C0C5D3" p-id="56999"></path><path d="M602.56 602.56a128 128 0 0 1-181.12 0l-181.12 181.12a384 384 0 0 0 544 0z" fill="#9BA1B5" p-id="57000"></path><path d="M384 512a128 128 0 0 1 128-128V64a448 448 0 0 0-316.8 764.8l226.24-226.24A128 128 0 0 1 384 512z" fill="#C0C5D3" p-id="57001"></path></svg>

File diff suppressed because it is too large
+ 0 - 0
src/icons/svg/sankeyDiagram.svg


File diff suppressed because it is too large
+ 0 - 0
src/icons/svg/scatter.svg


File diff suppressed because it is too large
+ 0 - 0
src/icons/svg/stackedBar.svg


+ 1 - 1
src/icons/svg/waterfall.svg

@@ -1 +1 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1732066795849" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="40610" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M623.995259 111.995259h99.991704v497.000297h-99.991704z" fill="#0BCC93" p-id="40611"></path><path d="M247.99763 288.995556h99.991703v491.008h-99.991703z" fill="#4ABCFA" p-id="40612"></path><path d="M811.994074 111.009185h99.991704v355.991704H811.994074z" fill="#9387FD" p-id="40613"></path><path d="M435.996444 288.995556h99.991704v283.003259h-99.991704z" fill="#3B64E9" p-id="40614"></path><path d="M152.007111 111.995259v759.99763h759.99763v40.011852H111.995259V111.995259z" fill="#D1DDF8" p-id="40615"></path></svg>
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1732599712541" class="icon" viewBox="0 0 1536 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="73266" width="192" height="128" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M0 960h1536v64H0z" fill="#5182E4" fill-opacity=".3" p-id="73267"></path><path d="M128 192h192v704H128V192z m640 320V0h192v512h-192z" fill="#5182E4" p-id="73268"></path><path d="M448 512V192h192v320H448z m768-512h192v896h-192V0z" fill="#5182E4" fill-opacity=".504" p-id="73269"></path></svg>

+ 11 - 4
src/main.js

@@ -32,10 +32,8 @@ Vue.prototype.$qs = qs;
 // Vue.prototype.$tinymce = tinymce;
 
 // dialog拖拽全屏
-import dialogDrag from './views/health/dialogDrag';
-Vue.directive('dialogDrag', dialogDrag);
-
-
+import dialogDrag from "./views/health/dialogDrag";
+Vue.directive("dialogDrag", dialogDrag);
 
 Vue.use(ElementUI);
 // 引入tailwind
@@ -71,8 +69,17 @@ Vue.prototype.$formatDateTWO = function (timestamp) {
   // const seconds = String(date.getSeconds()).padStart(2, "0");:${seconds}
   return `${year}-${month}-${day} ${hours}:${minutes}`;
 };
+
+// 路由导航守卫
+router.beforeEach((to, from, next) => {
+  if (from.path === "/home/performance/customAnalysis") {
+    store.commit("dragChart/clearchart");
+  }
+  next();
+});
 // 监听页面刷新或关闭事件
 window.addEventListener("beforeunload", () => {
+  console.log("调用了dragChart/clearchart");
   // 调用清空 Vuex 仓库的 Action
   store.commit("dragChart/clearchart");
 });

+ 14 - 20
src/store/dragChart.js

@@ -1,6 +1,10 @@
 import { SCALE } from "@/assets/js/constants/config.js";
 import { Message } from "element-ui";
-import { clearAllDataFromIndexedDB } from "@/utils/indexedDb";
+import {
+  clearAllDataFromIndexedDB,
+  clearMyIndexedDBIndexedDB,
+} from "@/utils/indexedDb";
+
 const _ = require("lodash");
 
 export default {
@@ -14,7 +18,6 @@ export default {
     originChartList: [], // 当前文件的原始数据
     fileList: [], // 文件列表
     dataBaseCheckList: [], //选中数据更新
-    // formFilterAlignData: [], //这个是所有图表数据筛选保存字段
   },
   mutations: {
     setUpdateTriggerGetData(state, value) {
@@ -24,7 +27,6 @@ export default {
       state.triggerGetData = value;
     },
     setRelatedFieldsData(state, data) {
-      console.log(data);
       state.relatedFieldsData = [...state.relatedFieldsData, { ...data }];
     },
     // 清空图表
@@ -42,7 +44,8 @@ export default {
         formFilterAlign: [],
       };
       //清空indexeddb 数据库
-      // clearAllDataFromIndexedDB();
+      clearAllDataFromIndexedDB();
+      clearMyIndexedDBIndexedDB();
       // 遍历重置每个字段
       Object.keys(resetState).forEach((key) => {
         state[key] = resetState[key];
@@ -52,18 +55,11 @@ export default {
     setFormFilterAlignData(state, data) {
       //将数据存储起来用于回显 数据
       // 检查是否已经存在相同的 id
-      const index = state.curEdit.formFilterAlignData.findIndex(
-        (item) => item.id === data.id
-      );
-      if (index !== -1) {
-        // 如果找到相同的 id,直接更新
-        state.curEdit.formFilterAlignData[index] = {
-          ...data,
-        };
-      } else {
-        // 如果不存在,新增一条数据
-        state.curEdit.formFilterAlignData.push({ ...data });
-      }
+      state.currentChartList?.map((chartItem, ind) => {
+        if (chartItem.id === data.id) {
+          state.currentChartList[ind].formFilterAlignData = data.data;
+        }
+      });
     },
     // 设置当前编辑的图表
     setCurEdit(state, data) {
@@ -81,12 +77,12 @@ export default {
     },
     //更新数据配置当前选中数据
     updateDataBase(state, data) {
-      //   console.log("更改了图表数据", data);
+      // console.log("更改了图表数据", data);
       state.dataBaseCheckList = data;
     },
     // 更新图表
     updateChart(state, data) {
-      //   console.log("更改了图表组件", data.index, data);
+      // console.log("更改了图表组件", data.index, data);
       if (state.currentChartList[data.index]) {
         state.currentChartList[data.index] = Object.assign(
           state.currentChartList[data.index],
@@ -119,7 +115,6 @@ export default {
     fileListUpdate(state, item) {
       state.fileList = _.cloneDeep(item);
     },
-
     // 记录当前文件的原始数据
     recordOriginChartList(state, id) {
       const fileList = state.fileList;
@@ -130,7 +125,6 @@ export default {
         state.originChartList = {};
       }
     },
-
     // 还原当前文件的原始数据
     restoreOriginChartList(state, id) {
       const fileList = state.fileList;

+ 9 - 0
src/store/index.js

@@ -7,6 +7,7 @@ import settings from "./settings.js";
 import themes from "./themes.js";
 import menuTag from "./menuTag.js";
 import dragChart from "./dragChart.js";
+import vuexIndexedDBPlugin from "@/utils/vuexIndexedDBPlugin";
 Vue.use(Vuex);
 export const store = new Vuex.Store({
   state: {
@@ -42,6 +43,14 @@ export const store = new Vuex.Store({
   plugins: [
     createPersistedState({
       storage: window.sessionStorage, // 或者 localStorage
+      paths: [
+        "breadStore",
+        "auth",
+        "settings",
+        "themes",
+        "menuTag", // 指定需要存储的模块,排除 dragChart
+      ],
     }),
+    vuexIndexedDBPlugin,
   ],
 });

+ 69 - 2
src/utils/indexedDb.js

@@ -93,7 +93,7 @@ export async function getDataFromIndexedDB() {
   });
 }
 
-// 清除整个对象存储
+// 清除 FileDataDB整个对象存储
 export async function clearAllDataFromIndexedDB() {
   return new Promise((resolve, reject) => {
     const versionRequest = indexedDB.open("FileDataDB");
@@ -140,7 +140,6 @@ export async function clearAllDataFromIndexedDB() {
         reject(event.target.error);
       };
     };
-
     versionRequest.onerror = (event) => {
       console.error("Failed to retrieve database version:", event.target.error);
       reject(event.target.error);
@@ -148,6 +147,38 @@ export async function clearAllDataFromIndexedDB() {
   });
 }
 
+// 清除 myIndexedDB整个对象存储
+
+export const clearMyIndexedDBIndexedDB = () => {
+  const dbName = "myIndexedDB";
+
+  const request = indexedDB.open(dbName);
+
+  request.onsuccess = (event) => {
+    const db = event.target.result;
+
+    const transaction = db.transaction(db.objectStoreNames, "readwrite");
+
+    for (const storeName of db.objectStoreNames) {
+      if (storeName.startsWith("vuexData")) {
+        const objectStore = transaction.objectStore(storeName);
+        objectStore.clear().onsuccess = () => {
+          console.log(`Cleared all data in ${storeName}`);
+        };
+      }
+    }
+
+    transaction.oncomplete = () => {
+      console.log("All vuexData tables cleared.");
+      db.close();
+    };
+  };
+
+  request.onerror = (event) => {
+    console.error("Failed to open IndexedDB:", event.target.error);
+  };
+};
+
 //往indexedDB 某一个表里添加一条数据
 export async function storeSetData(db, storeName, key, newFileData, callback) {
   if (!db) {
@@ -214,3 +245,39 @@ export async function storeSetData(db, storeName, key, newFileData, callback) {
 //     console.error("从IndexedDB检索数据时出错:", event.target.error);
 //   };
 // }
+// utils/indexedDb.js
+export async function openDB(dbName, version) {
+  return new Promise((resolve, reject) => {
+    const request = indexedDB.open(dbName, version);
+    request.onsuccess = () => resolve(request.result);
+    request.onerror = (event) => reject(event.target.error);
+    request.onupgradeneeded = (event) => {
+      const db = event.target.result;
+      if (!db.objectStoreNames.contains("vuexData")) {
+        db.createObjectStore("vuexData", { keyPath: "key" });
+      }
+    };
+  });
+}
+
+export async function saveData(dbName, key, value) {
+  const db = await openDB(dbName, 1);
+  return new Promise((resolve, reject) => {
+    const transaction = db.transaction(["vuexData"], "readwrite");
+    const store = transaction.objectStore("vuexData");
+    const request = store.put({ key, value });
+    request.onsuccess = () => resolve(true);
+    request.onerror = (event) => reject(event.target.error);
+  });
+}
+
+export async function getData(dbName, key) {
+  const db = await openDB(dbName, 1);
+  return new Promise((resolve, reject) => {
+    const transaction = db.transaction(["vuexData"], "readonly");
+    const store = transaction.objectStore("vuexData");
+    const request = store.get(key);
+    request.onsuccess = () => resolve(request.result?.value || null);
+    request.onerror = (event) => reject(event.target.error);
+  });
+}

+ 105 - 0
src/utils/vuexIndexedDBPlugin.js

@@ -0,0 +1,105 @@
+import { saveData, getData, openDB } from "@/utils/indexedDb";
+import { stringify, parse } from "flatted"; // 用于处理循环引用
+import pako from "pako";
+import { Message } from "element-ui";
+// 通用分片函数
+const splitIntoChunks = (data, chunkSize) => {
+  const chunks = [];
+  for (let i = 0; i < data.length; i += chunkSize) {
+    chunks.push(data.slice(i, i + chunkSize));
+  }
+  return chunks;
+};
+const vuexIndexedDBPlugin = (store) => {
+  const dbName = "vuexDB";
+  const keyName = "vuexState";
+
+  // 过滤 Vuex 状态,去掉不可序列化的部分
+  const filterState = (state) => {
+    const clonedState = JSON.parse(
+      JSON.stringify(state, (key, value) => {
+        // 如果是函数或无法克隆的对象,返回 undefined
+        if (typeof value === "function") return undefined;
+        return value;
+      })
+    );
+    return clonedState;
+  };
+
+  // 初始化 IndexedDB 并加载状态
+  openDB(dbName, 1).then(() => {
+    getData(dbName, keyName).then((savedState) => {
+      if (savedState) {
+        store.replaceState({
+          ...store.state,
+          ...savedState,
+        });
+        console.log("Vuex state loaded from IndexedDB");
+      }
+    });
+  });
+
+  // 订阅 Vuex mutations,每次状态变更时保存到 IndexedDB
+  store.subscribe((mutation, state) => {
+    if (mutation.type.startsWith("dragChart/")) {
+      const dragChartState = state.dragChart;
+
+      try {
+        const cleanedState = JSON.parse(
+          JSON.stringify(dragChartState, (key, value) => {
+            if (
+              typeof value === "function" ||
+              value instanceof HTMLElement ||
+              value === undefined
+            ) {
+              return undefined;
+            }
+            return value;
+          })
+        );
+
+        // 压缩或分片存储
+        const chunkSize = 500;
+        if (
+          cleanedState.currentChartList &&
+          Array.isArray(cleanedState.currentChartList)
+        ) {
+          const chunks = splitIntoChunks(
+            cleanedState.currentChartList,
+            chunkSize
+          );
+          chunks.forEach((chunk, index) => {
+            const chunkKey = `dragChart_chunk_${index}`;
+            saveData("myIndexedDB", chunkKey, chunk)
+              .then(() => console.log(`Chunk ${index} saved successfully`))
+              .catch((error) =>
+                console.error(`Failed to save chunk ${index}:`, error)
+              );
+          });
+
+          saveData("myIndexedDB", "dragChart_chunk_meta", {
+            totalChunks: chunks.length,
+          });
+        }
+
+        // 存储压缩的元数据
+        const compressedData = pako.deflate(stringify(cleanedState), {
+          to: "string",
+        });
+        saveData("myIndexedDB", "dragChart_compressed", compressedData)
+          .then(() => console.log("Compressed metadata saved"))
+          .catch((error) =>
+            console.error("Failed to save compressed metadata:", error)
+          );
+      } catch (error) {
+        console.error("Error processing dragChart state:", error);
+        Message({
+          message: "数据存储已满,请刷新页面进行数据清除" + error,
+          type: "error",
+        });
+      }
+    }
+  });
+};
+
+export default vuexIndexedDBPlugin;

+ 169 - 239
src/views/dataAdministration/vibration/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-11-25 09:28:47
- * @LastEditTime: 2024-11-25 09:33:01
+ * @LastEditTime: 2024-12-06 16:12:50
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/dataAdministration/vibration/index.vue
@@ -15,7 +15,6 @@
         ref="ruleForm"
         :model="formInline"
         class="demo-form-inline"
-        :rules="rules"
       >
         <el-form-item label="风场名称:" prop="fieldName">
           <el-input
@@ -24,23 +23,19 @@
             placeholder="请输入风场名称"
           ></el-input>
         </el-form-item>
-        <el-form-item label="状态:" prop="batchState" size="small">
-          <el-select v-model="formInline.batchState" placeholder="请选择状态">
-            <el-option label="启用" value="1"></el-option>
-            <el-option label="停用" value="0"></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="创建时间">
-          <el-date-picker
+        <el-form-item label="状态:">
+          <el-select
             size="small"
-            v-model="formInline.picker"
-            type="daterange"
-            range-separator="至"
-            start-placeholder="开始日期"
-            end-placeholder="结束日期"
-            @change="onDateChange"
+            v-model="formInline.transferStatus"
+            placeholder="请选择状态"
+            style="width: 100%"
           >
-          </el-date-picker>
+            <el-option
+              :label="item.label"
+              v-for="item in StateCodeList"
+              :value="item.value"
+            ></el-option>
+          </el-select>
         </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="onSubmit" size="small"
@@ -71,21 +66,25 @@
           prop="fieldName"
           align="center"
           min-width="100"
-          label="关联风场"
+          label="风场名称"
         >
         </el-table-column>
         <el-table-column
           align="center"
           min-width="100"
-          label="批次名称"
-          prop="batchName"
+          label="转换路径"
+          prop="transferAddr"
+        >
+        </el-table-column>
+        <el-table-column
+          align="center"
+          min-width="100"
+          label="进度"
+          prop="transferProgress"
         >
         </el-table-column>
-        <!-- <el-table-column align="center" label="批次编号" prop="batchCode">
-          </el-table-column> -->
-
         <el-table-column
-          prop="batchState"
+          prop="transferStatus"
           align="center"
           label="状态"
           min-width="100"
@@ -93,20 +92,39 @@
           <template slot-scope="scope">
             <span>
               {{
-                scope.row.batchState == 0
-                  ? "禁用"
-                  : scope.row.batchState == 1
-                  ? "启用"
+                scope.row.transferStatus == 0
+                  ? "转换中"
+                  : scope.row.transferStatus == 1
+                  ? "转换完成"
+                  : scope.row.transferStatus == 2
+                  ? "转换异常"
+                  : scope.row.transferStatus == -1
+                  ? "未转换"
                   : "/"
               }}</span
             >
           </template>
         </el-table-column>
+
+        <el-table-column
+          align="center"
+          min-width="100"
+          label="异常信息"
+          prop="errInfo"
+        >
+        </el-table-column>
+        <el-table-column
+          prop="transferStartTime"
+          align="center"
+          min-width="150"
+          label="开始时间"
+        >
+        </el-table-column>
         <el-table-column
-          prop="createTime"
+          prop="transferEndTime"
           align="center"
           min-width="150"
-          label="创建时间"
+          label="结束时间"
         >
         </el-table-column>
         <el-table-column
@@ -116,40 +134,27 @@
           label="操作"
           min-width="200"
         >
+          <!-- v-hasPermi="['dataAdministration:vibration:conversion']" -->
           <template slot-scope="scope">
             <el-button
-              v-hasPermi="['performance:batchMag:edit']"
-              @click="compile(scope.row)"
+              v-if="scope.row.transferStatus === -1"
+              @click="conversion(scope.row, 0)"
               type="text"
               size="small"
-              >编辑</el-button
+              >转换</el-button
             >
+            <!-- v-hasPermi="['dataAdministration:vibration:reconversion']" -->
             <el-button
-              v-hasPermi="['performance:batchMag:editState']"
-              v-if="scope.row.batchState == 0"
-              @click="setState(1, scope.row)"
+              v-if="
+                scope.row.transferStatus === 0 ||
+                scope.row.transferStatus === 1 ||
+                scope.row.transferStatus === 2
+              "
+              @click="conversion(scope.row, 1)"
               type="text"
               size="small"
-              >启用</el-button
-            >
-            <el-button
-              v-else
-              v-hasPermi="['performance:batchMag:editState']"
-              style="color: #666"
-              @click="setState(0, scope.row)"
-              type="text"
-              size="small"
-              >禁用</el-button
-            >
-
-            <el-button
-              style="color: #f00"
-              @click="deleted(scope.row)"
-              v-hasPermi="['performance:batchMag:delete']"
-              type="text"
-              size="small"
-              :disabled="scope.row.batchState == 1"
-              >删除</el-button
+              :disabled="scope.row.transferStatus == 0"
+              >重新转换</el-button
             >
           </template>
         </el-table-column>
@@ -182,11 +187,11 @@
           label-width="100px"
           class="demo-ruleForm"
         >
-          <el-form-item label="关联风场:" prop="fieldCode">
+          <el-form-item label="风场:" prop="fieldCode">
             <el-select
-              :disabled="title === '编辑'"
               v-model="ruleForm.fieldCode"
-              placeholder="请选择关联风场"
+              placeholder="请选择风场"
+              :disabled="title !== '新增'"
               style="width: 100%"
             >
               <el-option
@@ -196,14 +201,10 @@
               ></el-option>
             </el-select>
           </el-form-item>
-          <el-form-item
-            label="批次名称"
-            prop="batchName"
-            v-if="title === '编辑'"
-          >
+          <el-form-item label="转换路径" prop="transferAddr">
             <el-input
-              v-model="ruleForm.batchName"
-              placeholder="请输入批次名称"
+              v-model="ruleForm.transferAddr"
+              placeholder="请输入转换路径"
             ></el-input>
           </el-form-item>
         </el-form>
@@ -225,61 +226,63 @@
 </template>
 
 <script>
+import { updateFieldBatch, queryCodeNum } from "@/api/performance.js";
 import {
-  getBatchMagList,
-  addFieldBatch,
-  updateFieldBatch,
-  queryCodeNum,
-  onOrOffFieldBatch,
-  deleteFieldBatch,
-  createBatchName,
-} from "@/api/performance.js";
+  getDataTransfer,
+  addDataTransfer,
+  DataTransfer,
+} from "@/api/dataManage.js";
+
 export default {
   data() {
     return {
       loadingView: false,
       loading: false, //数据加载中
-      rules: {
-        fieldCode: { trigger: "change" },
-        batchState: { trigger: "blur" },
-      },
-      startDate: "",
-      endDate: "",
       fieldCodeList: [],
+      StateCodeList: [
+        {
+          label: "未转换",
+          value: -1,
+        },
+        {
+          label: "转换中",
+          value: 0,
+        },
+        {
+          label: "转换完成",
+          value: 1,
+        },
+        {
+          label: "转换异常",
+          value: 2,
+        },
+      ],
       formInline: {
-        fieldName: undefined,
-        batchState: undefined,
-        picker: [],
         pageNum: 1,
         pageSize: 10,
-        totalSize: 0,
+        transferType: 1,
+        fieldName: "",
+        transferStatus: "",
       },
       tableData: [],
       // 新增编辑表单
       ruleForm: {
         fieldCode: null,
-        batchName: null,
-        batchCode: null,
+        transferAddr: null,
       },
       addUserRules: {
-        batchCode: {
+        fieldCode: {
           required: true,
-          message: "请选择关联风场",
+          message: "请选择风场",
           trigger: "change",
         },
-        batchName: [
-          { required: true, message: "请输入批次名称", trigger: "blur" },
+        transferAddr: [
+          { required: true, message: "请输入转换路径", trigger: "blur" },
         ],
       },
-      //修改密码
-      editUserPassword: {
-        oldPWD: "",
-        newPWD: "",
-        userId: "",
-      },
-
       nuedialog: false,
       title: "",
+      id: "",
     };
   },
   created() {
@@ -288,6 +291,21 @@ export default {
   },
 
   methods: {
+    //转换重新转换
+    conversion(row, retransfer) {
+      try {
+        // 直接替换整个对象,以确保 Vue 的响应式系统能够检测到变化
+        this.ruleForm = {
+          fieldCode: row.fieldCode,
+          transferAddr: row.transferAddr,
+        };
+        this.id = row.id;
+        this.nuedialog = true;
+        this.title = retransfer === 0 ? "转换" : "重新转换";
+      } catch (error) {
+        this.$message.error("获取用户信息失败");
+      }
+    },
     handleCloses(done) {
       this.$confirm("确认关闭?")
         .then((_) => {
@@ -295,18 +313,7 @@ export default {
         })
         .catch((_) => {});
     },
-    onDateChange(date) {
-      if (Array.isArray(date)) {
-        this.startDate = this.$formatDate(date[0]);
-        this.endDate = this.$formatDate(date[1]);
-        if (this.endDate < this.startDate) {
-          this.endDate = this.startDate;
-        }
-      } else {
-        this.startDate = null;
-        this.endDate = null;
-      }
-    },
+
     //获取风场列表
     async getQueryCodeNumList() {
       this.loading = true;
@@ -324,32 +331,20 @@ export default {
       this.formInline.pageNum = val;
       this.getTableList();
     },
-    //修改状态
-    setState(state, row) {
-      //启用接口
-      this.loading = true;
-      onOrOffFieldBatch({ batchCode: row.batchCode, batchState: state })
-        .then((res) => {
-          this.$message({
-            message: res.msg,
-            type: "success",
-          });
-          this.loading = false;
-          this.getTableList();
-        })
-        .catch((error) => {
-          this.loading = false;
-        });
-    },
+
     async getTableList() {
       try {
         this.loading = true;
-        const result = await getBatchMagList({
+        const result = await getDataTransfer({
           ...this.formInline,
-          picker: undefined,
-          startTime: this.startDate || undefined,
-          endTime: this.endDate || undefined,
-          totalSize: undefined,
+          transferStatus:
+            this.formInline.transferStatus === ""
+              ? undefined
+              : this.formInline.transferStatus,
+          fieldName:
+            this.formInline.fieldName === ""
+              ? undefined
+              : this.formInline.fieldName,
         });
         this.tableData = result.data.list;
         this.formInline.totalSize = result.data.totalSize;
@@ -369,135 +364,70 @@ export default {
     onSubmit() {
       this.getTableList();
     },
-    // 重置
-    reset(formName) {
-      this.formInline.picker = [];
-      this.startDate = undefined;
-      this.endDate = undefined;
-      this.$refs[formName].resetFields();
-      this.getTableList();
-    },
 
     // 新增,编辑确定
     submitForm(formName) {
-      // this.loading = true;
-      this.$refs[formName].validate((valid) => {
-        if (valid) {
-          this.loadingView = true;
-          switch (this.title) {
-            case "新增":
-              const obj = this.fieldCodeList.find(
-                (item) => item.codeNumber === this.ruleForm.fieldCode
-              );
-              const form = new FormData();
-              form.append("fieldName", obj.fieldName);
-              createBatchName(form).then((results) => {
-                addFieldBatch({
-                  ...this.ruleForm,
-                  batchName: results.data,
-                  batchCode: undefined,
-                })
-                  .then((res) => {
-                    this.$message({
-                      type: "success",
-                      message: res.msg,
-                    });
-                    // this.loading = false;
-                    this.getTableList();
-                    this.nuedialog = false;
-                    this.loadingView = false;
-                  })
-                  .catch(() => {
-                    this.loadingView = false;
-                    // this.loading = false;
-                  });
-              });
-
-              break;
-            case "编辑":
-              updateFieldBatch({ ...this.ruleForm, fieldCode: undefined })
-                .then((res) => {
-                  this.$message({
-                    type: "success",
-                    message: res.msg,
-                  });
-                  this.getTableList();
-                  this.nuedialog = false;
-                  this.loadingView = false;
-                })
-                .catch(() => {
-                  this.loadingView = false;
-                });
-
-              break;
+      this.$refs[formName].validate(async (valid) => {
+        if (!valid) return false;
+        this.loadingView = true;
+        // 定义处理逻辑的映射
+        const actionMap = {
+          新增: () => addDataTransfer({ transferType: "1", ...this.ruleForm }),
+          转换: () =>
+            DataTransfer({
+              id: this.id,
+              retransfer: 0,
+              transferAddr: this.ruleForm.transferAddr,
+            }),
+          重新转换: () =>
+            DataTransfer({
+              id: this.id,
+              retransfer: 1,
+              transferAddr: this.ruleForm.transferAddr,
+            }),
+        };
+        try {
+          // 执行对应的操作
+          const response = await actionMap[this.title]?.();
+          if (response) {
+            this.$message({
+              type: "success",
+              message: response.msg,
+            });
+            this.getTableList();
+            this.nuedialog = false;
           }
-          // this.nuedialog = false;
-        } else {
-          return false;
+        } catch (error) {
+          console.error("操作失败:", error);
+          this.$message.error(error?.msg || "操作失败,请稍后重试。");
+        } finally {
+          this.loadingView = false;
         }
       });
     },
+
     //点击取消
     cancel(formName) {
       this.$refs[formName] && this.$refs[formName].resetFields();
       this.ruleForm = {
         fieldCode: null,
-        batchCode: null,
-        batchName: null,
+        transferAddr: null,
       };
       this.nuedialog = false;
       this.loadingView = false;
     },
-    // 编辑 回显数据
-    async compile(row) {
-      try {
-        // 直接替换整个对象,以确保 Vue 的响应式系统能够检测到变化
-        this.ruleForm = {
-          fieldCode: row.fieldCode,
-          batchCode: row.batchCode,
-          batchName: row.batchName,
-        };
-        this.nuedialog = true;
-        this.title = "编辑";
-      } catch (error) {
-        this.$message.error("获取用户信息失败");
-      }
-    },
-    // 删除
-    deleted(row) {
-      this.$confirm("此操作将永久删除该用户, 是否继续?", "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning",
-      })
-        .then(() => {
-          this.loading = true;
-          deleteFieldBatch({ batchCode: row.batchCode })
-            .then((res) => {
-              this.$message({
-                type: "success",
-                message: "删除成功!",
-              });
-              this.loading = false;
-              this.getTableList();
-            })
-            .catch(() => {
-              this.loading = false;
-            });
-        })
-        .catch(() => {
-          this.$message({
-            type: "info",
-            message: "已取消删除",
-          });
-        });
+    reset() {
+      this.formInline = {
+        fieldName: "",
+        transferStatus: "",
+      };
+      this.getTableList();
     },
     // 新增
     newnuedialog() {
       this.cancel("addUserForm");
       this.ruleForm = {
-        batchCode: "",
-        batchName: "",
+        transferAddr: "",
         fieldCode: "",
       };
       this.nuedialog = true;

+ 0 - 1
src/views/performance/components/custonAsCom/AssociatedFields.vue

@@ -267,7 +267,6 @@ export default {
             this.formSelection1[0].fileData.length <= 0 ||
             this.formSelection2[0].fileData.length <= 0
           ) {
-            console.log("sssss", this.formSelection1, this.formSelection2);
             this.$message({
               type: "warning",
               message: `至少需要关联1组字段。`,

+ 136 - 96
src/views/performance/components/custonAsCom/DatabaseTable.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-10-28 17:43:21
- * @LastEditTime: 2024-11-06 14:05:23
+ * @LastEditTime: 2024-12-06 14:11:30
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/custonAsCom/DatabaseTable.vue
@@ -57,24 +57,30 @@
         width="550px"
         :before-close="handleClose"
       >
-        <el-input placeholder="输入关键字进行过滤" v-model="filterText">
-        </el-input>
+        <el-input
+          placeholder="输入关键字进行过滤"
+          v-model="filterText"
+        ></el-input>
         <el-tree
           class="filter-tree"
-          :data="data"
+          :data="treeData"
+          show-checkbox
           :props="defaultProps"
-          default-expand-all
+          :check-strictly="false"
           :filter-node-method="filterNode"
           ref="tree"
-          :render-content="renderContent"
         >
+          <!-- :check-strictly="false"
+          :render-content="renderContent" -->
         </el-tree>
         <el-row type="flex" class="row-bg" justify="space-between">
           <el-col :span="4">
-            <el-button size="small" @click="">选择相关表</el-button>
+            <el-button size="small" @click="handleClose">取消</el-button>
           </el-col>
           <el-col :span="4">
-            <el-button size="small" type="primary" @click="">加载</el-button>
+            <el-button size="small" type="primary" @click="loadData"
+              >加载</el-button
+            >
           </el-col>
         </el-row>
       </el-dialog>
@@ -82,6 +88,9 @@
   </div>
 </template>
 <script>
+import axios from "axios";
+import { storeSetData, initDatabase } from "@/utils/indexedDb";
+import { mapMutations, mapState } from "vuex";
 export default {
   props: {
     dialogVisible: {
@@ -118,65 +127,28 @@ export default {
         children: "children",
         label: "label",
       },
+      // 转换后的树数据
+      treeData: [],
       filterText: "", // 初始化 filterText
-      data: [
-        {
-          id: 1,
-          label: "一级 1",
-          children: [
-            {
-              id: 4,
-              label: "二级 1-1",
-              children: [
-                {
-                  id: 9,
-                  label: "三级 1-1-1",
-                },
-                {
-                  id: 10,
-                  label: "三级 1-1-2",
-                },
-              ],
-            },
-          ],
-        },
-        {
-          id: 2,
-          label: "一级 2",
-          children: [
-            {
-              id: 5,
-              label: "二级 2-1",
-            },
-            {
-              id: 6,
-              label: "二级 2-2",
-            },
-          ],
-        },
-        {
-          id: 3,
-          label: "一级 3",
-          children: [
-            {
-              id: 7,
-              label: "二级 3-1",
-            },
-            {
-              id: 8,
-              label: "二级 3-2",
-            },
-          ],
-        },
-      ],
+      data: [],
     };
   },
+  computed: {
+    ...mapState("dragChart", {
+      updateTriggerGetData: "updateTriggerGetData",
+      triggerGetData: "triggerGetData",
+    }),
+  },
   watch: {
     filterText(val) {
       this.$refs.tree.filter(val);
     },
   },
   methods: {
+    ...mapMutations("dragChart", [
+      "setTriggerGetData",
+      "setUpdateTriggerGetData",
+    ]),
     handleClose(done) {
       this.$confirm("确认关闭?")
         .then((_) => {
@@ -186,53 +158,117 @@ export default {
         })
         .catch((_) => {});
     },
+    // 将原始数据转化为树形数据
+    initializeTreeData(data) {
+      // 构建树结构
+      this.treeData = Object.keys(data).map((tableName) => ({
+        label: tableName,
+        children: data[tableName].map((field) => ({
+          label: field,
+          field: field,
+          parentNode: tableName,
+        })),
+      }));
+    },
+    // 节点过滤方法
     filterNode(value, data) {
-      if (!value) return true;
-      return data.label.indexOf(value) !== -1;
+      if (!value) return true; // 如果没有输入过滤文本,则显示所有节点
+      return data.label.indexOf(value) !== -1; // 如果节点的label包含过滤文本,则返回true
     },
-    renderContent(h, { node, data }) {
-      return h("span", [
-        // 检查是否为子节点,如果是,则显示 checkbox
-        node.level > 1
-          ? h("el-checkbox", {
-              props: {
-                value: node.checked,
-                // disabled: node.disabled,
-              },
-              on: {
-                change: (val) => {
-                  this.$refs.tree.setChecked(node, val);
-                },
-              },
-            })
-          : null, // 父节点不显示 checkbox
-
-        node.level > 1
-          ? h("svg-icon", {
-              props: {
-                "icon-class": "database1", // 设置自定义组件的属性
-              },
-              style: { margin: "0 10px" }, // 设置边距
-            })
-          : h("svg-icon", {
-              props: {
-                "icon-class": "dicfiles", // 设置自定义组件的属性
-              },
-              style: { margin: "0 10px" }, // 设置边距
-            }),
-        h("span", data.label),
-      ]);
+    // 加载按钮的点击事件
+    async loadData() {
+      const selectedNodes = this.$refs.tree.getCheckedNodes();
+      if (selectedNodes.length <= 0) {
+        this.$message.warning("请最少选择1表数据");
+        return;
+      }
+      const output = [];
+      // 使用 Map 分组数据
+      const grouped = new Map();
+      selectedNodes.forEach((item) => {
+        const { parentNode, label } = item;
+        if (!grouped.has(parentNode)) {
+          grouped.set(parentNode, []);
+        }
+        grouped.get(parentNode).push(label);
+      });
+      // 转换为目标结构
+      grouped.forEach((checkChildNode, parentNode) => {
+        output.push({ parentNode, checkChildNode });
+      });
+      const response = await axios.post("/databaseApi/filterTablesData", {
+        database: { ...this.formLabelAlign },
+        filterData: output,
+      });
+      this.conversionData(response.data);
     },
     submitForm(formName) {
-      this.$refs[formName].validate((valid) => {
+      this.$refs[formName].validate(async (valid) => {
         if (valid) {
-          this.$emit("closeDialog");
-          this.showDialog = true;
+          try {
+            const response = await axios.get("/databaseApi/tables", {
+              params: { ...this.formLabelAlign },
+            });
+            // this.tableFieldMap = response.data;
+            this.initializeTreeData(response.data);
+            this.$emit("closeDialog");
+            this.showDialog = true;
+          } catch (error) {
+            this.$message.error(
+              "数据库连接失败,请查看填写的数据库数据是否有误" + error
+            );
+            console.error("Failed to fetch database structure:", error);
+          }
         } else {
           return false;
         }
       });
     },
+    async conversionData(data) {
+      try {
+        // 定义最终结果数组
+        const result = Object.keys(data)
+          .filter((key) => data[key].length > 0) // 过滤掉空数组的字段
+          .map((key) => ({
+            fileData: data[key],
+            fileId: `${new Date().getTime()}_${key}`, // 添加唯一时间戳和字段标识
+            fileOldName: `${key}.xlsx`, // 文件原始名称
+            filename: `${new Date().getTime()}_${key}.xlsx`, // 包含时间戳的文件名
+          }));
+        // 初始化数据库
+        const database = await initDatabase();
+        // 遍历结果并存储数据
+        for (const item of result) {
+          await storeSetData(database, "files", "fileDataArray", item, () => {
+            this.$message({
+              type: "success",
+              message: `关联完成,关联表可在数据表格中查看。`,
+            });
+          });
+        }
+
+        // 更新状态和关闭对话框
+        //更新数据表格数据和自定义图表树形列表
+        this.setTriggerGetData(true);
+        this.setUpdateTriggerGetData(true);
+        this.showDialog = false;
+
+        // 重置表单
+        this.formLabelAlign = {
+          IP: "",
+          host: "",
+          baseName: "",
+          username: "",
+          password: "",
+        };
+      } catch (error) {
+        console.error("操作失败:", error);
+        this.$message({
+          type: "error",
+          message: "操作失败,详情请查看控制台。",
+        });
+      }
+    },
   },
 };
 </script>
@@ -241,6 +277,10 @@ export default {
   margin-bottom: 18px;
 }
 .row-bg {
-  margin-top: 50px;
+  margin-top: 30px;
+}
+.el-tree {
+  height: 350px;
+  overflow: scroll;
 }
 </style>

+ 1 - 3
src/views/performance/components/custonAsCom/dataTable.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-10-28 16:46:38
- * @LastEditTime: 2024-11-15 09:59:57
+ * @LastEditTime: 2024-12-05 15:27:24
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dataTable.vue
@@ -109,10 +109,8 @@ export default {
     ...mapMutations("dragChart", ["setTriggerGetData"]),
     async getIndexDbData() {
       // this.loading = true;
-      console.log("触发了这个事件");
       const jsonData = await getDataFromIndexedDB();
       this.tabData = jsonData;
-      console.log(jsonData, "jsonData dataTable");
       this.activeName =
         jsonData &&
         jsonData[0] &&

+ 15 - 2
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/index.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2024-11-20 11:18:08
- * @LastEditTime: 2024-11-21 15:41:37
+ * @LastEditTime: 2024-11-28 11:07:41
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/utils/chartLogic/index.js
@@ -11,10 +11,23 @@ import { handleBarChartLogic } from "./modules/barAndLine";
 import { handleScatterChartLogic } from "./modules/scatter";
 import { handleRadarChartLogic } from "./modules/radar";
 import { handleCpChartLogic } from "./modules/cp";
-
+import { handlePieChartLogic } from "./modules/pie";
+import { handleRoseChartChartLogic } from "./modules/roseChart";
+import { handlestackedBarChartLogic } from "./modules/stackedBar";
+import { handleParetoChartLogic } from "./modules/pareto";
+import { handleBoxPlotChartLogic } from "./modules/boxPlot";
+import { handleSankeyDiagramPlotChartLogic } from "./modules/sankeyDiagram"; //流图 桑基图
+import { handleHeatmapPlotChartLogic } from "./modules/Heatmap";
 export {
   handleBarChartLogic,
   handleScatterChartLogic,
   handleRadarChartLogic,
   handleCpChartLogic,
+  handlePieChartLogic,
+  handleRoseChartChartLogic,
+  handlestackedBarChartLogic,
+  handleParetoChartLogic,
+  handleBoxPlotChartLogic,
+  handleSankeyDiagramPlotChartLogic,
+  handleHeatmapPlotChartLogic,
 };

+ 127 - 0
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/Heatmap.js

@@ -0,0 +1,127 @@
+/*
+ * @Author: your name
+ * @Date: 2024-11-28 10:31:21
+ * @LastEditTime: 2024-11-28 13:43:22
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/Heatmap.js
+ */
+import { filterData } from "../dargChartFIlter";
+export function handleHeatmapPlotChartLogic(
+  item,
+  formLabelAlign,
+  formFilterAlign,
+  isFilter,
+  type
+) {
+  // 数据筛选逻辑
+  if (isFilter === "filter") {
+    const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
+      label: yItem.label,
+      id: yItem.id,
+      data: yItem.data.map((val) => {
+        const filters = formFilterAlign[index]?.filters || [];
+        // 排除 null 数据和不符合筛选条件的数据
+        return val === null ||
+          (filters.length > 0 && !filters.includes(val[yItem.label]))
+          ? null
+          : val;
+      }),
+    }));
+    // 条件筛选逻辑
+    const filterList = filterResult.map((filteredItem, index) => {
+      const filter = formFilterAlign[index];
+      const { filterType1, filterType2, number1, number2 } = filter;
+
+      if (
+        (number1 === null || number1 === "") &&
+        (number2 === null || number2 === "")
+      ) {
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: filteredItem.data,
+        };
+      } else {
+        const filterDatas = filterData(
+          filter,
+          filteredItem.data,
+          filteredItem.label
+        );
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: [...filterDatas],
+        };
+      }
+    });
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = filterList;
+  } else {
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = formLabelAlign.Ydata;
+  }
+  // 生成数据
+  if (
+    item.Xdata.length > 1 &&
+    item.Xdata[1]?.data?.length > 0 &&
+    item.Ydata.length > 0 &&
+    item.Ydata[0]?.data?.length > 0
+  ) {
+    // 初始化 series 数据
+    item.option.series = [];
+    const xAxisData = item.Xdata[0].data
+      .map((xitem) => xitem[item.Xdata[0].label])
+      .filter((val) => val !== null && val !== "" && val !== undefined);
+    const yAxisData = item.Xdata[1].data
+      .map((xitem) => xitem[item.Xdata[1].label])
+      .filter((val) => val !== null && val !== "" && val !== undefined);
+    // 设置 x 和 y 轴标签
+    item.option.xAxis = {
+      ...item.option.xAxis,
+      name: formLabelAlign.Xlable,
+      data: xAxisData,
+    };
+    item.option.yAxis = {
+      ...item.option.yAxis,
+      name: formLabelAlign.Ylable,
+      data: yAxisData,
+    };
+    // 初始化热力图数据
+    const data1 = [];
+    for (let z = 0; z < xAxisData.length; z++) {
+      for (let i = 0; i < yAxisData.length; i++) {
+        // 在 Ydata[0].data 中查找匹配的值
+        const matchedValue = item.Ydata[0].data.find(
+          (yval) =>
+            yval !== null &&
+            yval[item.Xdata[0].label] === xAxisData[z] &&
+            yval[item.Xdata[1].label] === yAxisData[i]
+        );
+        // 如果找到匹配值,则取 Ydata[0].label 的值,否则为 null
+        const value = matchedValue ? matchedValue[item.Ydata[0].label] : null;
+        // 将值推入 data1
+        data1.push([i, z, value]);
+      }
+    }
+    // 转换数据结构(如有必要)
+    const formattedData = data1.map((item) => [
+      item[1],
+      item[0],
+      item[2] || "-",
+    ]);
+
+    item.option.series = [
+      {
+        type: "heatmap",
+        data: formattedData,
+        emphasis: {
+          itemStyle: {
+            shadowBlur: 10,
+            shadowColor: "rgba(0, 0, 0, 0.5)",
+          },
+        },
+      },
+    ];
+  }
+}

+ 1 - 1
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/barAndLine.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2024-11-20 11:18:35
- * @LastEditTime: 2024-11-22 14:13:07
+ * @LastEditTime: 2024-11-27 15:03:25
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/utils/chartLogic/modules/barAndLine.js

+ 116 - 0
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/boxPlot.js

@@ -0,0 +1,116 @@
+/*
+ * @Author: your name
+ * @Date: 2024-11-27 15:20:57
+ * @LastEditTime: 2024-11-27 17:09:21
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/boxPlot.js
+ */
+import { filterData } from "../dargChartFIlter";
+export function handleBoxPlotChartLogic(
+  item,
+  formLabelAlign,
+  formFilterAlign,
+  isFilter,
+  type
+) {
+  // 数据筛选逻辑
+  if (isFilter === "filter") {
+    const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
+      label: yItem.label,
+      id: yItem.id,
+      data: yItem.data.map((val) => {
+        const filters = formFilterAlign[index]?.filters || [];
+        // 排除 null 数据和不符合筛选条件的数据
+        return val === null ||
+          (filters.length > 0 && !filters.includes(val[yItem.label]))
+          ? null
+          : val;
+      }),
+    }));
+
+    // 条件筛选逻辑
+    const filterList = filterResult.map((filteredItem, index) => {
+      const filter = formFilterAlign[index];
+      const { filterType1, filterType2, number1, number2 } = filter;
+
+      if (
+        (number1 === null || number1 === "") &&
+        (number2 === null || number2 === "")
+      ) {
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: filteredItem.data,
+        };
+      } else {
+        const filterDatas = filterData(
+          filter,
+          filteredItem.data,
+          filteredItem.label
+        );
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: [...filterDatas],
+        };
+      }
+    });
+
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = filterList;
+  } else {
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = formLabelAlign.Ydata;
+  }
+
+  // 设置 X 轴
+  const xData = formLabelAlign.Xdata.flatMap((item) =>
+    item.data.map((val) => val[item.label])
+  ).filter((val) => val !== null && val !== undefined); // 排除 null 和 undefined
+  item.option.xAxis = {
+    ...item.option.xAxis,
+    // data: [...new Set(xData)],
+    data: xData,
+    name: formLabelAlign.Xlable,
+  };
+
+  // 设置 Y 轴
+  item.option.yAxis = {
+    ...item.option.yAxis,
+    name: formLabelAlign.Ylable,
+  };
+
+  // 生成 boxplot 数据
+  if (item.Ydata.length > 4 && item.Ydata[4]?.data?.length > 0) {
+    // 初始化 series 数据
+    item.option.series = [];
+    const boxplotData = [];
+    const dataLength = item.Ydata[0]?.data?.length || 0;
+
+    for (let i = 0; i < dataLength; i++) {
+      // 获取并解析值
+      const min = item.Ydata[0]?.data[i]?.[item.Ydata[0].label] ?? null;
+      const q1 = item.Ydata[1]?.data[i]?.[item.Ydata[1].label] ?? null;
+      const median = item.Ydata[2]?.data[i]?.[item.Ydata[2].label] ?? null;
+      const q3 = item.Ydata[3]?.data[i]?.[item.Ydata[3].label] ?? null;
+      const max = item.Ydata[4]?.data[i]?.[item.Ydata[4].label] ?? null;
+
+      // 解析为浮点数
+      const values = [min, q1, median, q3, max].map((val) =>
+        val !== null ? parseFloat(val) : null
+      );
+
+      // 检查所有值是否有效
+      if (values.every((v) => v !== null && !isNaN(v))) {
+        boxplotData.push(values);
+      }
+    }
+
+    // 添加到 series
+    item.option.series.push({
+      type: "boxplot",
+      data: boxplotData,
+    });
+  }
+}

+ 127 - 86
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/cp.js

@@ -1,14 +1,44 @@
-/*
- * @Author: your name
- * @Date: 2024-11-21 15:40:30
- * @LastEditTime: 2024-11-25 15:18:08
- * @LastEditors: bogon
- * @Description: In User Settings Edit
- * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/cp.js
- */
-//散点折线图
 import { filterData } from "../dargChartFIlter";
+
 import { getFormattedLabels, getFormattedSeries } from "../../configFn";
+//赋值需要给所有的X和Y赋值,拿到过滤的数据是用来渲染图表的,不需要保存
+// 通用函数,生成折线图或散点图的 series 数据
+function generateSeriesData(dataSource, xData, yData, labelKey) {
+  return dataSource?.map((item, ind) => {
+    return {
+      name: item.label,
+      type: labelKey, // 'line' 或 'scatter'
+      renderMode: "webgl", // 启用 WebGL 渲染
+      showSymbol: labelKey === "line" ? true : undefined,
+      // itemStyle: {
+      //   color: colorPalette[ind], // 为风机A的散点设置单独的颜色
+      // },
+      // itemStyle:
+      //   labelKey === "scatter"
+      //     ? {
+      //         shadowBlur: 3,
+      //         shadowColor: "rgba(25, 100, 150, 0.3)",
+      //         shadowOffsetY: 1.5,
+      //       }
+      //     : {},
+      data: item.data
+        ?.map((val, valInd) => {
+          if (val === null) {
+            // 如果 val 为 null,直接跳过当前的散点
+            return null;
+          }
+          // 返回有效的散点数据
+          return [
+            xData[ind]?.data[valInd][xData[ind].label], // x轴数据
+            val[item.label], // y轴数据
+          ];
+        })
+        .filter(Boolean), // 使用 filter 去除 null 值
+      symbolSize: labelKey === "scatter" ? 8 : undefined, // 仅对散点图设置 symbolSize
+    };
+  });
+}
+
 export function handleCpChartLogic(
   item,
   formLabelAlign,
@@ -16,60 +46,69 @@ export function handleCpChartLogic(
   isFilter,
   type
 ) {
-  // console.log(item, formLabelAlign, formFilterAlign, "cp");
-  // 封装柱状图的具体逻辑
-  if (isFilter === "filter") {
-    // 数据筛选逻辑
-    const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
-      label: yItem.label,
-      id: yItem.id,
-      data: yItem.data.map((val) => {
-        const filters = formFilterAlign[index]?.filters || [];
-        return val === null ||
-          (filters.length > 0 && !filters.includes(val[yItem.label]))
-          ? null
-          : val;
-      }),
-    }));
-    // 条件筛选逻辑
-    const filterList = filterResult.map((filteredItem, index) => {
-      const filter = formFilterAlign[index];
-      const { filterType1, filterType2, number1, number2 } = filter;
-      if (
-        (number1 === null || number1 === "") &&
-        (number2 === null || number2 === "")
-      ) {
-        return {
-          label: filteredItem.label,
-          id: filteredItem.id,
-          data: filteredItem.data,
-        };
-      } else {
-        const filterDatas = filterData(
-          filter,
-          filteredItem.data,
-          filteredItem.label
-        );
-        return {
-          label: filteredItem.label,
-          id: filteredItem.id,
-          data: [...filterDatas],
-        };
-      }
-    });
-    item.Xdata = formLabelAlign.Xdata;
-    item.Ydata = filterList;
-  } else {
-    item.LineXdata = formLabelAlign.LineXdata;
-    item.LineYdata = formLabelAlign.LineYdata;
-    item.ScatterXdata = formLabelAlign.ScatterXdata;
-    item.ScatterYdata = formLabelAlign.ScatterYdata;
-  }
-  //默认数据
+  // 数据筛选逻辑
+  const filterResult = [
+    ...formLabelAlign.LineYdata,
+    ...formLabelAlign.ScatterYdata,
+  ].map((yItem, index) => {
+    if (formFilterAlign[index]?.filters.length > 0) {
+      return {
+        label: yItem.label,
+        id: yItem.id,
+        data: yItem.data.map((val) => {
+          const filters = formFilterAlign[index]?.filters || [];
+
+          return val !== null &&
+            filters.length > 0 &&
+            filters.includes(val[yItem.label])
+            ? val
+            : null;
+        }),
+      };
+    } else {
+      return yItem;
+    }
+  });
+
+  // 条件筛选逻辑
+  const filterList = filterResult.map((filteredItem, index) => {
+    const filter = formFilterAlign[index];
+    const { filterType1, filterType2, number1, number2 } = filter;
+    if (
+      (number1 === null || number1 === "") &&
+      (number2 === null || number2 === "")
+    ) {
+      return {
+        label: filteredItem.label,
+        id: filteredItem.id,
+        data: filteredItem.data,
+      };
+    } else {
+      const filterDatas = filterData(
+        filter,
+        filteredItem.data,
+        filteredItem.label
+      );
+      return {
+        label: filteredItem.label,
+        id: filteredItem.id,
+        data: [...filterDatas],
+      };
+    }
+  });
+
+  // 默认数据
   item.LineXdata = formLabelAlign.LineXdata;
-  item.LineYdata = formLabelAlign.LineYdata;
+  item.LineYdata = formLabelAlign.LineYdata.map((filterItem) =>
+    filterList.find((findItem) => filterItem.id === findItem.id)
+  ).filter(Boolean);
+
   item.ScatterXdata = formLabelAlign.ScatterXdata;
-  item.ScatterYdata = formLabelAlign.ScatterYdata;
+  item.ScatterYdata = formLabelAlign.ScatterYdata.map((filterItem) =>
+    filterList.find((findItem) => filterItem.id === findItem.id)
+  ).filter(Boolean);
+
+  // 设置 x 和 y 轴标签
   item.option.xAxis = {
     ...item.option.xAxis,
     name: formLabelAlign.Xlable,
@@ -78,31 +117,33 @@ export function handleCpChartLogic(
     ...item.option.yAxis,
     name: formLabelAlign.Ylable,
   };
-
+  // 生成折线图数据
   if (item.LineYdata[0]?.data?.length > 0) {
-    const res = item.LineYdata?.map((lineItem, ind) => {
-      return {
-        name: lineItem.label,
-        type: "line",
-        renderMode: "webgl", // 启用 WebGL 渲染
-        data: [
-          ...lineItem.data?.map((val, valInd) => {
-            return [
-              item.LineXdata[ind]?.data[valInd][item.LineXdata[ind].label],
-              val[lineItem.label],
-            ];
-          }),
-        ],
-      };
-    });
-    item.option.series = [...res];
+    const lineSeries = generateSeriesData(
+      item.LineYdata,
+      item.LineXdata,
+      item.LineYdata,
+      "line"
+    );
+    const scatterSeries = generateSeriesData(
+      item.ScatterYdata,
+      item.ScatterXdata,
+      item.ScatterYdata,
+      "scatter"
+    );
+    // 合并折线图和散点图的数据
+    item.option.series = [...lineSeries, ...scatterSeries];
   }
-  // item.option.xAxis = {
-  //   ...item.option.xAxis,
-  //   axisTick: { alignWithLabel: true },
-  // };
-  // item.option.tooltip = {
-  //   trigger: "axis",
-  //   axisPointer: { type: "shadow" },
-  // };
+
+  // // x轴轴标对齐
+  item.option.xAxis = {
+    ...item.option.xAxis,
+    axisTick: { alignWithLabel: true },
+  };
+
+  // 配置提示框
+  item.option.tooltip = {
+    trigger: "axis",
+    axisPointer: { type: "shadow" },
+  };
 }

+ 246 - 0
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/pareto.js

@@ -0,0 +1,246 @@
+/*
+ * @Author: your name
+ * @Date: 2024-11-27 09:59:10
+ * @LastEditTime: 2024-11-27 14:32:23
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/pareto.js
+ */
+//pareto 怕雷特图(折线柱状图)
+import { filterData } from "../dargChartFIlter";
+import * as echarts from "echarts/core";
+import { BarChart, LineChart } from "echarts/charts";
+import {
+  GridComponent,
+  TooltipComponent,
+  LegendComponent,
+  ToolboxComponent,
+} from "echarts/components";
+import { CanvasRenderer } from "echarts/renderers";
+import { GraphicComponent } from "echarts/components"; // 引入 graphic 模块
+
+echarts.use([
+  BarChart,
+  LineChart,
+  GridComponent,
+  TooltipComponent,
+  LegendComponent,
+  ToolboxComponent,
+  CanvasRenderer,
+  GraphicComponent,
+]);
+
+//赋值需要给所有的X和Y赋值,拿到过滤的数据是用来渲染图表的,不需要保存
+function generateSeriesData(dataSource, xData, yData, labelKey) {
+  return dataSource?.map((item, ind) => {
+    return {
+      name: item.label,
+      type: labelKey, // 'line' 或 'bar'
+      renderMode: "webgl", // 启用 WebGL 渲染
+      showBackground: true,
+      smooth: labelKey === "line" ? true : undefined,
+      lineStyle:
+        labelKey === "line"
+          ? {
+              color: "#d14a61",
+            }
+          : undefined,
+      itemStyle:
+        labelKey === "bar"
+          ? {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: "#83bff6" },
+                { offset: 0.5, color: "#188df0" },
+                { offset: 1, color: "#188df0" },
+              ]),
+            }
+          : undefined,
+      emphasis: {
+        itemStyle:
+          labelKey === "bar"
+            ? {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: "#2378f7" },
+                  { offset: 0.7, color: "#2378f7" },
+                  { offset: 1, color: "#83bff6" },
+                ]),
+              }
+            : undefined,
+      },
+      data: item.data
+        ?.map((val, valInd) => {
+          if (val === null) {
+            // 如果 val 为 null,直接跳过当前的散点
+            return null;
+          }
+          // 返回有效的散点数据
+          return [
+            xData[ind]?.data[valInd][xData[ind].label], // x轴数据
+            val[item.label], // y轴数据
+          ];
+        })
+        .filter(Boolean), // 使用 filter 去除 null 值
+    };
+  });
+}
+
+export function handleParetoChartLogic(
+  item,
+  formLabelAlign,
+  formFilterAlign,
+  isFilter,
+  type
+) {
+  // 数据筛选逻辑
+  const filterResult = [
+    ...formLabelAlign.LineYdata,
+    ...formLabelAlign.BarYdata,
+  ].map((yItem, index) => {
+    if (formFilterAlign[index]?.filters.length > 0) {
+      return {
+        label: yItem.label,
+        id: yItem.id,
+        data: yItem.data.map((val) => {
+          const filters = formFilterAlign[index]?.filters || [];
+
+          return val !== null &&
+            filters.length > 0 &&
+            filters.includes(val[yItem.label])
+            ? val
+            : null;
+        }),
+      };
+    } else {
+      return yItem;
+    }
+  });
+
+  // 条件筛选逻辑
+  const filterList = filterResult.map((filteredItem, index) => {
+    const filter = formFilterAlign[index];
+    const { filterType1, filterType2, number1, number2 } = filter;
+    if (
+      (number1 === null || number1 === "") &&
+      (number2 === null || number2 === "")
+    ) {
+      return {
+        label: filteredItem.label,
+        id: filteredItem.id,
+        data: filteredItem.data,
+      };
+    } else {
+      const filterDatas = filterData(
+        filter,
+        filteredItem.data,
+        filteredItem.label
+      );
+      return {
+        label: filteredItem.label,
+        id: filteredItem.id,
+        data: [...filterDatas],
+      };
+    }
+  });
+  // 默认数据
+  item.LineXdata = formLabelAlign.LineXdata;
+  item.LineYdata = formLabelAlign.LineYdata.map((filterItem) =>
+    filterList.find((findItem) => filterItem.id === findItem.id)
+  ).filter(Boolean);
+
+  item.BarXdata = formLabelAlign.BarXdata;
+  item.BarYdata = formLabelAlign.BarYdata.map((filterItem) =>
+    filterList.find((findItem) => filterItem.id === findItem.id)
+  ).filter(Boolean);
+  const xData = [
+    ...formLabelAlign.LineXdata.map((item) => {
+      return item.data.map((val) => val[item.label]);
+    }),
+    ...formLabelAlign.BarXdata.map((item) =>
+      item.data.map((val) => val[item.label])
+    ),
+  ].flat();
+
+  // 使用 Set 去除重复值
+  const uniqueXData = [...new Set(xData)];
+  item.option.xAxis = {
+    ...item.option.xAxis,
+    type: "category", // 确保 x 轴是分类轴
+    data: uniqueXData,
+    name: formLabelAlign.Xlable,
+    axisLabel: {
+      rotate: 45, // x轴标签旋转,避免重叠
+      //   interval: 0, // 确保所有标签都显示
+      formatter: (value) => value, // 确保标签文本正确显示
+      // 控制标签的间距,避免标签重叠
+      //   margin: 50, // 增加标签与轴线之间的间距
+    },
+    barCategoryGap: "10%", // 调整柱状图之间的间距
+  };
+
+  item.option.grid = {
+    left: "10%", // 左边留出更多空间
+    right: "10%", // 右边留出更多空间
+    bottom: "15%", // 底部留出空间
+    top: "15%", // 顶部留出空间
+  };
+
+  item.option.yAxis = [
+    {
+      type: "value", // 左侧 y 轴用于折状图
+      name: formLabelAlign.YRightLable,
+      position: "left",
+      axisLine: { show: true },
+      axisTick: { show: false },
+      splitLine: { show: true },
+      nameTextStyle: {
+        fontWeight: "bold",
+        fontSize: 12,
+      },
+    },
+    {
+      type: "value", // 右侧 y 轴用于柱线图(累计值或百分比)
+      name: formLabelAlign.YLeftLable,
+      position: "right",
+      axisLine: { show: true },
+      axisTick: { show: false },
+      splitLine: { show: false }, // 不显示分隔线
+      nameTextStyle: {
+        fontWeight: "bold",
+        fontSize: 12,
+      },
+    },
+  ];
+
+  // 如果 LineYdata 中有数据,生成折线图数据并添加到 series
+  if (item.LineYdata[0]?.data?.length > 0) {
+    const lineSeries = generateSeriesData(
+      item.LineYdata,
+      item.LineXdata,
+      item.LineYdata,
+      "line"
+    );
+    lineSeries.forEach((series) => {
+      series.yAxisIndex = 1; // 将折线图的数据绑定到右侧 y 轴
+    });
+
+    const scatterSeries = generateSeriesData(
+      item.BarYdata,
+      item.BarXdata,
+      item.BarYdata,
+      "bar"
+    );
+    scatterSeries.forEach((series) => {
+      series.yAxisIndex = 0; // 将柱状图的数据绑定到左侧 y 轴
+      series.stack = "stacked"; // 设置为堆叠模式
+    });
+    // item.option.visualMap = [
+    //   {
+    //     show: false,
+    //     type: "continuous",
+    //     seriesIndex: 0,
+    //   },
+    // ];
+    // 合并折线图和柱状图的数据
+    item.option.series = [...lineSeries, ...scatterSeries];
+  }
+}

+ 89 - 0
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/pie.js

@@ -0,0 +1,89 @@
+/*
+ * @Author: your name
+ * @Date: 2024-11-26 16:33:45
+ * @LastEditTime: 2024-11-26 17:31:22
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/pie.js
+ */
+import { filterData } from "../dargChartFIlter";
+export function handlePieChartLogic(
+  item,
+  formLabelAlign,
+  formFilterAlign,
+  isFilter,
+  type
+) {
+  // 封装柱状图的具体逻辑
+  if (isFilter === "filter") {
+    // 数据筛选逻辑,
+    const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
+      label: yItem.label,
+      id: yItem.id,
+      data: yItem.data.map((val) => {
+        const filters = formFilterAlign[index]?.filters || [];
+
+        return val === null ||
+          (filters.length > 0 && !filters.includes(val[yItem.label]))
+          ? null
+          : val;
+      }),
+    }));
+    // 条件筛选逻辑
+    const filterList = filterResult.map((filteredItem, index) => {
+      const filter = formFilterAlign[index];
+      const { filterType1, filterType2, number1, number2 } = filter;
+
+      if (
+        (number1 === null || number1 === "") &&
+        (number2 === null || number2 === "")
+      ) {
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: filteredItem.data,
+        };
+      } else {
+        const filterDatas = filterData(
+          filter,
+          filteredItem.data,
+          filteredItem.label
+        );
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: [...filterDatas],
+        };
+      }
+    });
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = filterList;
+  } else {
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = formLabelAlign.Ydata;
+  }
+  const res = item.Ydata.map((yItem, yIndex) => {
+    return {
+      name: yItem.label,
+      type,
+      radius: "60%",
+      data:
+        yItem.data &&
+        yItem.data.map((val, valIndex) => {
+          // 获取对应的 Xdata 数据
+          const xVal =
+            item.Xdata[yIndex]?.data?.[valIndex]?.[item.Xdata[yIndex].label] ||
+            "";
+
+          return {
+            value: (val && val[yItem.label]) || null, // 从 Ydata 获取 value
+            name: xVal, // 从 Xdata 获取 name
+          };
+        }),
+    };
+  });
+
+  if (item.Ydata[0]?.data?.length > 0) {
+    item.option.series = res;
+  }
+}

+ 97 - 0
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/roseChart.js

@@ -0,0 +1,97 @@
+/*
+ * @Author: your name
+ * @Date: 2024-11-26 16:33:38
+ * @LastEditTime: 2024-11-26 17:21:35
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/roseChart.js
+ */
+//玫瑰图
+import { filterData } from "../dargChartFIlter";
+export function handleRoseChartChartLogic(
+  item,
+  formLabelAlign,
+  formFilterAlign,
+  isFilter,
+  type
+) {
+  // 封装柱状图的具体逻辑
+  if (isFilter === "filter") {
+    // 数据筛选逻辑,
+    const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
+      label: yItem.label,
+      id: yItem.id,
+      data: yItem.data.map((val) => {
+        const filters = formFilterAlign[index]?.filters || [];
+
+        return val === null ||
+          (filters.length > 0 && !filters.includes(val[yItem.label]))
+          ? null
+          : val;
+      }),
+    }));
+    // 条件筛选逻辑
+    const filterList = filterResult.map((filteredItem, index) => {
+      const filter = formFilterAlign[index];
+      const { filterType1, filterType2, number1, number2 } = filter;
+
+      if (
+        (number1 === null || number1 === "") &&
+        (number2 === null || number2 === "")
+      ) {
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: filteredItem.data,
+        };
+      } else {
+        const filterDatas = filterData(
+          filter,
+          filteredItem.data,
+          filteredItem.label
+        );
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: [...filterDatas],
+        };
+      }
+    });
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = filterList;
+  } else {
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = formLabelAlign.Ydata;
+  }
+  const xres = item.Xdata?.map((xitem) => {
+    return {
+      boundaryGap: false,
+      type: "category",
+      data:
+        xitem.data &&
+        xitem.data.map((val) => xitem.label + val[xitem.label] || null),
+    };
+  }).filter((items) => items !== null || items !== undefined);
+  const yres = item.Ydata?.map((yitem) => {
+    return {
+      name: yitem.label,
+      type: "bar",
+      coordinateSystem: "polar",
+      data:
+        yitem.data &&
+        yitem.data.map((val) => {
+          return (val && val[yitem.label]) || null;
+        }),
+    };
+  }).filter((items) => items !== null || items !== undefined);
+  if (item.Ydata[0]?.data?.length > 0) {
+    item.option.series = yres;
+    item.option.angleAxis = xres;
+  }
+  if (item.Xdata[0]?.data?.length > 0) {
+    item.option.tooltip = {
+      trigger: "axis",
+      axisPointer: { type: "shadow" },
+    };
+  }
+}

+ 124 - 0
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/sankeyDiagram.js

@@ -0,0 +1,124 @@
+/*
+ * @Author: your name
+ * @Date: 2024-11-27 17:15:51
+ * @LastEditTime: 2024-11-28 10:24:14
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/sankeyDiagram.js
+ */
+//流图
+import { filterData } from "../dargChartFIlter";
+export function handleSankeyDiagramPlotChartLogic(
+  item,
+  formLabelAlign,
+  formFilterAlign,
+  isFilter,
+  type
+) {
+  // 数据筛选逻辑
+  if (isFilter === "filter") {
+    const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
+      label: yItem.label,
+      id: yItem.id,
+      data: yItem.data.map((val) => {
+        const filters = formFilterAlign[index]?.filters || [];
+        // 排除 null 数据和不符合筛选条件的数据
+        return val === null ||
+          (filters.length > 0 && !filters.includes(val[yItem.label]))
+          ? null
+          : val;
+      }),
+    }));
+    // 条件筛选逻辑
+    const filterList = filterResult.map((filteredItem, index) => {
+      const filter = formFilterAlign[index];
+      const { filterType1, filterType2, number1, number2 } = filter;
+
+      if (
+        (number1 === null || number1 === "") &&
+        (number2 === null || number2 === "")
+      ) {
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: filteredItem.data,
+        };
+      } else {
+        const filterDatas = filterData(
+          filter,
+          filteredItem.data,
+          filteredItem.label
+        );
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: [...filterDatas],
+        };
+      }
+    });
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = filterList;
+  } else {
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = formLabelAlign.Ydata;
+  }
+  console.log(item.Xdata, item.Ydata, "item.Xdata,item.Ydata");
+  // 设置 X 轴
+  const xData = formLabelAlign.Xdata.flatMap((item) =>
+    item.data.map((val) => val[item.label])
+  ).filter((val) => val !== null && val !== undefined && val !== ""); // 排除 null 和 undefined
+  // 对 xData 去重并转换为 [{name: ''}, {name: ''}] 的格式
+  const uniqueXData = [...new Set(xData)].map((name) => ({ name }));
+  console.log(uniqueXData, "uniqueXData");
+
+  // 生成 sankeyDiagram 数据
+  if (
+    item.Xdata.length > 1 &&
+    item.Xdata[1]?.data?.length > 0 &&
+    item.Ydata.length > 0 &&
+    item.Ydata[0]?.data?.length > 0
+  ) {
+    // 初始化 series 数据
+    item.option.series = [];
+    const sankeyDiagramData = [];
+    const dataLength = item.Xdata[0]?.data?.length || 0;
+
+    for (let i = 0; i < dataLength; i++) {
+      // 获取并解析值
+      const source = item.Xdata[0]?.data[i]?.[item.Xdata[0].label] ?? null;
+      const target = item.Xdata[1]?.data[i]?.[item.Xdata[1].label] ?? null;
+      const value = item.Ydata[0]?.data[i]?.[item.Ydata[0].label] ?? null;
+      if (source && target && value) {
+        // 解析为浮点数
+        const values = [source, target, value].map((val) =>
+          val !== null ? val : null
+        );
+        // 检查所有值是否有效
+        sankeyDiagramData.push({
+          source: values[0],
+          target: values[1],
+          value: values[2],
+        });
+      }
+    }
+    console.log(sankeyDiagramData, "sankeyDiagramData");
+    item.option.series = [
+      {
+        type: "sankey",
+        layout: "none",
+        emphasis: {
+          focus: "adjacency",
+        },
+        data: uniqueXData,
+        links: sankeyDiagramData,
+        lineStyle: {
+          color: "gradient",
+          curveness: 0.5,
+        },
+        label: {
+          color: "#333",
+        },
+      },
+    ];
+  }
+}

+ 199 - 31
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/scatter.js

@@ -1,15 +1,124 @@
 //散点图+散点折线图
 import { filterData } from "../dargChartFIlter";
+// export function handleScatterChartLogic(
+//   item, //curEdit编辑项配置
+//   formLabelAlign, //每一项label显示
+//   formFilterAlign, //过滤数据 数据筛选from
+//   isFilter, //是否是过滤
+//   type //图表类型
+// ) {
+//   // 封装柱状图的具体逻辑
+//   if (isFilter === "filter") {
+//     // 数据筛选逻辑
+//     const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
+//       label: yItem.label,
+//       id: yItem.id,
+//       data: yItem.data.map((val) => {
+//         const filters = formFilterAlign[index]?.filters || [];
+//         return val === null ||
+//           (filters.length > 0 && !filters.includes(val[yItem.label]))
+//           ? null
+//           : val;
+//       }),
+//     }));
+//     // 条件筛选逻辑
+//     const filterList = filterResult.map((filteredItem, index) => {
+//       const filter = formFilterAlign[index];
+//       const { filterType1, filterType2, number1, number2 } = filter;
+//       if (
+//         (number1 === null || number1 === "") &&
+//         (number2 === null || number2 === "")
+//       ) {
+//         return {
+//           label: filteredItem.label,
+//           id: filteredItem.id,
+//           data: filteredItem.data,
+//         };
+//       } else {
+//         const filterDatas = filterData(
+//           filter,
+//           filteredItem.data,
+//           filteredItem.label
+//         );
+//         return {
+//           label: filteredItem.label,
+//           id: filteredItem.id,
+//           data: [...filterDatas],
+//         };
+//       }
+//     });
+//     item.Xdata = formLabelAlign.Xdata;
+//     item.Ydata = filterList;
+//   } else {
+//     item.Xdata = formLabelAlign.Xdata;
+//     item.Ydata = formLabelAlign.Ydata;
+//   }
+//   item.option.xAxis = {
+//     ...item.option.xAxis,
+//     type: "value",
+//     name: formLabelAlign.Xlable,
+//   };
+//   item.option.yAxis = {
+//     ...item.option.yAxis,
+
+//     name: formLabelAlign.Ylable,
+//   };
+
+//   if (item.Ydata[0]?.data?.length > 0 || item.Xdata[0]?.data?.length > 0) {
+//     // console.log(item.Xdata, "item.Xdata", item.Ydata);
+//     item.option.series = (
+//       item.Xdata.length > item.Ydata.length ? item.Xdata : item.Ydata
+//     ).map((val, ind) => {
+//       const xData = item.Xdata[ind]?.data || [];
+//       const yData = item.Ydata[ind]?.data || [];
+
+//       const scatterData = xData
+//         .map((xItem, idx) => {
+//           const yItem = yData[idx];
+//           if (!xItem || !yItem) return null; // 如果对应项不存在,则跳过
+//           return [
+//             Number(
+//               xItem[item.Xdata[ind].label] === undefined
+//                 ? 0
+//                 : xItem[item.Xdata[ind].label]
+//             ) || 0, // 取 X 值
+//             Number(
+//               yItem[item.Ydata[ind].label] === undefined
+//                 ? 0
+//                 : yItem[item.Ydata[ind].label]
+//             ) || 0, // 取 Y 值
+//           ];
+//         })
+//         .filter((point) => point !== null); // 过滤掉无效的点
+
+//       return {
+//         name: `${item.Xdata[ind]?.label || "X"} - ${
+//           item.Ydata[ind]?.label || "Y"
+//         }`,
+//         type: type,
+//         renderMode: "webgl", // 启用 WebGL 渲染
+//         data: scatterData, // 生成的散点图数据
+//         tooltip: {
+//           trigger: "item", // 鼠标悬停触发
+//         },
+//         itemStyle: {
+//           shadowBlur: 3,
+//           shadowColor: "rgba(25, 100, 150, 0.3)",
+//           shadowOffsetY: 1.5,
+//         },
+//       };
+//     });
+//   }
+// }
 export function handleScatterChartLogic(
-  item, //curEdit编辑项配置
-  formLabelAlign, //每一项label显示
-  formFilterAlign, //过滤数据 数据筛选from
-  isFilter, //是否是过滤
-  type //图表类型
+  item, // curEdit编辑项配置
+  formLabelAlign, // 每一项label显示
+  formFilterAlign, // 过滤数据 数据筛选from
+  isFilter, // 是否是过滤
+  type // 图表类型
 ) {
-  // 封装柱状图的具体逻辑
+  // 处理过滤数据的逻辑
   if (isFilter === "filter") {
-    // 数据筛选逻辑
     const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
       label: yItem.label,
       id: yItem.id,
@@ -21,7 +130,7 @@ export function handleScatterChartLogic(
           : val;
       }),
     }));
-    // 条件筛选逻辑
+
     const filterList = filterResult.map((filteredItem, index) => {
       const filter = formFilterAlign[index];
       const { filterType1, filterType2, number1, number2 } = filter;
@@ -53,6 +162,7 @@ export function handleScatterChartLogic(
     item.Xdata = formLabelAlign.Xdata;
     item.Ydata = formLabelAlign.Ydata;
   }
+
   item.option.xAxis = {
     ...item.option.xAxis,
     type: "value",
@@ -60,12 +170,11 @@ export function handleScatterChartLogic(
   };
   item.option.yAxis = {
     ...item.option.yAxis,
-
     name: formLabelAlign.Ylable,
   };
 
   if (item.Ydata[0]?.data?.length > 0 || item.Xdata[0]?.data?.length > 0) {
-    // console.log(item.Xdata, "item.Xdata", item.Ydata);
+    // 设置series配置
     item.option.series = (
       item.Xdata.length > item.Ydata.length ? item.Xdata : item.Ydata
     ).map((val, ind) => {
@@ -100,29 +209,88 @@ export function handleScatterChartLogic(
         data: scatterData, // 生成的散点图数据
         tooltip: {
           trigger: "item", // 鼠标悬停触发
-          // formatter: (params) => {
-          //   // params.dataIndex: 当前点的索引
-          //   const idx = params.dataIndex;
-          //   const xTooltipData = item.Xdata.map(
-          //     (xItem) =>
-          //       `${xItem.label}: ${
-          //         xItem.data[idx]
-          //           ? Number(xItem.data[idx][xItem.label] || 0)
-          //           : "N/A"
-          //       }`
-          //   ).join("<br>");
-          //   const yTooltipData = item.Ydata.map(
-          //     (yItem) =>
-          //       `${yItem.label}: ${
-          //         yItem.data[idx]
-          //           ? Number(yItem.data[idx][yItem.label]) || 0
-          //           : "N/A"
-          //       }`
-          //   ).join("<br>");
-          //   return `X轴数据:<br>${xTooltipData}<br>Y轴数据:<br>${yTooltipData}`;
-          // },
+        },
+        itemStyle: {
+          shadowBlur: 3,
+          shadowColor: "rgba(25, 100, 150, 0.3)",
+          shadowOffsetY: 1.5,
         },
       };
     });
+
+    // 记录选中的散点
+    const selectedPoints = [];
+
+    // 点击事件的处理函数
+    function handleClick(event) {
+      const selectedIndex = event.dataIndex;
+      const scatterData = item.option.series[0].data;
+
+      // 获取点击点的坐标
+      const xClick = event.data[0];
+      const yClick = event.data[1];
+
+      // 判断该点是否已经被选中
+      const existingIndex = selectedPoints.findIndex(
+        (point) => point.index === selectedIndex
+      );
+
+      if (existingIndex === -1) {
+        // 如果没有选中,则加入
+        selectedPoints.push({
+          index: selectedIndex,
+          x: xClick,
+          y: yClick,
+        });
+      } else {
+        // 如果已经选中,则取消选中
+        selectedPoints.splice(existingIndex, 1);
+      }
+
+      // 更新选中点的样式
+      const newColors = scatterData.map((point, index) => {
+        // 如果该点在 selectedPoints 中,则改变其颜色
+        if (
+          selectedPoints.some((selectedPoint) => selectedPoint.index === index)
+        ) {
+          return "red"; // 选中点为红色
+        }
+        return point[0] && point[1] ? "#000" : "transparent"; // 默认颜色,未选中点为黑色
+      });
+
+      const newSizes = scatterData.map((point, index) => {
+        // 如果该点在 selectedPoints 中,则增大其大小
+        if (
+          selectedPoints.some((selectedPoint) => selectedPoint.index === index)
+        ) {
+          return 10; // 选中点大小为 10
+        }
+        return 5; // 默认大小
+      });
+
+      // 更新图表的颜色和大小
+      item.option.series[0].itemStyle = {
+        color: newColors,
+        size: newSizes,
+      };
+
+      // 通过重新设置 `option` 来更新图表
+      if (item.chartInstance) {
+        item.chartInstance.setOption(item.option);
+      }
+    }
+
+    // 绑定点击事件
+    item.option.series[0].emphasis = {
+      itemStyle: {
+        color: "red",
+      },
+    };
+
+    // 添加点击事件
+    if (item.chartInstance) {
+      item.chartInstance.off("click"); // 先移除之前的事件
+      item.chartInstance.on("click", handleClick); // 然后绑定新的点击事件
+    }
   }
 }

+ 113 - 0
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/stackedBar.js

@@ -0,0 +1,113 @@
+/*
+ * @Author: your name
+ * @Date: 2024-11-27 09:36:28
+ * @LastEditTime: 2024-11-27 17:16:20
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/stackedBar.js
+ */
+//stackedBar 堆叠柱状图
+import { filterData } from "../dargChartFIlter";
+import { getFormattedLabels } from "../../configFn";
+export function handlestackedBarChartLogic(
+  item,
+  formLabelAlign,
+  formFilterAlign,
+  isFilter,
+  type
+) {
+  // 封装柱状图的具体逻辑
+  if (isFilter === "filter") {
+    // 数据筛选逻辑,
+    const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
+      label: yItem.label,
+      id: yItem.id,
+      data: yItem.data.map((val) => {
+        const filters = formFilterAlign[index]?.filters || [];
+        return val === null ||
+          (filters.length > 0 && !filters.includes(val[yItem.label]))
+          ? null
+          : val;
+      }),
+    }));
+    // 条件筛选逻辑
+    const filterList = filterResult.map((filteredItem, index) => {
+      const filter = formFilterAlign[index];
+      const { filterType1, filterType2, number1, number2 } = filter;
+
+      if (
+        (number1 === null || number1 === "") &&
+        (number2 === null || number2 === "")
+      ) {
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: filteredItem.data,
+        };
+      } else {
+        const filterDatas = filterData(
+          filter,
+          filteredItem.data,
+          filteredItem.label
+        );
+        return {
+          label: filteredItem.label,
+          id: filteredItem.id,
+          data: [...filterDatas],
+        };
+      }
+    });
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = filterList;
+  } else {
+    item.Xdata = formLabelAlign.Xdata;
+    item.Ydata = formLabelAlign.Ydata;
+  }
+
+  item.option.xAxis = {
+    ...item.option.xAxis,
+    name: formLabelAlign.Xlable,
+  };
+  item.option.yAxis = {
+    ...item.option.yAxis,
+    name: formLabelAlign.Ylable,
+  };
+
+  if (item.Ydata[0]?.data?.length > 0) {
+    let series = [];
+    item.Ydata.forEach((item) => {
+      series.push({
+        name: item.label,
+        type: "bar",
+        stack: "d",
+        data: item.data.map(
+          (data) => parseFloat(data !== null && data[item.label]) || 0
+        ), // 将数据转换为数值
+      });
+    });
+    item.option.series = series;
+  }
+  if (item.Xdata[0]?.data?.length > 0) {
+    item.option.xAxis = {
+      ...item.option.xAxis,
+      data: item.Xdata[0].data,
+      axisTick: { alignWithLabel: true },
+      axisLabel: {
+        formatter: (value, index) =>
+          value !== null ? getFormattedLabels(index, item.Xdata, value) : "",
+      },
+    };
+    item.option.tooltip = {
+      trigger: "axis",
+      axisPointer: { type: "shadow" },
+      formatter: (params) => {
+        const index = params[0]?.dataIndex; // 获取当前数据点索引
+        const content = params
+          .map((param) => `${param.marker}${param.seriesName}: ${param.value}`)
+          .join("<br/>");
+        const customLabels = getFormattedLabels(index, item.Xdata);
+        return `${customLabels}<br/>${content}`;
+      },
+    };
+  }
+}

+ 397 - 119
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartTitle.vue

@@ -20,17 +20,40 @@
             <el-tooltip
               content="添加纬度"
               placement="bottom-start"
-              v-if="curEdit.type === 'scatter' || curEdit.type === 'radar'"
+              v-if="
+                curEdit.type === 'scatter' ||
+                curEdit.type === 'radar' ||
+                curEdit.type === 'sankeyDiagram' ||
+                curEdit.type === 'Heatmap'
+              "
             >
               <i
-                @click="
-                  formLabelAlign.Xdata.push({ lable: '', data: [], id: '' })
-                "
+                @click="handleLatitude('init')"
                 class="el-icon-circle-plus-outline"
                 style="font-size: 20px"
               ></i>
             </el-tooltip>
           </div>
+          <el-tooltip
+            content="按顺序添加纬度,不添加则不显示图表"
+            placement="bottom-start"
+            v-if="
+              curEdit.type === 'sankeyDiagram' || curEdit.type === 'Heatmap'
+            "
+          >
+            <div
+              v-if="curEdit.type === 'sankeyDiagram'"
+              style="color: red; font-size: 12px"
+            >
+              源纬度-目标纬度
+            </div>
+            <div
+              v-if="curEdit.type === 'Heatmap'"
+              style="color: red; font-size: 12px"
+            >
+              横轴纬度-纵轴纬度
+            </div>
+          </el-tooltip>
           <template v-for="(item, ind) in formLabelAlign.Xdata">
             <div class="attributeItemData">
               <el-select
@@ -45,11 +68,16 @@
                   v-for="item in selectData"
                   :label="item.label"
                   :value="item.id"
-                  :key="item.id"
+                  :key="item.id + ind"
                 ></el-option>
               </el-select>
               <el-tooltip
-                v-if="curEdit.type === 'scatter' || curEdit.type === 'radar'"
+                v-if="
+                  curEdit.type === 'scatter' ||
+                  curEdit.type === 'radar' ||
+                  curEdit.type === 'sankeyDiagram' ||
+                  curEdit.type === 'Heatmap'
+                "
                 :content="
                   formLabelAlign.Xdata.length <= 1
                     ? '该指标不可删除,最少存在一组指标'
@@ -81,7 +109,16 @@
             "
           >
             <span>指标值</span>
-            <el-tooltip content="添加指标值" placement="bottom-start">
+            <el-tooltip
+              content="添加指标值"
+              placement="bottom-start"
+              v-if="
+                curEdit.type !== 'roseChart' &&
+                curEdit.type !== 'pie' &&
+                curEdit.type !== 'sankeyDiagram' &&
+                curEdit.type !== 'Heatmap'
+              "
+            >
               <i
                 @click="handleMetrics('init')"
                 class="el-icon-circle-plus-outline"
@@ -89,6 +126,16 @@
               ></i>
             </el-tooltip>
           </div>
+          <el-tooltip
+            content="按顺序添加指标值,不添加则不显示图表"
+            placement="bottom-start"
+            v-if="curEdit.type === 'boxPlot'"
+          >
+            <div style="color: red; font-size: 12px">
+              最小值-Q1-中位数-Q3-最大值
+            </div>
+          </el-tooltip>
+
           <template v-for="(item, ind) in formLabelAlign.Ydata">
             <div class="attributeItemData">
               <el-select
@@ -103,10 +150,16 @@
                   v-for="item in selectData"
                   :label="item.label"
                   :value="item.id"
-                  :key="item.id"
+                  :key="item.id + ind"
                 ></el-option>
               </el-select>
               <el-tooltip
+                v-if="
+                  curEdit.type !== 'roseChart' &&
+                  curEdit.type !== 'pie' &&
+                  curEdit.type !== 'sankeyDiagram' &&
+                  curEdit.type !== 'Heatmap'
+                "
                 :content="
                   formLabelAlign.Ydata.length <= 1
                     ? '该指标不可删除,最少存在一组指标'
@@ -129,8 +182,10 @@
           </template>
         </el-form-item>
       </template>
-
-      <el-form-item v-if="curEdit.type === 'pareto'" label="柱纬度标签">
+      <el-form-item
+        v-if="curEdit.type === 'pareto' || curEdit.type === 'Cp'"
+        label="线纬度标签"
+      >
         <div
           slot="label"
           style="
@@ -139,37 +194,37 @@
             justify-content: space-between;
           "
         >
-          <span>纬度标签</span>
-          <el-tooltip content="添加纬度" placement="bottom-start">
+          <span>线纬度标签</span>
+          <!-- <el-tooltip content="添加纬度" placement="bottom-start">
             <i
               @click="
-                formLabelAlign.BarXdata.push({ lable: '', data: [], id: '' })
+                formLabelAlign.LineXdata.push({ lable: '', data: [], id: '' })
               "
               class="el-icon-circle-plus-outline"
               style="font-size: 20px"
             ></i>
-          </el-tooltip>
+          </el-tooltip> -->
         </div>
-        <template v-for="(item, ind) in formLabelAlign.BarXdata">
+        <template v-for="(item, ind) in formLabelAlign.LineXdata">
           <div class="attributeItemData">
             <el-select
               style="margin: 5px 0"
               :key="ind + 'select'"
-              v-model="formLabelAlign.BarXdata[ind].id"
+              v-model="formLabelAlign.LineXdata[ind].id"
               placeholder="请先进行数据配置"
               :disabled="disabled"
-              @change="handleXdata('bar')"
+              @change="handleXdata('line')"
             >
               <el-option
                 v-for="item in selectData"
                 :label="item.label"
                 :value="item.id"
-                :key="item.id"
+                :key="item.id + ind"
               ></el-option>
             </el-select>
-            <el-tooltip
+            <!-- <el-tooltip
               :content="
-                formLabelAlign.BarXdata.length <= 1
+                formLabelAlign.LineXdata.length <= 1
                   ? '该指标不可删除,最少存在一组指标'
                   : '删除该指标'
               "
@@ -177,19 +232,22 @@
             >
               <el-button
                 type="text"
-                :disabled="formLabelAlign.BarXdata.length <= 1"
-                @click="removeXdata(ind, 'bar')"
+                :disabled="formLabelAlign.LineXdata.length <= 1"
+                @click="removeXdata(ind, 'line')"
               >
                 <i
                   class="el-icon-delete"
                   style="font-size: 16px; color: red; padding: 0 0 0 10px"
                 ></i
               ></el-button>
-            </el-tooltip>
+            </el-tooltip> -->
           </div>
         </template>
       </el-form-item>
-      <el-form-item v-if="curEdit.type === 'pareto'" label="柱指标值">
+      <el-form-item
+        v-if="curEdit.type === 'pareto' || curEdit.type === 'Cp'"
+        label="线指标值"
+      >
         <div
           slot="label"
           style="
@@ -198,35 +256,40 @@
             justify-content: space-between;
           "
         >
-          <span>柱指标值</span>
-          <el-tooltip content="添加柱指标值" placement="bottom-start">
+          <span>线指标值</span>
+          <el-tooltip
+            content="添加线指标值"
+            placement="bottom-start"
+            v-if="curEdit.type !== 'pareto'"
+          >
             <i
-              @click="handleMetrics('bar')"
+              @click="handleMetrics('line')"
               class="el-icon-circle-plus-outline"
               style="font-size: 20px"
             ></i>
           </el-tooltip>
         </div>
-        <template v-for="(item, ind) in formLabelAlign.BarYdata">
+        <template v-for="(item, ind) in formLabelAlign.LineYdata">
           <div class="attributeItemData">
             <el-select
               style="margin: 5px 0"
               :key="ind + 'select' + 'zhibiao'"
-              v-model="formLabelAlign.BarYdata[ind].id"
+              v-model="formLabelAlign.LineYdata[ind].id"
               placeholder="请先进行数据配置"
               :disabled="disabled"
-              @change="handleYdata(ind, 'bar')"
+              @change="handleYdata(ind, 'line')"
             >
               <el-option
                 v-for="item in selectData"
                 :label="item.label"
                 :value="item.id"
-                :key="item.id"
+                :key="item.id + ind"
               ></el-option>
             </el-select>
             <el-tooltip
+              v-if="curEdit.type !== 'pareto'"
               :content="
-                formLabelAlign.BarYdata.length <= 1
+                formLabelAlign.LineYdata.length <= 1
                   ? '该指标不可删除,最少存在一组指标'
                   : '删除该指标'
               "
@@ -234,8 +297,8 @@
             >
               <el-button
                 type="text"
-                :disabled="formLabelAlign.BarYdata.length <= 1"
-                @click="removeYdata(ind, 'bar')"
+                :disabled="formLabelAlign.LineYdata.length <= 1"
+                @click="removeYdata(ind, 'line')"
               >
                 <i
                   class="el-icon-delete"
@@ -246,10 +309,7 @@
           </div>
         </template>
       </el-form-item>
-      <el-form-item
-        v-if="curEdit.type === 'pareto' || curEdit.type === 'Cp'"
-        label="线纬度标签"
-      >
+      <el-form-item v-if="curEdit.type === 'pareto'" label="柱纬度标签">
         <div
           slot="label"
           style="
@@ -258,37 +318,42 @@
             justify-content: space-between;
           "
         >
-          <span>线纬度标签</span>
-          <el-tooltip content="添加纬度" placement="bottom-start">
+          <span>柱纬度标签</span>
+          <el-tooltip
+            content="添加纬度"
+            placement="bottom-start"
+            v-if="curEdit.type !== 'pareto'"
+          >
             <i
               @click="
-                formLabelAlign.LineXdata.push({ lable: '', data: [], id: '' })
+                formLabelAlign.BarXdata.push({ lable: '', data: [], id: '' })
               "
               class="el-icon-circle-plus-outline"
               style="font-size: 20px"
             ></i>
           </el-tooltip>
         </div>
-        <template v-for="(item, ind) in formLabelAlign.LineXdata">
+        <template v-for="(item, ind) in formLabelAlign.BarXdata">
           <div class="attributeItemData">
             <el-select
               style="margin: 5px 0"
               :key="ind + 'select'"
-              v-model="formLabelAlign.LineXdata[ind].id"
+              v-model="formLabelAlign.BarXdata[ind].id"
               placeholder="请先进行数据配置"
               :disabled="disabled"
-              @change="handleXdata('line')"
+              @change="handleXdata('bar')"
             >
               <el-option
                 v-for="item in selectData"
                 :label="item.label"
                 :value="item.id"
-                :key="item.id"
+                :key="item.id + ind"
               ></el-option>
             </el-select>
             <el-tooltip
+              v-if="curEdit.type !== 'pareto'"
               :content="
-                formLabelAlign.LineXdata.length <= 1
+                formLabelAlign.BarXdata.length <= 1
                   ? '该指标不可删除,最少存在一组指标'
                   : '删除该指标'
               "
@@ -296,8 +361,8 @@
             >
               <el-button
                 type="text"
-                :disabled="formLabelAlign.LineXdata.length <= 1"
-                @click="removeXdata(ind, 'line')"
+                :disabled="formLabelAlign.BarXdata.length <= 1"
+                @click="removeXdata(ind, 'bar')"
               >
                 <i
                   class="el-icon-delete"
@@ -308,10 +373,7 @@
           </div>
         </template>
       </el-form-item>
-      <el-form-item
-        v-if="curEdit.type === 'pareto' || curEdit.type === 'Cp'"
-        label="线指标值"
-      >
+      <el-form-item v-if="curEdit.type === 'pareto'" label="柱指标值">
         <div
           slot="label"
           style="
@@ -320,35 +382,40 @@
             justify-content: space-between;
           "
         >
-          <span>线指标值</span>
-          <el-tooltip content="添加线指标值" placement="bottom-start">
+          <span>柱指标值</span>
+          <el-tooltip
+            v-if="curEdit.type !== 'pareto'"
+            content="添加柱指标值"
+            placement="bottom-start"
+          >
             <i
-              @click="handleMetrics('line')"
+              @click="handleMetrics('bar')"
               class="el-icon-circle-plus-outline"
               style="font-size: 20px"
             ></i>
           </el-tooltip>
         </div>
-        <template v-for="(item, ind) in formLabelAlign.LineYdata">
+        <template v-for="(item, ind) in formLabelAlign.BarYdata">
           <div class="attributeItemData">
             <el-select
               style="margin: 5px 0"
               :key="ind + 'select' + 'zhibiao'"
-              v-model="formLabelAlign.LineYdata[ind].id"
+              v-model="formLabelAlign.BarYdata[ind].id"
               placeholder="请先进行数据配置"
               :disabled="disabled"
-              @change="handleYdata(ind, 'line')"
+              @change="handleYdata(ind, 'bar')"
             >
               <el-option
                 v-for="item in selectData"
                 :label="item.label"
                 :value="item.id"
-                :key="item.id"
+                :key="item.id + ind"
               ></el-option>
             </el-select>
             <el-tooltip
+              v-if="curEdit.type !== 'pareto'"
               :content="
-                formLabelAlign.LineYdata.length <= 1
+                formLabelAlign.BarYdata.length <= 1
                   ? '该指标不可删除,最少存在一组指标'
                   : '删除该指标'
               "
@@ -356,8 +423,8 @@
             >
               <el-button
                 type="text"
-                :disabled="formLabelAlign.LineYdata.length <= 1"
-                @click="removeYdata(ind, 'line')"
+                :disabled="formLabelAlign.BarYdata.length <= 1"
+                @click="removeYdata(ind, 'bar')"
               >
                 <i
                   class="el-icon-delete"
@@ -406,7 +473,7 @@
                 v-for="item in selectData"
                 :label="item.label"
                 :value="item.id"
-                :key="item.id"
+                :key="item.id + ind"
               ></el-option>
             </el-select>
             <el-tooltip
@@ -463,7 +530,7 @@
                 v-for="item in selectData"
                 :label="item.label"
                 :value="item.id"
-                :key="item.id"
+                :key="item.id + ind"
               ></el-option>
             </el-select>
             <el-tooltip
@@ -493,26 +560,45 @@
       </el-form-item>
       <el-form-item
         label="X轴名称"
-        v-if="curEdit.type !== 'pie' && curEdit.type !== 'radar'"
+        v-if="
+          curEdit.type !== 'pie' &&
+          curEdit.type !== 'radar' &&
+          curEdit.type !== 'roseChart' &&
+          curEdit.type !== 'sankeyDiagram'
+        "
       >
         <el-input v-model="formLabelAlign.Xlable"></el-input>
       </el-form-item>
       <el-form-item
         label="Y轴名称"
-        v-if="curEdit.type !== 'pie' && curEdit.type !== 'radar'"
+        v-if="
+          curEdit.type !== 'pie' &&
+          curEdit.type !== 'radar' &&
+          curEdit.type !== 'roseChart' &&
+          curEdit.type !== 'pareto' &&
+          curEdit.type !== 'sankeyDiagram'
+        "
       >
         <el-input v-model="formLabelAlign.Ylable"></el-input>
       </el-form-item>
+      <el-form-item label="柱Y轴名称" v-if="curEdit.type === 'pareto'">
+        <el-input v-model="formLabelAlign.YRightLable"></el-input>
+      </el-form-item>
+      <el-form-item label="线Y轴名称" v-if="curEdit.type === 'pareto'">
+        <el-input v-model="formLabelAlign.YLeftLable"></el-input>
+      </el-form-item>
     </el-form>
     <div style="margin: 20px 0">
       <el-divider style="height: 2px"></el-divider>
     </div>
-    <el-collapse v-if="formLabelAlign.Ydata[0].data.length > 0">
+    <el-collapse
+      v-if="filteredYData.length > 0 && filteredYData[0].data.length > 0"
+    >
       <el-collapse-item
-        v-for="(itemFilter, filterInd) in formLabelAlign.Ydata"
+        v-for="(itemFilter, filterInd) in filteredYData"
         :title="itemFilter.label || `数据筛选`"
         :name="itemFilter.id"
-        :key="itemFilter.id"
+        :key="itemFilter.id + filterInd"
       >
         <el-form
           label-position="top"
@@ -596,8 +682,16 @@ import {
   handleScatterChartLogic,
   handleRadarChartLogic,
   handleCpChartLogic,
+  handleRoseChartChartLogic,
+  handlePieChartLogic,
+  handlestackedBarChartLogic,
+  handleParetoChartLogic,
+  handleBoxPlotChartLogic,
+  handleSankeyDiagramPlotChartLogic,
+  handleHeatmapPlotChartLogic,
 } from "./chartLogic/index";
 import Vue from "vue";
+import { constructNow } from "date-fns";
 export default {
   name: "title",
   props: {
@@ -699,6 +793,8 @@ export default {
         text: "",
         Xlable: "",
         Ylable: "",
+        YRightLable: "",
+        YLeftLable: "",
       },
       disabled: true,
       selectData: [], //可选择的数据
@@ -709,8 +805,33 @@ export default {
       currentChartList: "currentChartList",
       dataBaseCheckList: "dataBaseCheckList",
     }),
+    filteredYData() {
+      const { type } = this.curEdit;
+      const { BarYdata, LineYdata, ScatterYdata, Ydata } = this.formLabelAlign;
+      if (type === "pareto") {
+        console.log([...BarYdata, ...LineYdata], "[...BarYdata, ...LineYdata]");
+        return [...LineYdata, ...BarYdata];
+      } else if (type === "Cp") {
+        return [...LineYdata, ...ScatterYdata];
+      } else if (
+        [
+          "bar",
+          "line",
+          "radar",
+          "scatter",
+          "pie",
+          "roseChart",
+          "stackedBar",
+          "boxPlot",
+          "sankeyDiagram",
+          "Heatmap",
+        ].includes(type)
+      ) {
+        return Ydata;
+      }
+      return []; // 默认返回空数组
+    },
   },
-
   watch: {
     curEdit() {
       this.changeData();
@@ -736,18 +857,44 @@ export default {
       deep: true, // 深度监听
     },
   },
-  mounted() {
-    this.changeData();
-  },
   methods: {
     ...mapMutations("dragChart", [
       "updateChart",
       "setCurEdit",
       "setFormFilterAlignData",
     ]),
+    handleLatitude(type) {
+      switch (type) {
+        case "init":
+          console.log(this.curEdit.type, this.formLabelAlign.Xdata.length);
+          if (
+            (this.curEdit.type === "sankeyDiagram" ||
+              this.curEdit.type === "Heatmap") &&
+            this.formLabelAlign.Xdata.length >= 2
+          ) {
+            this.$message.warning(
+              "纬度请根据上方红色字提示的进行添加且只能添加两个纬度标签"
+            );
+            return;
+          }
+          this.formLabelAlign.Xdata.push({ lable: "", data: [], id: "" });
+          break;
+      }
+    },
     handleMetrics(type) {
+      console.log(type, "tianjia yige");
       switch (type) {
         case "init":
+          if (
+            this.curEdit.type === "boxPlot" &&
+            this.formLabelAlign.Ydata.length >= 5
+          ) {
+            this.$message.warning(
+              "箱线图指标只允许添加最小值, Q1, 中位数, Q3, 最大值几位"
+            );
+            return;
+          }
+
           this.formLabelAlign.Ydata.push({ lable: "", data: [], id: "" });
           this.formFilterAlign.push({
             filters: [],
@@ -875,11 +1022,55 @@ export default {
       });
       return axisData;
     },
+    removeYdata(index, type) {
+      const { BarYdata, LineYdata, ScatterYdata, Ydata } = this.formLabelAlign;
+      switch (type) {
+        case "init":
+          this.formLabelAlign.Ydata.splice(index, 1); // 删除当前项
+          break;
+        case "bar":
+          this.formLabelAlign.BarYdata.splice(index, 1); // 删除当前项
 
+          break;
+        case "line":
+          this.formLabelAlign.LineYdata.splice(index, 1); // 删除当前项
+          if (this.curEdit.type === "Cp") {
+            this.formFilterAlign.splice(index, 1);
+          }
+          //这里需要处理this.formFilterAlign.filter(item)
+          break;
+        case "scatter":
+          if (this.curEdit.type === "Cp") {
+            this.formFilterAlign.splice(
+              this.formLabelAlign.LineYdata.length + index,
+              1
+            );
+          }
+          this.formLabelAlign.ScatterYdata.splice(index, 1); // 删除当前项
+          break;
+      }
+    },
+    removeXdata(index, type) {
+      switch (type) {
+        case "init":
+          this.formLabelAlign.Xdata.splice(index, 1); // 删除当前项
+          break;
+        case "bar":
+          this.formLabelAlign.BarXdata.splice(index, 1); // 删除当前项
+          break;
+        case "line":
+          this.formLabelAlign.LineXdata.splice(index, 1); // 删除当前项
+          break;
+        case "scatter":
+          this.formLabelAlign.ScatterXdata.splice(index, 1); // 删除当前项
+          break;
+      }
+    },
     changeData() {
       if (this.$refs.form) {
         this.$refs.form.resetFields();
       }
+      console.log(this.formFilterAlign, "this.formFilterAlign 默认");
       // 图表内容回显图表配置赋值
       if (this.curEdit && this.curEdit.option) {
         // 使用 this.$set 替代直接赋值
@@ -887,6 +1078,14 @@ export default {
           text: this.curEdit.option.title?.text || "",
           Xlable: this.curEdit.option.xAxis?.name || "",
           Ylable: this.curEdit.option.yAxis?.name || "",
+          YRightLable:
+            this.curEdit.type === "pareto"
+              ? this.curEdit.option.yAxis[1].name
+              : "",
+          YLeftLable:
+            this.curEdit.type === "pareto"
+              ? this.curEdit.option.yAxis[0].name
+              : "",
           Xdata:
             this.curEdit.Xdata.length > 0
               ? this.curEdit.Xdata
@@ -969,26 +1168,79 @@ export default {
                 ],
         });
         // 查找是否存在数据
-        const index = this.curEdit.formFilterAlignData.findIndex(
+        const index = this.currentChartList.findIndex(
           (item) => item.id === this.curEdit.id
         );
         if (index !== -1) {
           this.$set(
             this,
             "formFilterAlign",
-            this.curEdit.formFilterAlignData[index]?.data
+            this.curEdit.formFilterAlignData.length > 0
+              ? this.curEdit.formFilterAlignData
+              : this.curEdit.type === "Cp" || this.curEdit.type === "pareto"
+              ? [
+                  {
+                    filters: [],
+                    filterType1: "",
+                    number1: null,
+                    filterType2: "",
+                    number2: null,
+                    radio: null,
+                  },
+                  {
+                    filters: [],
+                    filterType1: "",
+                    number1: null,
+                    filterType2: "",
+                    number2: null,
+                    radio: null,
+                  },
+                ]
+              : [
+                  {
+                    filters: [],
+                    filterType1: "",
+                    number1: null,
+                    filterType2: "",
+                    number2: null,
+                    radio: null,
+                  },
+                ]
           );
         } else {
-          this.$set(this, "formFilterAlign", [
-            {
-              filters: [],
-              filterType1: "",
-              number1: null,
-              filterType2: "",
-              number2: null,
-              radio: null,
-            },
-          ]);
+          this.$set(
+            this,
+            "formFilterAlign",
+            this.curEdit.type === "Cp" || this.curEdit.type === "pareto"
+              ? [
+                  {
+                    filters: [],
+                    filterType1: "",
+                    number1: null,
+                    filterType2: "",
+                    number2: null,
+                    radio: null,
+                  },
+                  {
+                    filters: [],
+                    filterType1: "",
+                    number1: null,
+                    filterType2: "",
+                    number2: null,
+                    radio: null,
+                  },
+                ]
+              : [
+                  {
+                    filters: [],
+                    filterType1: "",
+                    number1: null,
+                    filterType2: "",
+                    number2: null,
+                    radio: null,
+                  },
+                ]
+          );
         }
       } else {
         this.$message.warning("请选择一个图表进行编辑");
@@ -998,7 +1250,6 @@ export default {
     changeChart(isFilter) {
       if (!this.curEdit?.option) return; // 确保 curEdit 和 option 存在
       const item = JSON.parse(JSON.stringify(this.curEdit));
-
       if (this.curEdit.type === "scatter" || this.curEdit.type === "radar") {
         //判断散点选择的是否为number 或可转为number
         const isAllNumbers = (data) =>
@@ -1058,6 +1309,62 @@ export default {
           isFilter,
           this.curEdit.type
         );
+      } else if (this.curEdit.type === "roseChart") {
+        handleRoseChartChartLogic(
+          item,
+          this.formLabelAlign,
+          this.formFilterAlign,
+          isFilter,
+          this.curEdit.type
+        );
+      } else if (this.curEdit.type === "pie") {
+        handlePieChartLogic(
+          item,
+          this.formLabelAlign,
+          this.formFilterAlign,
+          isFilter,
+          this.curEdit.type
+        );
+      } else if (this.curEdit.type === "stackedBar") {
+        handlestackedBarChartLogic(
+          item,
+          this.formLabelAlign,
+          this.formFilterAlign,
+          isFilter,
+          this.curEdit.type
+        );
+      } else if (this.curEdit.type === "pareto") {
+        handleParetoChartLogic(
+          item,
+          this.formLabelAlign,
+          this.formFilterAlign,
+          isFilter,
+          this.curEdit.type
+        );
+      } else if (this.curEdit.type === "boxPlot") {
+        handleBoxPlotChartLogic(
+          item,
+          this.formLabelAlign,
+          this.formFilterAlign,
+          isFilter,
+          this.curEdit.type
+        );
+      } else if (this.curEdit.type === "sankeyDiagram") {
+        handleSankeyDiagramPlotChartLogic(
+          item,
+          this.formLabelAlign,
+          this.formFilterAlign,
+          isFilter,
+          this.curEdit.type
+        );
+      } else if (this.curEdit.type === "Heatmap") {
+        handleHeatmapPlotChartLogic(
+          item,
+          this.formLabelAlign,
+          this.formFilterAlign,
+          isFilter,
+          this.curEdit.type
+        );
       }
       //设置仓库
       this.setFormFilterAlignData({
@@ -1066,42 +1373,13 @@ export default {
       });
       this.updateChart({
         ...item,
-        Ydata: this.formLabelAlign.Ydata,
+        LineYdata: this.formLabelAlign.LineYdata,
+        ScatterYdata: this.formLabelAlign.ScatterYdata,
+        BarYdata: this.formLabelAlign.BarYdata,
+        Ydata: this.formLabelAlign.Ydata, //还是给所有的数据保存起来了,并不是过滤后的数据
         formFilterAlignData: this.formFilterAlign,
       }); // 更新图表
     },
-    removeYdata(index, type) {
-      switch (type) {
-        case "init":
-          this.formLabelAlign.Ydata.splice(index, 1); // 删除当前项
-          break;
-        case "bar":
-          this.formLabelAlign.BarYdata.splice(index, 1); // 删除当前项
-          break;
-        case "line":
-          this.formLabelAlign.LineYdata.splice(index, 1); // 删除当前项
-          break;
-        case "scatter":
-          this.formLabelAlign.ScatterYdata.splice(index, 1); // 删除当前项
-          break;
-      }
-    },
-    removeXdata(index, type) {
-      switch (type) {
-        case "init":
-          this.formLabelAlign.Xdata.splice(index, 1); // 删除当前项
-          break;
-        case "bar":
-          this.formLabelAlign.BarXdata.splice(index, 1); // 删除当前项
-          break;
-        case "line":
-          this.formLabelAlign.LineXdata.splice(index, 1); // 删除当前项
-          break;
-        case "scatter":
-          this.formLabelAlign.ScatterXdata.splice(index, 1); // 删除当前项
-          break;
-      }
-    },
   },
 };
 </script>

+ 32 - 30
src/views/performance/components/custonAsCom/dragChart/components/chartsAttributes.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-11-01 10:14:11
- * @LastEditTime: 2024-11-20 10:21:34
+ * @LastEditTime: 2024-11-27 15:39:28
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartsContent.vue
@@ -81,8 +81,8 @@ export default {
       currentView: "",
       svgIcon: [
         {
-          type: "bar",
-          name: "直方图",
+          type: "Cp",
+          name: "散点折线图",
         },
         {
           type: "scatter",
@@ -93,53 +93,55 @@ export default {
           name: "折线图",
         },
         {
-          type: "Cp",
-          name: "散点折线图",
+          type: "pie",
+          name: "图",
         },
         {
-          type: "stackedBar",
-          name: "堆叠柱状图",
+          type: "roseChart",
+          name: "玫瑰图",
         },
         {
-          type: "pareto",
-          name: "帕累托图",
+          type: "radar",
+          name: "雷达图",
         },
+
         {
           type: "sankeyDiagram",
           name: "流图",
         },
-        // {
-        //   type: "hexbin",
-        //   name: "蜂巢图",
-        // },
-        // {
-        //   type: "timeSeries",
-        //   name: "时间序列图",
-        // },
-        {
-          type: "waterfall",
-          name: "瀑布图",
-        },
         {
           type: "boxPlot",
           name: "箱线图",
         },
+
         {
-          type: "radar",
-          name: "雷达图",
+          type: "Heatmap",
+          name: "热力图",
         },
         {
-          type: "pie",
-          name: "图",
+          type: "bar",
+          name: "直方图",
         },
         {
-          type: "roseChart",
-          name: "玫瑰图",
+          type: "stackedBar",
+          name: "堆叠柱状图",
         },
         {
-          type: "Heatmap",
-          name: "热力图",
+          type: "pareto",
+          name: "帕累托图",
         },
+        // {
+        //   type: "hexbin",
+        //   name: "蜂巢图",
+        // },
+        // {
+        //   type: "timeSeries",
+        //   name: "时间序列图",
+        // },
+        // {
+        //   type: "waterfall",
+        //   name: "瀑布图",
+        // },
       ],
     };
   },
@@ -191,7 +193,7 @@ export default {
 <style scoped lang="scss">
 .chartContiner {
   background-color: pink;
-  width: 200px;
+  width: 210px;
   height: 100%;
 
   ::v-deep .card {

+ 17 - 13
src/views/performance/components/custonAsCom/dragChart/components/chartsData.vue

@@ -135,19 +135,23 @@ export default {
         node.level === 1
           ? h("span", [
               h(
-                "el-checkbox",
-                {
-                  props: {
-                    value: node.checked,
-                    indeterminate: node.indeterminate, // 用于半选状态
-                  },
-                  on: {
-                    change: (val) => {
-                      this.handleParentNodeChange(node, val);
-                    },
-                  },
-                },
-                [data.label]
+                "span",
+                data.label
+                // [
+                //   // "el-checkbox",
+                //   // {
+                //   //   props: {
+                //   //     value: node.checked,
+                //   //     indeterminate: node.indeterminate, // 用于半选状态
+                //   //   },
+                //   //   on: {
+                //   //     change: (val) => {
+                //   //       this.handleParentNodeChange(node, val);
+                //   //     },
+                //   //   },
+                //   // },
+                //   data.label
+                // ]
               ),
             ])
           : h("span", data.label),

+ 222 - 24
src/views/performance/customAnalysis.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="content">
+  <div class="content" v-loading="loading">
     <el-tabs
       ref="tabs"
       tab-position="left"
@@ -19,7 +19,7 @@
                 :before-upload="checkFileType"
                 :show-file-list="false"
               >
-                <div class="uploadBoxContent">
+                <div class="uploadBoxContent" inert>
                   <svg-icon
                     icon-class="table(2)"
                     style="width: 40px; height: 40px; margin-right: 10px"
@@ -87,7 +87,7 @@
         <DataTable ref="dataTableRef"></DataTable>
       </el-tab-pane>
       <el-tab-pane name="compute">
-        <span slot="label" class="iconFont" @click.stop="dialogVisible = true">
+        <span slot="label" class="iconFont" @click.stop="handleUploadBox">
           <el-tooltip
             class="item"
             effect="dark"
@@ -137,21 +137,31 @@
         class="demo-ruleForm"
       >
         <el-form-item label="选择数据列表:" prop="region">
-          <el-select
+          <el-cascader
+            v-model="ruleForm.region"
+            size="small"
+            placeholder="试试搜索:"
+            collapse-tags
+            :options="options"
+            filterable
+          >
+            <!-- :props="{ multiple: true }" -->
+          </el-cascader>
+          <!-- <el-select
             v-model="ruleForm.region"
             placeholder="请选择活动区域"
             size="small"
           >
             <el-option label="区域一" value="shanghai"></el-option>
             <el-option label="区域二" value="beijing"></el-option>
-          </el-select>
+          </el-select> -->
         </el-form-item>
         <el-form-item label="选择数据范围:">
           <div class="demo-input-suffix">
             <el-input
               size="small"
               type="number"
-              placeholder="最小值"
+              placeholder="开始行"
               v-model="ruleForm.min"
             >
             </el-input>
@@ -159,7 +169,7 @@
             <el-input
               size="small"
               type="number"
-              placeholder="最大值"
+              placeholder="结束行"
               v-model="ruleForm.max"
             >
             </el-input>
@@ -167,24 +177,23 @@
         </el-form-item>
         <el-form-item label="选择特征值计算:" prop="type">
           <el-checkbox-group v-model="ruleForm.type">
-            <el-checkbox label="有效值" name="type"></el-checkbox>
-            <el-checkbox label="平均值" name="type"></el-checkbox>
-            <el-checkbox label="最大值" name="type"></el-checkbox>
-            <el-checkbox label="最小值" name="type"></el-checkbox>
-            <el-checkbox label="峰值" name="type"></el-checkbox>
-            <el-checkbox label="峰峰值" name="type"></el-checkbox>
-            <el-checkbox label="峰值指标" name="type"></el-checkbox>
-            <el-checkbox label="峰度指标" name="type"></el-checkbox>
-            <el-checkbox label="歪度指标" name="type"></el-checkbox>
-            <el-checkbox label="裕度指标" name="type"></el-checkbox>
-            <el-checkbox label="脉冲指标" name="type"></el-checkbox>
-            <el-checkbox label="波形指标" name="type"></el-checkbox>
+            <el-checkbox label="有效值" name="Xrms"></el-checkbox>
+            <el-checkbox label="平均值" name="Mean"></el-checkbox>
+            <el-checkbox label="最大值" name="Max"></el-checkbox>
+            <el-checkbox label="最小值" name="Min"></el-checkbox>
+            <el-checkbox label="峰值" name="Xp"></el-checkbox>
+            <el-checkbox label="峰峰值" name="Xpp"></el-checkbox>
+            <el-checkbox label="峰度指标" name="Cf"></el-checkbox>
+            <el-checkbox label="歪度指标" name="Sk"></el-checkbox>
+            <el-checkbox label="裕度指标" name="Ce"></el-checkbox>
+            <el-checkbox label="脉冲指标" name="If"></el-checkbox>
+            <el-checkbox label="波形指标" name="Sf"></el-checkbox>
           </el-checkbox-group>
         </el-form-item>
       </el-form>
       <span slot="footer" class="dialog-footer">
-        <el-button @click="dialogVisible = false">取 消</el-button>
-        <el-button type="primary" @click="dialogVisible = false"
+        <el-button @click="resetForm">取 消</el-button>
+        <el-button type="primary" @click="submitComputedFn('ruleForm')"
           >确 定</el-button
         >
       </span>
@@ -203,9 +212,10 @@ import DragChart from "./components/custonAsCom/dragChart/index.vue";
 import AssociatedFields from "./components/custonAsCom/AssociatedFields.vue";
 import Papa from "papaparse";
 import * as XLSX from "xlsx";
-import { storeSetData } from "@/utils/indexedDb";
+import { storeSetData, getDataFromIndexedDB } from "@/utils/indexedDb";
 import { format } from "date-fns";
 import { mapMutations, mapState } from "vuex";
+import axios from "axios";
 export default {
   components: {
     DataTable,
@@ -215,6 +225,8 @@ export default {
   },
   data() {
     return {
+      options: [],
+      loading: false,
       db: null,
       activeName: "chart",
       showDatabaseTable: false,
@@ -249,6 +261,22 @@ export default {
     ...mapState("dragChart", {
       updateTriggerGetData: "updateTriggerGetData",
     }),
+    selectedNames() {
+      const nameMap = {
+        有效值: "Xrms",
+        平均值: "Mean",
+        最大值: "Max",
+        最小值: "Min",
+        峰值: "Xp",
+        峰峰值: "Xpp",
+        峰度指标: "Cf",
+        歪度指标: "Sk",
+        裕度指标: "Ce",
+        脉冲指标: "If",
+        波形指标: "Sf",
+      };
+      return this.ruleForm.type.map((label) => nameMap[label]);
+    },
   },
   watch: {
     updateTriggerGetData: function (newVal) {
@@ -265,6 +293,7 @@ export default {
       "setTriggerGetData",
       "setUpdateTriggerGetData",
     ]),
+
     async initDB() {
       return new Promise((resolve, reject) => {
         const request = indexedDB.open("FileDataDB", 2); // 使用较高版本
@@ -277,7 +306,7 @@ export default {
             db.createObjectStore("files", { keyPath: "id" });
           }
         };
-        request.onsuccess = (event) => {
+        request.onsuccess = async (event) => {
           this.db = event.target.result;
           console.log("数据库已成功初始化。");
           resolve();
@@ -288,6 +317,164 @@ export default {
         };
       });
     },
+    async handleUploadBox() {
+      this.dialogVisible = true;
+      const indexeddbData = await getDataFromIndexedDB();
+      this.options = indexeddbData.map((item) => {
+        return {
+          value: item.fileId,
+          label: item.filename,
+          children: Object.keys(item.fileData[0]).map((val) => ({
+            value: val,
+            label: val,
+          })),
+        };
+      });
+      console.log(this.options, "调用数据");
+    },
+    async submitComputedFn(formName) {
+      try {
+        // 1. 验证表单
+        if (!(await this.validateForm(formName))) return;
+        if (Number(this.ruleForm.max) < Number(this.ruleForm.min)) {
+          this.$message.error("开始行不可以大于结束行");
+          return;
+        }
+        // 2. 获取 IndexedDB 数据
+        const indexeddbData = await getDataFromIndexedDB();
+        const region = this.getRegionData(indexeddbData);
+
+        if (!region.length) {
+          console.warn("当前选择的列未找到数据");
+          return;
+        }
+
+        // 3. 调用算法接口
+        const resData = await this.fetchAlgorithmData(region[0]);
+
+        // 4. 筛选和处理数据
+        const filteredData = this.filterResponseData(resData);
+
+        // 5. 构建导出数据
+        const resObj = this.buildExportData(indexeddbData, filteredData);
+        this.storeData(resObj);
+        this.resetForm();
+        console.log(resObj, "resObj");
+      } catch (error) {
+        console.error("提交过程中发生错误:", error);
+      }
+    },
+
+    async validateForm(formName) {
+      try {
+        const valid = await this.$refs[formName].validate();
+        if (!valid) {
+          console.warn("表单验证失败");
+          return false;
+        }
+        return true;
+      } catch (error) {
+        console.error("表单验证错误:", error);
+        return false;
+      }
+    },
+    //生成数据
+    getRegionData(indexeddbData) {
+      return indexeddbData
+        .filter((item) => item.fileId === this.ruleForm.region[0])
+        .map((item) =>
+          item.fileData.map((val, ind) => ({
+            index: ind + 1,
+            value: val[this.ruleForm.region[1]],
+          }))
+        );
+    },
+    //调用算法接口
+    async fetchAlgorithmData(regionData) {
+      try {
+        const res = await axios.post("/sAlgorithm/CalculateFeatures/", {
+          data: regionData,
+          start_index: Number(this.ruleForm.min),
+          end_index: Number(this.ruleForm.max),
+        });
+        return JSON.parse(res.data, "res");
+      } catch (error) {
+        console.error("算法接口调用失败:", error);
+        throw error;
+      }
+    },
+    //过滤字段
+    filterResponseData(resData) {
+      return resData.map((item) => {
+        const filteredItem = { ...item };
+        Object.keys(filteredItem).forEach((key) => {
+          if (
+            this.selectedNames.length > 0 &&
+            !this.selectedNames.includes(key) &&
+            key !== "index" &&
+            key !== "value"
+          ) {
+            delete filteredItem[key];
+          }
+        });
+        return filteredItem;
+      });
+    },
+    //处理算法返回的数据
+    buildExportData(indexeddbData, resData) {
+      const nameMap = {
+        有效值: "Xrms",
+        平均值: "Mean",
+        最大值: "Max",
+        最小值: "Min",
+        峰值: "Xp",
+        峰峰值: "Xpp",
+        峰度指标: "Cf",
+        歪度指标: "Sk",
+        裕度指标: "Ce",
+        脉冲指标: "If",
+        波形指标: "Sf",
+      };
+      const resObj = indexeddbData.find(
+        (item) => item.fileId === this.ruleForm.region[0]
+      );
+      if (!resObj) {
+        console.warn("未找到对应文件数据");
+        return {};
+      }
+      resObj.filename =
+        format(new Date(), "yyyyMMdd-HH:mm:ss") + resObj.fileOldName;
+      resObj.fileId = new Date().getTime();
+      resObj.fileData = resData.map((item) => {
+        const dynamicKeys = this.ruleForm.type.reduce((acc, label) => {
+          const fieldName = this.selectedNames.find(
+            (name) => nameMap[label] === name
+          );
+          if (fieldName) {
+            acc[label] = item[fieldName];
+          }
+          return acc;
+        }, {});
+
+        return {
+          [this.ruleForm.region[1]]: item.value,
+          ...dynamicKeys,
+        };
+      });
+
+      return resObj;
+    },
+
+    resetForm() {
+      this.ruleForm = {
+        max: "",
+        min: "",
+        region: [],
+        type: [],
+      };
+      this.dialogVisible = false; // 重置表单状态
+    },
+
     async storeData(newFileData) {
       await storeSetData(this.db, "files", "fileDataArray", newFileData, () => {
         this.setTriggerGetData(true);
@@ -335,10 +522,12 @@ export default {
             };
             if (results.data.length > 0) {
               this.storeData(fileData);
+              this.loading = false;
             }
           },
           error: (error) => {
             console.error("Error parsing CSV:", error);
+            this.loading = false;
           },
         });
       } else {
@@ -358,6 +547,7 @@ export default {
             };
             if (sheetData.length > 0) {
               this.storeData(fileData);
+              this.loading = false;
             }
             // console.log("Parsed Excel Sheet Data:", sheetData);
             // 可以进一步处理解析后的数据
@@ -376,8 +566,16 @@ export default {
         file.name.endsWith(".xlsx");
       if (!isPdf) {
         this.$message.error("只能上传csv文件或xlsx文件");
+        return false;
+      }
+      // 判断文件大小(以字节为单位,100kB = 102400字节)
+      const maxSize = 50 * 1024; // 100kB
+      if (file.size > maxSize) {
+        this.$message.error("文件大小不能超过50kB");
+        return false;
       }
-      return isPdf;
+      this.loading = true;
+      return true;
     },
   },
   async mounted() {

+ 20 - 7
vue.config.js

@@ -72,6 +72,9 @@ module.exports = {
         pathRewrite: {
           "^/api": "", // 需要regit write重写的,
         },
+        onProxyReq(proxyReq, req, res) {
+          console.log("Proxying request to:", proxyReq.path); // 打印代理请求路径
+        },
       },
       "/transDataWeb": {
         target: "http://192.168.50.241:9000/trans_data_web",
@@ -80,13 +83,23 @@ module.exports = {
           "^/transDataWeb": "", // 需要regit write重写的,
         },
       },
-      // "/downLoadApi": {
-      //   target: "http://192.168.50.241:8080", //http://192.168.50.241:8080/
-      //   changeOrigin: true,
-      //   pathRewrite: {
-      //     "^/downLoadApi": "", // 需要rewrite重写的,z
-      //   },
-      // },
+      "/sAlgorithm": {
+        target: "http://192.168.5.28:8666", // 目标地址
+        changeOrigin: true,
+        pathRewrite: {
+          "^/sAlgorithm": "", // 如果后端需要 `/api` 前缀
+        },
+        onProxyReq(proxyReq, req, res) {
+          console.log("Proxying request to:", proxyReq.path); // 打印代理请求路径
+        },
+      },
+      "/databaseApi": {
+        target: "http://192.168.5.18:3000",
+        changeOrigin: true,
+        pathRewrite: {
+          "^/databaseApi": "", // 如果后端需要 `/api` 前缀
+        },
+      },
     },
   },
 

Some files were not shown because too many files changed in this diff