|
@@ -1,15 +1,124 @@
|
|
//散点图+散点折线图
|
|
//散点图+散点折线图
|
|
import { filterData } from "../dargChartFIlter";
|
|
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(
|
|
export function handleScatterChartLogic(
|
|
- item, //curEdit编辑项配置
|
|
|
|
- formLabelAlign, //每一项label显示
|
|
|
|
- formFilterAlign, //过滤数据 数据筛选from
|
|
|
|
- isFilter, //是否是过滤
|
|
|
|
- type //图表类型
|
|
|
|
|
|
+ item, // curEdit编辑项配置
|
|
|
|
+ formLabelAlign, // 每一项label显示
|
|
|
|
+ formFilterAlign, // 过滤数据 数据筛选from
|
|
|
|
+ isFilter, // 是否是过滤
|
|
|
|
+ type // 图表类型
|
|
) {
|
|
) {
|
|
- // 封装柱状图的具体逻辑
|
|
|
|
|
|
+ // 处理过滤数据的逻辑
|
|
if (isFilter === "filter") {
|
|
if (isFilter === "filter") {
|
|
- // 数据筛选逻辑
|
|
|
|
const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
|
|
const filterResult = formLabelAlign.Ydata.map((yItem, index) => ({
|
|
label: yItem.label,
|
|
label: yItem.label,
|
|
id: yItem.id,
|
|
id: yItem.id,
|
|
@@ -21,7 +130,7 @@ export function handleScatterChartLogic(
|
|
: val;
|
|
: val;
|
|
}),
|
|
}),
|
|
}));
|
|
}));
|
|
- // 条件筛选逻辑
|
|
|
|
|
|
+
|
|
const filterList = filterResult.map((filteredItem, index) => {
|
|
const filterList = filterResult.map((filteredItem, index) => {
|
|
const filter = formFilterAlign[index];
|
|
const filter = formFilterAlign[index];
|
|
const { filterType1, filterType2, number1, number2 } = filter;
|
|
const { filterType1, filterType2, number1, number2 } = filter;
|
|
@@ -53,6 +162,7 @@ export function handleScatterChartLogic(
|
|
item.Xdata = formLabelAlign.Xdata;
|
|
item.Xdata = formLabelAlign.Xdata;
|
|
item.Ydata = formLabelAlign.Ydata;
|
|
item.Ydata = formLabelAlign.Ydata;
|
|
}
|
|
}
|
|
|
|
+
|
|
item.option.xAxis = {
|
|
item.option.xAxis = {
|
|
...item.option.xAxis,
|
|
...item.option.xAxis,
|
|
type: "value",
|
|
type: "value",
|
|
@@ -60,12 +170,11 @@ export function handleScatterChartLogic(
|
|
};
|
|
};
|
|
item.option.yAxis = {
|
|
item.option.yAxis = {
|
|
...item.option.yAxis,
|
|
...item.option.yAxis,
|
|
-
|
|
|
|
name: formLabelAlign.Ylable,
|
|
name: formLabelAlign.Ylable,
|
|
};
|
|
};
|
|
|
|
|
|
if (item.Ydata[0]?.data?.length > 0 || item.Xdata[0]?.data?.length > 0) {
|
|
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.option.series = (
|
|
item.Xdata.length > item.Ydata.length ? item.Xdata : item.Ydata
|
|
item.Xdata.length > item.Ydata.length ? item.Xdata : item.Ydata
|
|
).map((val, ind) => {
|
|
).map((val, ind) => {
|
|
@@ -100,50 +209,88 @@ export function handleScatterChartLogic(
|
|
data: scatterData, // 生成的散点图数据
|
|
data: scatterData, // 生成的散点图数据
|
|
tooltip: {
|
|
tooltip: {
|
|
trigger: "item", // 鼠标悬停触发
|
|
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: {
|
|
itemStyle: {
|
|
shadowBlur: 3,
|
|
shadowBlur: 3,
|
|
shadowColor: "rgba(25, 100, 150, 0.3)",
|
|
shadowColor: "rgba(25, 100, 150, 0.3)",
|
|
shadowOffsetY: 1.5,
|
|
shadowOffsetY: 1.5,
|
|
- // color: {
|
|
|
|
- // type: "radial",
|
|
|
|
- // x: 0.4,
|
|
|
|
- // y: 0.3,
|
|
|
|
- // r: 1,
|
|
|
|
- // colorStops: [
|
|
|
|
- // {
|
|
|
|
- // offset: 0,
|
|
|
|
- // color: "#f90",
|
|
|
|
- // },
|
|
|
|
- // {
|
|
|
|
- // offset: 1,
|
|
|
|
- // color: "#F00",
|
|
|
|
- // },
|
|
|
|
- // ],
|
|
|
|
- // },
|
|
|
|
},
|
|
},
|
|
};
|
|
};
|
|
});
|
|
});
|
|
|
|
+
|
|
|
|
+ // 记录选中的散点
|
|
|
|
+ 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); // 然后绑定新的点击事件
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|