浏览代码

toolbox图形组件

liujiejie 7 月之前
父节点
当前提交
f60052d8d8

+ 30 - 40
src/assets/js/constants/echarts-config/funnelPlot2.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-08-25 15:54:37
- * @LastEditTime: 2025-08-25 16:05:42
+ * @LastEditTime: 2025-08-26 14:01:52
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/assets/js/constants/echarts-config/funnelPlot2.js
@@ -10,9 +10,9 @@ import { colorPalette } from "../color";
 
 export const option = {
   color: colorPalette,
-  //   color: ["#4CAF50", "#2196F3", "#FF9800", "#E91E63", "#9C27B0"],
+
   title: {
-    text: "风机运行状态分析",
+    text: "风机性能分析 - TSR/Cp^(1/3) 比值",
     left: "center",
   },
   tooltip: {
@@ -27,49 +27,39 @@ export const option = {
     },
   },
   legend: {
-    top: "5%",
-    data: ["正常运行", "轻微故障", "重度故障", "检修中", "停机"],
+    top: "10%",
+    data: ["理想状态", "轻微偏离", "中等偏离", "严重偏离", "故障风险"],
   },
   series: [
     {
-      name: "风机状态",
+      name: "风机性能状态",
       type: "funnel",
-      left: "10%",
-      top: 80,
-      bottom: 60,
-      width: "80%",
-      min: 0,
-      max: 120,
-      minSize: "0%",
-      maxSize: "100%",
-      sort: "descending",
-      gap: 2,
-      label: {
-        show: true,
-        position: "inside",
-      },
-      labelLine: {
-        length: 10,
-        lineStyle: {
-          width: 1,
-          type: "solid",
+      data: [
+        {
+          value: 40,
+          name: "理想状态",
+          desc: "TSR/Cp^(1/3) 比值接近理论最优值,风机运行效率高,设备状态良好",
         },
-      },
-      itemStyle: {
-        borderColor: "#fff",
-        borderWidth: 1,
-      },
-      emphasis: {
-        label: {
-          fontSize: 18,
+        {
+          value: 25,
+          name: "轻微偏离",
+          desc: "比值略高或略低,可能是风速波动或轻微负荷变化造成,性能可接受",
+        },
+        {
+          value: 20,
+          name: "中等偏离",
+          desc: "比值偏离最佳范围,可能存在控制策略不足,需要优化功率曲线",
+        },
+        {
+          value: 10,
+          name: "严重偏离",
+          desc: "比值明显异常,可能存在叶片积冰、偏航误差或传感器故障",
+        },
+        {
+          value: 5,
+          name: "故障风险",
+          desc: "比值极度异常,需立即停机检查,可能涉及重大故障",
         },
-      },
-      data: [
-        { value: 100, name: "正常运行" },
-        { value: 80, name: "轻微故障" },
-        { value: 50, name: "重度故障" },
-        { value: 30, name: "检修中" },
-        { value: 20, name: "停机" },
       ],
     },
   ],

+ 2 - 2
src/store/dragChart.js

@@ -66,13 +66,13 @@ export default {
     },
     // 当前画布添加图表
     addChart(state, data) {
-      console.log(data, "data");
-      //   console.log("当前画布添加图表", data);
       if (state.currentChartList.length <= 0) {
+        // state.currentChartList.push(data);
         state.currentChartList.push({ ...data, index: 0 });
       } else {
         state.currentChartList.push(data);
       }
+      console.log(state.currentChartList, "state.currentChartList");
     },
     //更新数据配置当前选中数据
     updateDataBase(state, data) {

+ 0 - 140
src/utils/vuexIndexedDBPlugin.js

@@ -1,143 +1,3 @@
-// import { saveData, getData } 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;
-// };
-
-// // 修改后的 openDB 方法
-// const openDB = (dbName, version) => {
-//   return new Promise((resolve, reject) => {
-//     const request = indexedDB.open(dbName, version);
-
-//     request.onsuccess = () => {
-//       resolve(request.result);
-//     };
-
-//     request.onerror = (error) => {
-//       reject(error);
-//     };
-
-//     request.onupgradeneeded = (event) => {
-//       const db = event.target.result;
-
-//       // 创建对象存储(如果不存在)
-//       if (!db.objectStoreNames.contains("dragChart_chunk_meta")) {
-//         db.createObjectStore("dragChart_chunk_meta");
-//       }
-//       if (!db.objectStoreNames.contains("dragChart_compressed")) {
-//         db.createObjectStore("dragChart_compressed");
-//       }
-//       if (!db.objectStoreNames.contains("myIndexedDB")) {
-//         db.createObjectStore("myIndexedDB");
-//       }
-//     };
-//   });
-// };
-
-// // vuex 插件
-// 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,
-//         });
-//       }
-//     });
-//   });
-
-//   // 订阅 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;
 import { saveData, getData } from "@/utils/indexedDb";
 import { Message } from "element-ui";
 

+ 3 - 1
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: 2025-08-25 14:49:24
+ * @LastEditTime: 2025-08-26 11:17:33
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/utils/chartLogic/index.js
@@ -19,6 +19,7 @@ import { handleBoxPlotChartLogic } from "./modules/boxPlot";
 import { handleSankeyDiagramPlotChartLogic } from "./modules/sankeyDiagram"; //流图 桑基图
 import { handleHeatmapPlotChartLogic } from "./modules/Heatmap";
 import { handlHorizontalStackedBar1ChartLogic } from "./modules/horizontalStackedBar1";
+import { handleFunnelPlot2Chart } from "./modules/funnelPlot2";
 export {
   handleBarChartLogic,
   handleScatterChartLogic,
@@ -32,4 +33,5 @@ export {
   handleSankeyDiagramPlotChartLogic,
   handleHeatmapPlotChartLogic,
   handlHorizontalStackedBar1ChartLogic,
+  handleFunnelPlot2Chart,
 };

+ 54 - 12
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/funnelPlot2.js

@@ -1,22 +1,23 @@
 /*
  * @Author: your name
  * @Date: 2025-08-25 15:38:10
- * @LastEditTime: 2025-08-25 16:18:38
+ * @LastEditTime: 2025-08-26 15:24:28
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartLogic/modules/funnelPlot2.js
  */
 import { filterData } from "../dargChartFIlter";
-import { getFormattedLabels } from "../../configFn";
 
 export function handleFunnelPlot2Chart(
   item,
   formLabelAlign,
   formFilterAlign,
-  isFilter,
-  type
+  isFilter
 ) {
-  // 1. 数据筛选逻辑保持不变
+  console.log(item, "handleFunnelPlot2Chart");
+  let filteredYData;
+
+  // 1. 数据筛选逻辑
   if (isFilter === "filter") {
     const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
       label: yItem.label,
@@ -29,7 +30,8 @@ export function handleFunnelPlot2Chart(
           : val;
       }),
     }));
-    const filterList = filterResult.map((filteredItem, index) => {
+
+    filteredYData = filterResult.map((filteredItem, index) => {
       const filter = formFilterAlign[index];
       const { number1, number2 } = filter;
 
@@ -39,7 +41,6 @@ export function handleFunnelPlot2Chart(
       ) {
         return {
           label: filteredItem.label,
-          id: filteredItem.id,
           data: filteredItem.data,
         };
       } else {
@@ -50,15 +51,56 @@ export function handleFunnelPlot2Chart(
         );
         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;
+    filteredYData = formLabelAlign.Ydata;
   }
+
+  const yLabel = filteredYData[0]?.label || "数据";
+  const rawData = filteredYData[0]?.data || [];
+
+  // 2. 数据分组统计:将相同温度或相近区间的数量聚合
+  const tempCountMap = {};
+  rawData.forEach((d) => {
+    const val = parseFloat(d[yLabel]) || 0;
+    // 保留 1 位小数,避免太多重复数据
+    const key = val.toFixed(1);
+    if (!tempCountMap[key]) {
+      tempCountMap[key] = 0;
+    }
+    tempCountMap[key] += 1;
+  });
+
+  // 3. 转换成漏斗图数据
+  const funnelSeriesData = Object.keys(tempCountMap)
+    .map((key) => ({
+      value: tempCountMap[key],
+      name: `${key}℃`,
+    }))
+    .sort((a, b) => b.value - a.value); // 按数量排序
+
+  // 4. 配置漏斗图
+  item.option = {
+    ...item.option,
+    legend: {
+      top: "10%",
+      data:
+        funnelSeriesData.length > 0
+          ? funnelSeriesData.map((d) => d.name)
+          : item.option.legend.data,
+    },
+    series: [
+      {
+        name: yLabel || item.series[0].name,
+        type: "funnel",
+        data:
+          funnelSeriesData.length > 0
+            ? funnelSeriesData
+            : item.option.series[0].data,
+      },
+    ],
+  };
 }

+ 19 - 6
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/chartTitle.vue

@@ -7,7 +7,7 @@
       ref="form"
     >
       <template v-if="curEdit.type !== 'Cp' && curEdit.type !== 'pareto'">
-        <el-form-item label="纬度标签">
+        <el-form-item label="纬度标签" v-if="curEdit.type !== 'funnelPlot2'">
           <div
             slot="label"
             style="
@@ -116,7 +116,8 @@
                 // curEdit.type !== 'roseChart' &&
                 curEdit.type !== 'pie' &&
                 curEdit.type !== 'doughnut' &&
-                curEdit.type !== 'sankeyDiagram'
+                curEdit.type !== 'sankeyDiagram' &&
+                curEdit.type !== 'funnelPlot2'
               "
             >
               <i
@@ -158,7 +159,8 @@
                   // curEdit.type !== 'roseChart' &&
                   curEdit.type !== 'pie' &&
                   curEdit.type !== 'doughnut' &&
-                  curEdit.type !== 'sankeyDiagram'
+                  curEdit.type !== 'sankeyDiagram' &&
+                  curEdit.type !== 'funnelPlot2'
                 "
                 :content="
                   formLabelAlign.Ydata.length <= 1
@@ -570,7 +572,8 @@
           curEdit.type !== 'doughnut' &&
           curEdit.type !== 'radar' &&
           curEdit.type !== 'roseChart' &&
-          curEdit.type !== 'sankeyDiagram'
+          curEdit.type !== 'sankeyDiagram' &&
+          curEdit.type !== 'funnelPlot2'
         "
       >
         <el-input v-model="formLabelAlign.Xlable"></el-input>
@@ -583,7 +586,8 @@
           curEdit.type !== 'radar' &&
           curEdit.type !== 'roseChart' &&
           curEdit.type !== 'pareto' &&
-          curEdit.type !== 'sankeyDiagram'
+          curEdit.type !== 'sankeyDiagram' &&
+          curEdit.type !== 'funnelPlot2'
         "
       >
         <el-input v-model="formLabelAlign.Ylable"></el-input>
@@ -702,6 +706,7 @@ import {
   handleSankeyDiagramPlotChartLogic,
   handleHeatmapPlotChartLogic,
   handlHorizontalStackedBar1ChartLogic,
+  handleFunnelPlot2Chart,
 } from "./chartLogic/index";
 import Vue from "vue";
 export default {
@@ -835,6 +840,7 @@ export default {
           // "doughnut",
           // "lineHighlight",
           "horizontalStackedBar1",
+          "funnelPlot2",
           "roseChart",
           "stackedBar",
           "boxPlot",
@@ -1307,7 +1313,6 @@ export default {
       // 确保标题和坐标轴对象存在
       item.option.title = item.option.title || {};
       Object.assign(item.option.title, { text: this.formLabelAlign.text });
-      console.log(this.curEdit.type, item, "this.curEdit.type");
       if (
         this.curEdit.type === "bar" ||
         this.curEdit.type === "line" ||
@@ -1371,6 +1376,14 @@ export default {
           isFilter,
           this.curEdit.type
         );
+      } else if (this.curEdit.type === "funnelPlot2") {
+        handleFunnelPlot2Chart(
+          item,
+          this.formLabelAlign,
+          this.formFilterAlign,
+          isFilter,
+          this.curEdit.type
+        );
       } else if (this.curEdit.type === "horizontalStackedBar1") {
         handlHorizontalStackedBar1ChartLogic(
           item,

文件差异内容过多而无法显示
+ 76 - 953
src/views/performance/components/custonAsCom/dragChart/components/chartConfig/form/toolbox.vue


+ 4 - 2
src/views/performance/components/custonAsCom/dragChart/components/chartsContent.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-11-01 10:14:11
- * @LastEditTime: 2024-12-31 14:54:06
+ * @LastEditTime: 2025-08-26 14:33:06
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/custonAsCom/dragChart/components/chartsContent.vue
@@ -160,6 +160,7 @@ export default {
     },
 
     onClickChart(item, index) {
+      console.log(item, "item onClickChart");
       this.setCurEdit(item);
       this.chartIndex = index;
       const nodes = document.getElementsByClassName("info");
@@ -171,8 +172,8 @@ export default {
       nodes[index].style.opacity = 0;
     },
     appendChart(type) {
-      // console.log("type  修改", type);
       const config = require(`@/assets/js/constants/echarts-config/${type}.js`);
+      console.log("type  修改", type);
       this.addChart(
         new ChartClass({
           option: config.option,
@@ -202,6 +203,7 @@ export default {
     },
 
     handleImportConfig(option) {
+      console.log(option, this.addChartType, "chartscontent.vue");
       this.addChart(
         new ChartClass({
           option: new Function("return " + option)() /* eslint-disable-line */,

部分文件因为文件数量过多而无法显示