ソースを参照

联调有功功率数据,进行前端展示

liujiejie 8 ヶ月 前
コミット
e4ee35859d

+ 5 - 6
src/components/map/index.vue

@@ -103,7 +103,7 @@
         </p>
       </div>
     </div>
-<!-- 这是测试 -->
+    <!-- 这是测试 -->
     <el-dialog title="异常描述" :visible.sync="dialogVisible" width="50%">
       <el-table :data="tableData" max-height="500" style="width: 100%">
         <el-table-column prop="analysisTypeName" label="类型" width="300">
@@ -111,7 +111,6 @@
         <el-table-column prop="errDesc" label="描述"> </el-table-column>
       </el-table>
     </el-dialog>
-    
   </div>
 </template>
 
@@ -197,9 +196,9 @@ export default {
         new TileLayer({
           source: new XYZ({
             // url: "http://127.0.0.1:8010/tiles/{z}/{x}/{y}.png", //本地
-            // url: "http://192.168.50.235/tiles/{z}/{x}/{y}.png", //内网
-           // url: "http://106.120.102.238:18000/tiles/{z}/{x}/{y}.png", //外网
-             url: "http://10.96.137.5:9080/tiles/{z}/{x}/{y}.png", 
+            url: "http://192.168.50.235/tiles/{z}/{x}/{y}.png", //内网
+            // url: "http://106.120.102.238:18000/tiles/{z}/{x}/{y}.png", //外网
+            //  url: "http://10.96.137.5:9080/tiles/{z}/{x}/{y}.png",
           }),
         }),
         new VectorLayer({
@@ -303,7 +302,7 @@ export default {
         if (features && features.length > 0) {
           const feature = features.at(0);
           const val = feature.get("data").val;
-          if (val == "1" || val =="30" ) {
+          if (val == "1" || val == "30") {
             this.hoverInfo = feature.get("data");
             this.hoverStyle.left = `${evt.pixel[0] + 10}px`;
             this.hoverStyle.top = `${evt.pixel[1] - 150}px`;

+ 194 - 80
src/views/performance/assetssDetail.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-05-27 09:25:45
- * @LastEditTime: 2024-09-13 11:03:49
+ * @LastEditTime: 2024-09-14 16:05:45
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/assetssDetail.vue
@@ -44,12 +44,16 @@
         <el-row type="flex" justify="space-between">
           <el-col :span="8">
             <el-form-item label="分析类型" prop="analysisTypeCode">
-              <el-select v-model="formInfo.analysisTypeCode" size="small">
+              <el-select
+                v-model="formInfo.analysisTypeCode"
+                size="small"
+                @change="handleAnalysisType"
+              >
                 <el-option
                   v-for="(item, indAns) in analysisTypeList"
                   :key="item.analysisTypeCode + indAns"
-                  :label="item.analysisTypeName + indAns"
-                  :value="item.analysisTypeCode + indAns"
+                  :label="item.analysisTypeName"
+                  :value="item.analysisTypeCode"
                 ></el-option>
               </el-select>
             </el-form-item>
@@ -58,10 +62,10 @@
             <el-form-item label="机组名称" prop="fieldEngineCode">
               <el-select v-model="formInfo.fieldEngineCode" size="small">
                 <el-option
-                  v-for="(item,indWind) in windEngineGroupList"
-                  :key="item.engineCode+indWind"
-                  :label="item.engineName+indWind"
-                  :value="item.engineCode+indWind"
+                  v-for="(item, indWind) in windEngineGroupList"
+                  :key="item.engineCode + indWind"
+                  :label="item.engineName"
+                  :value="item.engineCode"
                 ></el-option>
               </el-select>
             </el-form-item>
@@ -91,25 +95,21 @@
     </el-card>
     <el-empty :image-size="200" v-if="flage"></el-empty>
     <div v-else>
-      <!-- <DetailCharts
-        v-if="this.formInfo.analysisTypeCode === 'power_curve'"
-        :jsonData=""
-      ></DetailCharts> -->
       <el-table
+        class="box-card"
         v-if="
           this.formInfo.analysisTypeCode === 'yaw_error' &&
           this.csvData.length > 0
         "
         :data="csvData"
         border
+        height="550"
         style="width: 100%"
         align="center"
       >
         <el-table-column prop="engine_name" label="风机名称"> </el-table-column>
         <el-table-column prop="yaw_error1" label="误差值"> </el-table-column>
       </el-table>
-      <!-- <JsonMarkerCharts></JsonMarkerCharts> -->
-      <!-- <MarkersCharts></MarkersCharts> -->
       <div v-else>
         <el-card class="box-card analysisType" v-if="generalFiles.length > 0">
           <div slot="header" class="clearfix">
@@ -123,26 +123,67 @@
               loadings[index + generalFiles.length] &&
               getFileType(file.fileAddr) === 'html'
             " -->
-            <el-col
-              v-for="(file, index) in generalFiles"
-              :key="index + file.fileAddr + file.createTime"
-              :span="24"
-              class="col_content"
-              :style="{
-                display:
-                  getFileType(file.fileAddr) === 'html' ? 'block' : 'none',
-              }"
-            >
-              <iframe
-                v-if="getFileType(file.fileAddr) === 'html'"
-                :src="file.fileAddr"
-                :ref="'iframe' + index"
-                frameborder="0"
-                @load="iframeLoad(index + generalFiles.length)"
-                width="100%"
-                height="100%"
-              ></iframe>
-            </el-col>
+            <template v-if="formInfo.analysisTypeCode === 'power_curve'">
+              <template v-for="(powerCurveDom, ind) in generalFilesData">
+                <el-col :span="12">
+                  <div class="left">
+                    <el-table
+                      :data="
+                        powerCurveDom && powerCurveDom.powerCurveTableData[0]
+                      "
+                      border
+                      height="550"
+                      style="width: 100%"
+                      align="center"
+                    >
+                      <el-table-column prop="enginName" label="风机名称">
+                      </el-table-column>
+                      <el-table-column prop="engineTypeName" label="风机机型">
+                      </el-table-column>
+                      <el-table-column prop="xData" label="风速">
+                      </el-table-column>
+                      <el-table-column prop="yData" label="合同功率">
+                      </el-table-column>
+                      <el-table-column
+                        prop="contractPowerCurve"
+                        label="实际功率"
+                      >
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                </el-col>
+                <el-col :span="12">
+                  <div class="right">
+                    <PlotlyCharts
+                      :lineMarkerData="powerCurveDom.chartsData"
+                      :comType="'generalDrawing'"
+                    ></PlotlyCharts>
+                  </div>
+                </el-col>
+              </template>
+            </template>
+            <template v-else>
+              <el-col
+                v-for="(file, index) in generalFiles"
+                :key="index + file.fileAddr + file.createTime"
+                :span="24"
+                class="col_content"
+                :style="{
+                  display:
+                    getFileType(file.fileAddr) === 'html' ? 'block' : 'none',
+                }"
+              >
+                <iframe
+                  v-if="getFileType(file.fileAddr) === 'html'"
+                  :src="file.fileAddr"
+                  :ref="'iframe' + index"
+                  frameborder="0"
+                  @load="iframeLoad(index + generalFiles.length)"
+                  width="100%"
+                  height="100%"
+                ></iframe>
+              </el-col>
+            </template>
           </el-row>
         </el-card>
         <el-card
@@ -156,25 +197,40 @@
           </div>
           <el-row class="assetssConent">
             <el-col
-              v-for="(file, index) in diagramRelations"
-              :key="index + file.fileAddr + file.createTime"
               :span="24"
-              :style="{
-                display:
-                  getFileType(file.fileAddr) === 'html' ? 'block' : 'none',
-              }"
-              class="col_content"
+              v-if="
+                formInfo.analysisTypeCode === 'power_curve' &&
+                generalFiles.length > 0 &&
+                graphChartData.data
+              "
             >
-              <iframe
-                v-if="getFileType(file.fileAddr) === 'html'"
-                :src="file.fileAddr"
-                :ref="'iframe' + index + diagramRelations.length"
-                frameborder="0"
-                width="100%"
-                height="100%"
-                @load="iframeLoad(index + diagramRelations.length)"
-              ></iframe>
+              <PlotlyCharts
+                :lineMarkerData="graphChartData"
+                :comType="'graph'"
+              ></PlotlyCharts>
             </el-col>
+            <template v-else>
+              <el-col
+                v-for="(file, index) in diagramRelations"
+                :key="index + file.fileAddr + file.createTime"
+                :span="24"
+                :style="{
+                  display:
+                    getFileType(file.fileAddr) === 'html' ? 'block' : 'none',
+                }"
+                class="col_content"
+              >
+                <iframe
+                  v-if="getFileType(file.fileAddr) === 'html'"
+                  :src="file.fileAddr"
+                  :ref="'iframe' + index + diagramRelations.length"
+                  frameborder="0"
+                  width="100%"
+                  height="100%"
+                  @load="iframeLoad(index + diagramRelations.length)"
+                ></iframe>
+              </el-col>
+            </template>
           </el-row>
         </el-card>
       </div>
@@ -207,12 +263,13 @@ import {
 import CreateNewChart from "./createNewChart.vue";
 import DetailCharts from "./components/DetailCharts.vue";
 import JsonMarkerCharts from "./components/JsonMarkerCharts.vue";
+import PlotlyCharts from "./components/PlotlyCharts.vue";
 import { saveAs } from "file-saver";
 import JSZip from "jszip";
 import Papa from "papaparse";
 import axios from "axios";
 export default {
-  components: { DetailCharts, JsonMarkerCharts, CreateNewChart },
+  components: { DetailCharts, JsonMarkerCharts, CreateNewChart, PlotlyCharts },
   data() {
     return {
       loadings: [],
@@ -234,6 +291,8 @@ export default {
       flage: false,
       csvData: [], // 解析后的数据
       csvHeaders: [], // CSV 表头
+      generalFilesData: [],
+      graphChartData: {},
     };
   },
   created() {
@@ -312,6 +371,20 @@ export default {
           console.error("生成 ZIP 文件时发生错误:", error);
         });
     },
+    async handleAnalysisType(e) {
+      this.csvData = []; // 解析后的数据
+      this.csvHeaders = [];
+      const resEngineList = await queryAnalysisedEngine({
+        batchCode: this.$route.query.batchCode,
+        analysisTypeCode: e,
+      });
+      this.windEngineGroupList = resEngineList.data;
+      this.formInfo.fieldEngineCode =
+        resEngineList.data !== null && resEngineList.data.length > 0
+          ? resEngineList.data[0].engineCode
+          : null;
+      this.getDetailInfo();
+    },
     //分析类型图表样式
     async chartsTypeConfig() {
       const result = await queryAnalysisTypeConfig();
@@ -330,41 +403,13 @@ export default {
     onSubmit() {
       this.getDetailInfo();
     },
-    getCsvData(url) {
-      // 使用 axios 获取 CSV 文件
-      axios
-        .get(url, { responseType: "blob" }) // 确保数据以 blob 格式返回
-        .then((response) => {
-          const reader = new FileReader();
-          reader.onload = (e) => {
-            const csvText = e.target.result;
-            Papa.parse(csvText, {
-              header: true, // 使用 CSV 第一行作为键
-              complete: (result) => {
-                this.csvHeaders = Object.keys(result.data[0]);
-                this.csvData = result.data.filter(
-                  (row) => Object.keys(row).length
-                ); // 过滤空行
-              },
-              error: (error) => {
-                console.error("CSV 解析错误:", error);
-              },
-            });
-          };
-          reader.readAsText(response.data); // 读取 blob 数据
-        })
-        .catch((error) => {
-          console.error("无法获取 CSV 文件:", error);
-        });
-    },
+
     // 重置
     reset(formName) {
       this.$refs[formName].resetFields();
-
       this.getWindCodeList();
     },
     async getDetailInfo() {
-      console.log(this.csvData, "csvDatacsvData");
       const formData = new FormData();
       formData.append("batchCode", this.$route.query.batchCode);
       formData.append("analysisTypeCode", this.formInfo.analysisTypeCode);
@@ -399,12 +444,81 @@ export default {
           this.getCsvData(response.data[0].generalFiles[0].fileAddr);
         }
         this.initializeLoading();
+        //有功功率的数据处理
+        if (this.formInfo.analysisTypeCode === "power_curve") {
+          const generalFiles = response.data[0].generalFiles || [];
+          this.generalFilesData = await Promise.all(
+            generalFiles.map(async (item, ind) => {
+              const types = this.getFileType(item.fileAddr);
+              if (types !== "html" && types !== "image") {
+                const resultChartsData = await axios.get(item.fileAddr);
+                // 更新表格数据
+                return {
+                  chartsData: {
+                    ...resultChartsData.data,
+                  },
+                  powerCurveTableData: this.creatPowerCurveTableData(
+                    resultChartsData.data
+                  ).filter((val) => val !== undefined),
+                };
+              }
+            })
+          );
+
+          const grapgFilterData =
+            this.generalFilesData &&
+            this.generalFilesData[0].chartsData.data.filter(
+              (item) =>
+                item.enginName === "合同功率曲线" ||
+                item.enginName === this.formInfo.fieldEngineCode
+            );
+          this.graphChartData = {
+            ...this.generalFilesData[0].chartsData,
+            data: grapgFilterData,
+          };
+        }
         this.loading = false;
       } catch (error) {
         console.error(error);
         this.loading = false;
       }
     },
+    creatPowerCurveTableData(data) {
+      // 风机名称\风机机型\风速\合同功率\实际功率
+      // xData--风速
+      // yData--实际功率
+      // 合同功率曲线[...]---合同功率
+      // enginName--风机名称
+      // engineTypeName--风机机型
+      const contractPowerCurve =
+        data && data.data.filter((item) => item.enginName === "合同功率曲线");
+      const powerCurveTableData =
+        data &&
+        data.data.map((item, ind) => {
+          if (item.enginName !== "合同功率曲线") {
+            const childData = item.xData.map((child, childInd) => {
+              // 检查是否所有需要的数据都存在
+              if (
+                item.yData[childInd] !== undefined &&
+                contractPowerCurve[0].yData[childInd] !== undefined
+              ) {
+                return {
+                  xData: child,
+                  yData:
+                    item.yData[childInd] !== null ? item.yData[childInd] : 0.0,
+                  contractPowerCurve: contractPowerCurve[0].yData[childInd],
+                  enginName: item.enginName,
+                  engineTypeName: data.engineTypeName,
+                };
+              }
+            });
+
+            return childData;
+          }
+        });
+
+      return powerCurveTableData;
+    },
     getCsvData(url) {
       // 使用 axios 获取 CSV 文件
       axios

+ 37 - 37
src/views/performance/components/DetailCharts.vue

@@ -104,43 +104,43 @@ export default {
       selectJson: {},
       selectedPoints: [],
       modeBarButtons: [
-        // 撤销按钮
-        {
-          name: "撤销圈选",
-          icon: Plotly.Icons.undo,
-          click: (gd) => {
-            this.deleteLastShapeAndPoints(gd);
-          },
-        },
-        // 自定义工具按钮配置
-        {
-          name: "套索选择",
-          icon: Plotly.Icons.lasso,
-          click: (gd) => {
-            // 处理套索选择功能
-            Plotly.relayout(gd, { dragmode: "lasso" });
-            // 创建一个用于保存所有选择点的数组
-            let allSelectedPoints = [];
-            // 监听 plotly_selected 事件
-            gd.on("plotly_selected", (eventData) => {
-              if (eventData && eventData.points) {
-                // 将每次选择的点累加到 allSelectedPoints 中
-                allSelectedPoints = allSelectedPoints.concat(eventData.points);
-                // 显示累加后的所有选中点
-                this.debouncedGetSelectData(allSelectedPoints, gd.layout);
-                // this.getSelectData(allSelectedPoints, gd.layout);
-              }
-            });
-          },
-        },
-        // 其他工具按钮配置
-        {
-          name: "下载标记数据",
-          icon: Plotly.Icons.disk,
-          click: (gd) => {
-            this.downLoadSelectJson();
-          },
-        },
+        // // 撤销按钮
+        // {
+        //   name: "撤销圈选",
+        //   icon: Plotly.Icons.undo,
+        //   click: (gd) => {
+        //     this.deleteLastShapeAndPoints(gd);
+        //   },
+        // },
+        // // 自定义工具按钮配置
+        // {
+        //   name: "套索选择",
+        //   icon: Plotly.Icons.lasso,
+        //   click: (gd) => {
+        //     // 处理套索选择功能
+        //     Plotly.relayout(gd, { dragmode: "lasso" });
+        //     // 创建一个用于保存所有选择点的数组
+        //     let allSelectedPoints = [];
+        //     // 监听 plotly_selected 事件
+        //     gd.on("plotly_selected", (eventData) => {
+        //       if (eventData && eventData.points) {
+        //         // 将每次选择的点累加到 allSelectedPoints 中
+        //         allSelectedPoints = allSelectedPoints.concat(eventData.points);
+        //         // 显示累加后的所有选中点
+        //         this.debouncedGetSelectData(allSelectedPoints, gd.layout);
+        //         // this.getSelectData(allSelectedPoints, gd.layout);
+        //       }
+        //     });
+        //   },
+        // },
+        // // 其他工具按钮配置
+        // {
+        //   name: "下载标记数据",
+        //   icon: Plotly.Icons.disk,
+        //   click: (gd) => {
+        //     this.downLoadSelectJson();
+        //   },
+        // },
       ],
       imageDataUri: [],
       currentEngineIndex: 0,

+ 138 - 45
src/views/performance/components/EditAnalysis.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-05-29 09:14:23
- * @LastEditTime: 2024-09-13 10:51:05
+ * @LastEditTime: 2024-09-14 16:08:24
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/EditAnalysis.vue
@@ -22,8 +22,8 @@
                   @change="handleAnalysisType"
                 >
                   <el-option
-                    v-for="item in analysisTypeList"
-                    :key="item.analysisTypeCode"
+                    v-for="(item, indAns) in analysisTypeList"
+                    :key="item.analysisTypeCode + indAns"
                     :label="item.analysisTypeName"
                     :value="item.analysisTypeCode"
                   ></el-option>
@@ -38,8 +38,8 @@
                   size="small"
                 >
                   <el-option
-                    v-for="item in windEngineGroupList"
-                    :key="item.engineCode"
+                    v-for="(item, indWind) in windEngineGroupList"
+                    :key="item.engineCode + indWind"
                     :label="item.engineName"
                     :value="item.engineCode"
                   ></el-option>
@@ -66,41 +66,52 @@
     ></el-empty>
     <el-card v-if="!noData" shadow="always" class="box-card">
       <el-row>
-        <el-col
-          :span="12"
-          v-if="
-            form.configAnalysis === 'power_curve'
-            // ||
-            // form.configAnalysis === 'cp'
-          "
-          ><div class="left">
-            <el-table
-              :data="tableData"
-              border
-              style="width: 100%"
-              align="center"
-            >
-              <el-table-column prop="date" label="风机名称"> </el-table-column>
-              <el-table-column prop="name" label="风机机型"> </el-table-column>
-              <el-table-column prop="address" label="风速"> </el-table-column>
-              <el-table-column prop="address" label="合同功率">
-              </el-table-column>
-              <el-table-column prop="address" label="实际功率">
-              </el-table-column>
-            </el-table>
-          </div>
-        </el-col>
-        <el-col
-          v-loading="htmlLoading"
-          v-if="form.configAnalysis === 'power_curve'"
-          :span="12"
-        >
-          <div class="right">
-            <PlotlyCharts :lineMarkerData="lineMarkerData"></PlotlyCharts>
-          </div>
-        </el-col>
+        <!-- {{ generalFilesData }} -->
+        <template v-for="(powerCurveDom, ind) in generalFilesData">
+          <el-col
+            :span="12"
+            v-if="
+              form.configAnalysis === 'power_curve'
+              // ||
+              // form.configAnalysis === 'cp'
+            "
+            ><div class="left">
+              <el-table
+                :data="powerCurveDom && powerCurveDom.powerCurveTableData[0]"
+                border
+                height="550"
+                style="width: 100%"
+                align="center"
+              >
+                <el-table-column prop="enginName" label="风机名称">
+                </el-table-column>
+                <el-table-column prop="engineTypeName" label="风机机型">
+                </el-table-column>
+                <el-table-column prop="xData" label="风速"> </el-table-column>
+                <el-table-column prop="yData" label="合同功率">
+                </el-table-column>
+                <el-table-column prop="contractPowerCurve" label="实际功率">
+                </el-table-column>
+              </el-table>
+            </div>
+          </el-col>
+          <el-col
+            v-loading="htmlLoading"
+            v-if="form.configAnalysis === 'power_curve'"
+            :span="12"
+          >
+            <div class="right">
+              <PlotlyCharts
+                :lineMarkerData="powerCurveDom.chartsData"
+                :comType="'generalDrawing'"
+              ></PlotlyCharts>
+            </div>
+          </el-col>
+        </template>
+
         <el-col
           :span="24"
+          height="550"
           v-if="form.configAnalysis === 'yaw_error' && this.csvData.length > 0"
           ><div class="left">
             <el-table :data="csvData" border style="width: 100%" align="center">
@@ -200,8 +211,8 @@
                 @change="handleEngineCode"
               >
                 <el-option
-                  v-for="item in windEngineGroupList"
-                  :key="item.engineCode"
+                  v-for="(item, indWind) in windEngineGroupList"
+                  :key="item.engineCode + indWind"
                   :label="item.engineName"
                   :value="item.engineCode"
                 ></el-option>
@@ -257,10 +268,7 @@
             form.configAnalysis !== 'yaw_error' &&
             form.configAnalysis !== 'power_curve'
           "
-          &&
-          this.csvData.length
         >
-          0 >
           <div class="right">
             <iframe
               v-if="htmlLoading"
@@ -367,7 +375,6 @@ export default {
       engineCode: null, //台账机组编号
       windDetail: {},
       flage: false,
-      lineMarkerData: [],
       csvData: [], // 解析后的数据
       csvHeaders: [], // CSV 表头
       rules: {
@@ -398,6 +405,8 @@ export default {
       windEngineGroupList: [],
       formData: { content: "<p>Hello, Tinymce!</p>" },
       tabIndex: 2,
+      powerCurveTableData: [],
+      generalFilesData: [],
     };
   },
   created() {
@@ -409,6 +418,8 @@ export default {
       this.htmlLoading = false;
     },
     async handleAnalysisType(e) {
+      this.csvData = []; // 解析后的数据
+      this.csvHeaders = [];
       const resEngineList = await queryAnalysisedEngine({
         batchCode: this.$route.query.batchCode,
         analysisTypeCode: e,
@@ -426,6 +437,7 @@ export default {
         //获取台账机组编号
         this.getWindEngList();
       }
+      this.getDetailInfo();
     },
     async handleComment() {
       this.loading = true;
@@ -503,12 +515,94 @@ export default {
         if (this.form.configAnalysis === "yaw_error") {
           this.getCsvData(response.data[0].generalFiles[0].fileAddr);
         }
+        //有功功率的数据处理
+        if (this.form.configAnalysis === "power_curve") {
+          const generalFiles = response.data[0].generalFiles || [];
+          this.generalFilesData = await Promise.all(
+            generalFiles.map(async (item, ind) => {
+              const types = this.getFileType(item.fileAddr);
+              console.log(types,'返回url 类型')
+              if (types !== "html" && types !== "image") {
+                const resultChartsData = await axios.get(item.fileAddr);
+                // 更新表格数据
+                return {
+                  chartsData: {
+                    ...resultChartsData.data,
+                  },
+                  powerCurveTableData: this.creatPowerCurveTableData(
+                    resultChartsData.data
+                  ).filter((val) => val !== undefined),
+                };
+              }
+            })
+          );
+        }
         this.loading = false;
       } catch (error) {
         console.error(error);
         this.loading = false;
       }
     },
+    getFileType(url) {
+      // 使用 URL 对象解析 URL
+      // 获取路径名部分
+      let pathname = url.split("/").pop();
+      // 截取路径名,去除加密乱码字符部分
+      const index = pathname.indexOf(".html");
+      if (index !== -1) {
+        pathname = pathname.slice(0, index + 5); // '.html' 的长度是 5
+      } else {
+        pathname = pathname.slice(0, pathname.indexOf(".png") + 4); // '.png' 的长度是 4
+      }
+      // 正则表达式匹配图片扩展名
+      const imageExtensions = /\.(png|jpg|jpeg|gif|bmp|svg)$/i;
+      // 正则表达式匹配 HTML 扩展名
+      const htmlExtensions = /\.html?$/i;
+
+      if (imageExtensions.test(pathname)) {
+        return "image";
+      } else if (htmlExtensions.test(pathname)) {
+        return "html";
+      } else {
+        return "unknown";
+      }
+    },
+    creatPowerCurveTableData(data) {
+      // 风机名称\风机机型\风速\合同功率\实际功率
+      // xData--风速
+      // yData--实际功率
+      // 合同功率曲线[...]---合同功率
+      // enginName--风机名称
+      // engineTypeName--风机机型
+      const contractPowerCurve =
+        data && data.data.filter((item) => item.enginName === "合同功率曲线");
+      const powerCurveTableData =
+        data &&
+        data.data.map((item, ind) => {
+          if (item.enginName !== "合同功率曲线") {
+            const childData = item.xData.map((child, childInd) => {
+              // 检查是否所有需要的数据都存在
+              if (
+                item.yData[childInd] !== undefined &&
+                contractPowerCurve[0].yData[childInd] !== undefined
+              ) {
+                return {
+                  xData: child,
+                  yData:
+                    item.yData[childInd] !== null ? item.yData[childInd] : 0.0,
+                  contractPowerCurve: contractPowerCurve[0].yData[childInd],
+                  enginName: item.enginName,
+                  engineTypeName: data.engineTypeName,
+                };
+              }
+            });
+
+            return childData;
+          }
+        });
+
+      return powerCurveTableData;
+    },
     getCsvData(url) {
       // 使用 axios 获取 CSV 文件
       axios
@@ -598,7 +692,6 @@ export default {
         } else {
           this.noData = true;
         }
-
         this.loading = false;
       } catch (error) {
         console.error(error);

+ 236 - 175
src/views/performance/components/PlotlyCharts.vue

@@ -1,200 +1,261 @@
 <template>
-  <div id="myDiv"></div>
+  <div>
+    <!-- 总图组件 -->
+    <div
+      v-if="comType === 'generalDrawing'"
+      id="power-curve-plot"
+      style="width: 100%; height: 500px"
+    ></div>
+    <!-- 分图组件  -->
+    <template v-else-if="comType === 'graph'">
+      <div
+        v-for="(engine, index) in powerCurveData.turbines"
+        :key="'chart-' + index"
+        :id="'chart-' + index"
+        style="width: 100%; height: 500px"
+      ></div>
+    </template>
+  </div>
 </template>
 
 <script>
 import Plotly from "plotly.js-dist";
 
 export default {
-  name: "PlotlyChart",
-  mounted() {
-    this.initializeChart();
+  props: {
+    lineMarkerData: Object,
+    comType: String,
   },
+  name: "PowerCurvePlot",
   data() {
     return {
-      imageDataUri: "",
-    };
-  },
-  methods: {
-    initializeChart() {
-      const layout = {
-        title: "Power Curve",
-        xaxis: { title: "Wind Speed (m/s)" },
-        yaxis: { title: "Power (kW)" },
-        legend: {
-          orientation: "h",
-          y: -0.2,
-          x: 0.5,
-          xanchor: "center",
+      graphData: [], //分图数据length data
+      config: {
+        powerConfig: {
+          mode: "lines+markers",
+          name: "合同功率曲线",
+          line: { color: "red" },
+          marker: { color: "red", size: 5 },
         },
-      };
-      const data = {
-        analysisTypeCode: "power_curve",
-        graphType: "scatter",
-        data: [
-          {
-            engineName: "#1",
-            windSpeed: [
-              3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
-              27, 30,
-            ],
-            power: [
-              6.06, 76.54, 184.1, 345.94, 574.4, 879.9, 1274.73, 1664.94,
-              1942.96, 2004.78, 2004.78, 2004.78, 2004.78, 2004.78, 2004.78,
-              2004.78, 2004.78, 2004.78, 2230,
-            ],
-          },
-          {
-            engineName: "#2",
-            windSpeed: [
-              2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5,
-              10, 10.5, 11, 11.5, 12, 12.5, 13, 13.5, 14, 14.5, 15, 15.5, 16,
-              16.5, 33,
-            ],
-            power: [
-              2, 9.23, 100.12, 155.51, 230.09, 400.15, 500.95, 689.55, 961.09,
-              1257.53, 1346.02, 1479.78, 1528.01, 1618.52, 1789.09, 1819.35,
-              1920.29, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52,
-              2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52,
-              2153.52, 2159,
-            ],
+        lableConfig: {
+          title: { text: "", x: 0.5 },
+          plot_bgcolor: "#e5ecf6", // Chart background color
+          xaxis: {
+            title: "风速(m/s)",
+            // range: [0, 26],
+            tickmode: "linear",
+            gridcolor: "rgb(255,255,255)",
+            showgrid: true,
+            zeroline: false,
+            tickcolor: "rgb(255,255,255)",
+            dtick: 1,
+            tickangle: -45,
           },
-          {
-            engineName: "#3",
-            windSpeed: [
-              2.7, 3.7, 4.7, 5.7, 6.7, 7.7, 8.7, 9.7, 10.7, 11.5, 12, 13.5, 14,
-              15.5, 16, 17.5, 18, 19.5, 21, 21.5, 22, 22.5, 23, 23.5, 24, 27.5,
-              28, 29.5, 30, 36.5,
-            ],
-            power: [
-              2, 9.23, 100.12, 155.51, 230.09, 400.15, 500.95, 689.55, 961.09,
-              1257.53, 1346.02, 1479.78, 1528.01, 1618.52, 1789.09, 1819.35,
-              1920.29, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52,
-              2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52,
-              2053.52,
-            ],
+          yaxis: {
+            title: "功率(kW)",
+            gridcolor: "rgb(255,255,255)",
+            showgrid: true,
+            zeroline: false,
+            tickcolor: "rgb(255,255,255)",
           },
-        ],
-      };
-      const plotlyData = data.data.map((engine) => ({
-        x: engine.windSpeed,
-        y: engine.power,
-        mode: "lines+markers",
-        name: engine.engineName,
-      }));
-      const modeBarButtons = [
-        {
-          name: "套索选择",
-          icon: Plotly.Icons.lasso,
-          click: function (gd) {
-            // 处理套索选择功能
-            Plotly.relayout(gd, { dragmode: "lasso" });
+          legend: {
+            orientation: "h",
+            xanchor: "center",
+            x: 0.5,
+            y: -0.2,
           },
         },
-        {
-          name: "恢复",
-          icon: Plotly.Icons.home,
-          click: function (gd) {
-            Plotly.relayout(gd, {
-              "xaxis.autorange": true,
-              "yaxis.autorange": true,
-            });
+        colors: [
+          "#636EFA",
+          "#EF553B",
+          "#00CC96",
+          "#AB63FA",
+          "#FFA15A",
+          "#19D3F3",
+          "#FF6692",
+          "#B6E880",
+          "#FF97FF",
+          "#FECB52",
+          "#636EFB",
+          "#EF553C",
+          "#00CC97",
+          "#AB63FB",
+          "#FFA15B",
+          "#19D3F4",
+          "#FF6693",
+          "#B6E881",
+          "#FF97FE",
+          "#FECB51",
+          "#1F77B4",
+          "#FF7F0E",
+          "#2CA02C",
+          "#D62728",
+          "#9467BD",
+          "#8C564B",
+          "#E377C2",
+          "#7F7F7F",
+          "#BCBD22",
+          "#17BECF",
+          "#1A55F2",
+          "#FF5733",
+          "#33FF57",
+          "#3375FF",
+          "#FF33A6",
+          "#57FF33",
+          "#3380FF",
+          "#FF8033",
+          "#57FF80",
+          "#8033FF",
+          "#FF3380",
+          "#FFD733",
+        ],
+      },
+      powerCurveData: {
+        turbines: [],
+        contractPowerCurve: [],
+      },
+    };
+  },
+  mounted() {
+    this.powerCurveData.turbines =
+      this.lineMarkerData.data &&
+      this.lineMarkerData.data.length > 0 &&
+      this.lineMarkerData.data.filter(
+        (item) => item.enginName !== "合同功率曲线"
+      );
+    this.powerCurveData.contractPowerCurve =
+      this.lineMarkerData.data &&
+      this.lineMarkerData.data.length > 0 &&
+      this.lineMarkerData.data.filter(
+        (item) => item.enginName === "合同功率曲线"
+      );
+    if (
+      this.comType === "generalDrawing" &&
+      this.lineMarkerData &&
+      this.lineMarkerData.data
+    ) {
+      this.renderPlot();
+    } else if (
+      this.comType === "graph" &&
+      this.lineMarkerData &&
+      this.lineMarkerData.data
+    ) {
+      this.$nextTick(() => {
+        this.initializeEngineCharts();
+      });
+    }
+  },
+  methods: {
+    renderPlot() {
+      const data = [];
+      // Add traces for each turbine with colors from config
+      this.powerCurveData.turbines.forEach((turbine, index) => {
+        data.push({
+          x: turbine.xData,
+          y: turbine.yData.map((val) => (val !== null ? val : 0.0)),
+          mode: "lines",
+          name: turbine.enginName,
+          line: {
+            color: this.config.colors[index % this.config.colors.length],
           },
-        },
-        {
-          name: "拍照",
-          icon: Plotly.Icons.camera,
-          click: function (gd) {
-            Plotly.downloadImage(gd);
+        });
+      });
+
+      data.push({
+        x: this.powerCurveData.contractPowerCurve[0].xData,
+        y: this.powerCurveData.contractPowerCurve[0].yData,
+        mode: this.config.powerConfig.mode,
+        name: this.config.powerConfig.name,
+        line: this.config.powerConfig.line,
+        marker: this.config.powerConfig.marker,
+      });
+      const layout = {
+        title: this.config.lableConfig.title.text || "有功功率曲线分析",
+        plot_bgcolor: this.config.lableConfig.plot_bgcolor,
+        xaxis: this.config.lableConfig.xaxis,
+        yaxis: this.config.lableConfig.yaxis,
+        legend: this.config.lableConfig.legend,
+      };
+      Plotly.newPlot("power-curve-plot", data, layout);
+    },
+    //初始化分图
+    //初始化分图
+    initializeEngineCharts() {
+      this.powerCurveData.turbines.forEach((engine, index) => {
+        const layout = {
+          title: engine.enginName + "风机",
+          plot_bgcolor: "#e5ecf6", // Chart background color
+          xaxis: {
+            title: "风速(m/s)",
+            // range: [0, 26],
+            tickmode: "linear",
+            gridcolor: "rgb(255,255,255)",
+            showgrid: true,
+            zeroline: false,
+            tickcolor: "rgb(255,255,255)",
+            dtick: 1,
+            tickangle: -45,
           },
-        },
-        {
-          name: "放大",
-          icon: Plotly.Icons.zoom_plus,
-          click: function (gd) {
-            Plotly.relayout(gd, {
-              "xaxis.range": [
-                gd._fullLayout.xaxis.range[0],
-                gd._fullLayout.xaxis.range[1] * 0.5,
-              ],
-            });
+          yaxis: {
+            title: "功率(kW)",
+            gridcolor: "rgb(255,255,255)",
+            showgrid: true,
+            zeroline: false,
+            tickcolor: "rgb(255,255,255)",
           },
-        },
-        {
-          name: "缩小",
-          icon: Plotly.Icons.zoom_minus,
-          click: function (gd) {
-            Plotly.relayout(gd, {
-              "xaxis.range": [
-                gd._fullLayout.xaxis.range[0],
-                gd._fullLayout.xaxis.range[1] * 2,
-              ],
-            });
+          legend: {
+            orientation: "h",
+            xanchor: "center",
+            x: 0.5,
+            y: -0.2,
           },
-        },
-        {
-          name: "平移",
-          icon: Plotly.Icons.pan,
-          click: function (gd) {
-            Plotly.relayout(gd, { dragmode: "pan" });
+          shapes: [],
+          editable: true,
+        };
+        const plotlyData = this.powerCurveData.turbines.map((eng, i) => ({
+          x: eng.xData,
+          y: eng.yData,
+          mode: "lines",
+          name: eng.enginName,
+          line: {
+            color: "#1c77b3",
           },
-        },
-        {
-          name: "自动缩放",
-          icon: Plotly.Icons.autoscale,
-          click: function (gd) {
-            Plotly.relayout(gd, {
-              "xaxis.autorange": true,
-              "yaxis.autorange": true,
-            });
+        }));
+        plotlyData.push({
+          x: this.powerCurveData.contractPowerCurve[0].xData,
+          y: this.powerCurveData.contractPowerCurve[0].yData,
+          mode: "lines+markers",
+          name: this.powerCurveData.contractPowerCurve[0].enginName,
+          line: {
+            color: "#c1c1c1",
           },
-        },
-        // 添加更多的自定义按钮
-      ];
-
-      const config = {
-        modeBarButtonsToAdd: modeBarButtons,
-        modeBarButtonsToRemove: [
-          "toImage",
-          "zoom2d",
-          "pan2d",
-          "select2d",
-          "lasso2d",
-          "zoomIn2d",
-          "zoomOut2d",
-          "autoScale2d",
-          "resetScale2d",
-          "hoverClosestCartesian",
-          "hoverCompareCartesian",
-        ],
-        displaylogo: false, // 移除plotly logo
-        scrollZoom: true,
-        // editable: true,//编辑图表标题
-      };
-      Plotly.newPlot("myDiv", plotlyData, layout, config).then((gd) => {
-        //生成图片方法
-        Plotly.toImage(gd, { format: "png" }).then((dataUrl) => {
-          // console.log(dataUrl, "dataUrl");
-          this.imageDataUri = dataUrl;
-        });
-        // 处理选择事件
-        gd.on("plotly_selected", (eventData) => {
-          if (eventData) {
-            const selectedPoints = eventData.points.map((point) => ({
-              x: point.x,
-              y: point.y,
-            }));
-            console.log("选中的点:", selectedPoints);
-            // 这里可以保存选中的数据进行后续处理
-          }
         });
-        // 处理套索结束事件
-        gd.on("plotly_relayout", (eventData) => {
-          if (eventData["dragmode"] === "lasso") {
-            console.log("套索选择模式激活");
-            // 可以处理用户开始新的套索选择操作
+        const config = {
+          // modeBarButtonsToAdd: this.modeBarButtons,
+          modeBarButtonsToRemove: [
+            // "selectbox",
+            "lasso",
+            // "zoombox",
+            // "pan",
+            // "autoscale",
+            // "zoom2d",
+            // "pan2d",
+            // "select2d",
+          ],
+          displaylogo: false,
+          // scrollZoom: true,
+          editable: true,
+        };
+        console.log(plotlyData, "plotlyData");
+        Plotly.newPlot(`chart-${index}`, plotlyData, layout, config).then(
+          (gd) => {
+            // 初始化 _undoStack
+            // 生成图片方法
+            // Plotly.toImage(gd, { format: "png" }).then((dataUrl) => {
+            //   this.imageDataUri.push(dataUrl);
+            // });
           }
-        });
+        );
       });
     },
   },
@@ -202,5 +263,5 @@ export default {
 </script>
 
 <style scoped>
-/* 样式可选 */
+/* You can add styles for your component here */
 </style>

+ 1 - 1
src/views/performance/editAssets.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-05-27 09:26:31
- * @LastEditTime: 2024-08-05 09:59:55
+ * @LastEditTime: 2024-09-13 14:36:26
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/editAssets.vue

+ 2 - 2
vue.config.js

@@ -65,10 +65,10 @@ module.exports = {
     proxy: {
       "/api": {
         // target: "http://192.168.5.4:16200", // 石月
-        // target: "http://192.168.50.235:16200", //内网
+        target: "http://192.168.50.235:16200", //内网
         // target: "http://192.168.5.15:16200",
         // target: "http://106.120.102.238:16600", //外网
-           target: "http://10.96.137.5",
+        //  target: "http://10.96.137.5",
         changeOrigin: true,
         pathRewrite: {
           "^/api": "", // 需要regit write重写的,