Explorar el Código

添加处理热力图和流图图表 条件过滤

liujiejie hace 6 meses
padre
commit
2e160dc49c

+ 10 - 7
src/assets/js/constants/echarts-config/Heatmap.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2024-11-20 09:13:21
- * @LastEditTime: 2024-11-27 15:04:35
+ * @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
@@ -10,7 +10,7 @@
 // 风速随时间和风向的分布
 import { colorPalette } from "../color";
 export const option = {
-  color: colorPalette,
+  color: colorPalette, // 使用 colorPalette 作为颜色设置
   title: {
     text: "风速随时间和风向的分布",
   },
@@ -33,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],
@@ -59,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 - 2
src/assets/js/constants/echarts-config/sankeyDiagram.js

@@ -1,8 +1,8 @@
 /*
  * @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
  */

+ 5 - 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: 2024-11-27 15:23:51
+ * @LastEditTime: 2024-11-28 11:07:41
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/utils/chartLogic/index.js
@@ -16,6 +16,8 @@ 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,
@@ -26,4 +28,6 @@ export {
   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)",
+          },
+        },
+      },
+    ];
+  }
+}

+ 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",
+        },
+      },
+    ];
+  }
+}

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

@@ -1,14 +1,14 @@
 /*
  * @Author: your name
  * @Date: 2024-11-27 09:36:28
- * @LastEditTime: 2024-11-27 09:44:49
+ * @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, getFormattedSeries } from "../../configFn";
+import { getFormattedLabels } from "../../configFn";
 export function handlestackedBarChartLogic(
   item,
   formLabelAlign,
@@ -24,7 +24,6 @@ export function handlestackedBarChartLogic(
       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

+ 89 - 9
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
@@ -49,7 +72,12 @@
                 ></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
                     ? '该指标不可删除,最少存在一组指标'
@@ -84,7 +112,12 @@
             <el-tooltip
               content="添加指标值"
               placement="bottom-start"
-              v-if="curEdit.type !== 'roseChart' && curEdit.type !== 'pie'"
+              v-if="
+                curEdit.type !== 'roseChart' &&
+                curEdit.type !== 'pie' &&
+                curEdit.type !== 'sankeyDiagram' &&
+                curEdit.type !== 'Heatmap'
+              "
             >
               <i
                 @click="handleMetrics('init')"
@@ -121,7 +154,12 @@
                 ></el-option>
               </el-select>
               <el-tooltip
-                v-if="curEdit.type !== 'roseChart' && curEdit.type !== 'pie'"
+                v-if="
+                  curEdit.type !== 'roseChart' &&
+                  curEdit.type !== 'pie' &&
+                  curEdit.type !== 'sankeyDiagram' &&
+                  curEdit.type !== 'Heatmap'
+                "
                 :content="
                   formLabelAlign.Ydata.length <= 1
                     ? '该指标不可删除,最少存在一组指标'
@@ -525,7 +563,8 @@
         v-if="
           curEdit.type !== 'pie' &&
           curEdit.type !== 'radar' &&
-          curEdit.type !== 'roseChart'
+          curEdit.type !== 'roseChart' &&
+          curEdit.type !== 'sankeyDiagram'
         "
       >
         <el-input v-model="formLabelAlign.Xlable"></el-input>
@@ -536,7 +575,8 @@
           curEdit.type !== 'pie' &&
           curEdit.type !== 'radar' &&
           curEdit.type !== 'roseChart' &&
-          curEdit.type !== 'pareto'
+          curEdit.type !== 'pareto' &&
+          curEdit.type !== 'sankeyDiagram'
         "
       >
         <el-input v-model="formLabelAlign.Ylable"></el-input>
@@ -647,8 +687,11 @@ import {
   handlestackedBarChartLogic,
   handleParetoChartLogic,
   handleBoxPlotChartLogic,
+  handleSankeyDiagramPlotChartLogic,
+  handleHeatmapPlotChartLogic,
 } from "./chartLogic/index";
 import Vue from "vue";
+import { constructNow } from "date-fns";
 export default {
   name: "title",
   props: {
@@ -780,6 +823,8 @@ export default {
           "roseChart",
           "stackedBar",
           "boxPlot",
+          "sankeyDiagram",
+          "Heatmap",
         ].includes(type)
       ) {
         return Ydata;
@@ -818,6 +863,24 @@ export default {
       "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) {
@@ -831,6 +894,7 @@ export default {
             );
             return;
           }
+
           this.formLabelAlign.Ydata.push({ lable: "", data: [], id: "" });
           this.formFilterAlign.push({
             filters: [],
@@ -1285,6 +1349,22 @@ export default {
           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({