| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- 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}<br>` +
- `${data.yaixs}: %{y}<br>` +
- `时间: %{customdata}<extra></extra>`,
- };
- // ✅ 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;
- }
- };
|