import { renderChart } from "../chartService/index.js";
import { colorSchemes } from "../colors.js";
export const generateTwoDMarkersChart1 = async (
data,
bucketName,
objectName,
) => {
try {
// ✅ 1. 数据拆分(修复 enginName 拼写问题🔥)
const scatterData = data.data.find(
(item) => item.engineName !== "合同功率曲线",
);
const lineData = data.data.find(
(item) =>
item.engineName === "合同功率曲线" || item.enginName === "合同功率曲线",
);
if (!scatterData) {
throw new Error("scatterData 不存在");
}
// ✅ 2. 颜色数据源
const rawColorData =
scatterData.colorbar?.length === scatterData.xData.length
? scatterData.colorbar
: scatterData.color;
const uniqueLabels = [...new Set(rawColorData)];
const tickvals = uniqueLabels.map((_, i) => i + 1);
const ticktext = uniqueLabels.map((dateStr) => {
const date = new Date(dateStr);
if (isNaN(date)) return dateStr; // 防止非法时间🔥
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, "0");
return `${y}-${m}`;
});
const mapping = uniqueLabels.reduce((acc, cur, i) => {
acc[cur] = i + 1;
return acc;
}, {});
// ✅ 3. 颜色渐变(安全版)
const colors = colorSchemes?.[0]?.colors || [];
const safePick = (i) => colors[i] || colors[0] || "#1B2973";
const colorStops = [safePick(0), safePick(4), safePick(8), safePick(12)];
const colorscale = colorStops.map((c, i) => [
i / (colorStops.length - 1),
c,
]);
if (colorscale.length < 2) {
colorscale.push([1, safePick(0)]);
}
// ✅ 4. 映射颜色
const colorValues = rawColorData.map((v) => mapping[v]);
// ⚠️ 性能优化
const pointCount = scatterData.xData.length;
const markerSize = pointCount > 5000 ? 3 : 6;
// ✅ 5. scatter trace
const scatterTrace = {
x: scatterData.xData,
y: scatterData.yData,
type: "scattergl",
mode: "markers",
name: scatterData.engineName,
marker: {
color: colorValues,
colorscale,
size: markerSize,
colorbar: {
title: { text: scatterData.colorbartitle || "时间" },
tickvals,
ticktext,
},
line: {
color: "#fff",
width: 0.3,
},
},
customdata: rawColorData,
hovertemplate:
`${data.xaixs}: %{x}
` +
`${data.yaixs}: %{y}
` +
`时间: %{customdata}`,
};
// ✅ 6. 合同曲线(优化:避免空对象加入🔥)
const traces = [scatterTrace];
if (lineData?.xData?.length && lineData?.yData?.length) {
traces.push({
x: lineData.xData,
y: lineData.yData,
type: "scatter",
mode: "lines+markers",
name: "合同功率曲线",
line: { color: "red" },
marker: { color: "red", size: 4 },
});
}
// ✅ 7. layout
const layout = {
title: {
text: scatterData.title || "散点图",
font: { size: 16 },
},
xaxis: {
title: data.xaixs,
gridcolor: "rgb(255,255,255)",
tickcolor: "rgb(255,255,255)",
backgroundcolor: "#e5ecf6",
showbackground: true,
showline: true, // ✅ 显示 X 轴轴线
zeroline: false,
linecolor: "#ffffff", // ✅ X 轴轴线颜色设为白色
},
yaxis: {
title: data.yaixs,
gridcolor: "rgb(255,255,255)",
tickcolor: "rgb(255,255,255)",
backgroundcolor: "#e5ecf6",
showbackground: true,
showline: true, // ✅ 显示 X 轴轴线
zeroline: false,
linecolor: "#ffffff", // ✅ X 轴轴线颜色设为白色
},
showlegend: false,
plot_bgcolor: "#e5ecf6",
paper_bgcolor: "#e5ecf6",
};
// ✅ 8. 渲染
const url = await renderChart({
traces,
layout,
bucketName,
objectName,
});
return url;
} catch (error) {
console.error("❌ 生成2D散点图失败:", error);
throw error;
}
};