/*
* @Author: your name
* @Date: 2025-05-14 10:49:00
* @LastEditTime: 2025-05-26 11:02:41
* @LastEditors: bogon
* @Description: In User Settings Edit
* @FilePath: /downLoadServer/src/server/utils/chartsCom/yawErrorLine.js
*/
import puppeteer from "puppeteer";
import fs from "fs-extra";
import path from "path";
import FormData from "form-data";
import { colorSchemes } from "../colors.js";
import axios from "axios";
export const generateYawErrorLine = async (
chartData,
bucketName,
objectName
) => {
try {
const data = [];
const colors = [...colorSchemes[0].colors]; // 生成颜色
// 获取 plotly.js 的绝对路径
const plotlyPath = path.join(
process.cwd(),
"src",
"public",
"js",
"plotly-3.0.1.min.js"
);
const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
chartData &&
chartData.data &&
chartData.data.forEach((turbine, index) => {
// 判断图表类型,根据类型调整绘制方式
const chartConfig = {
x: turbine.xData, // X 数据
y: turbine.yData, // Y 数据
name: turbine.legend, // 使用机组名称
line: {
color: colors[index % colors.length], // 为每个机组分配不同的颜色
},
marker: {
color: colors[index % colors.length], // 为每个机组分配不同的颜色
},
hovertemplate:
`${chartData.xaixs}:` +
` %{x}
` +
`${chartData.yaixs}:` +
"%{y}
",
};
if (chartData.chartType === "line") {
chartConfig.mode = "lines+markers"; // 如果是折线图
chartConfig.fill = "none";
} else if (chartData.chartType === "bar") {
chartConfig.fill = "tonexty";
}
data.push(chartConfig);
});
const layout = {
title: {
text: chartData.data[0].title,
font: {
size: 16, // 设置标题字体大小(默认 16)
weight: "bold",
},
},
xaxis: {
gridcolor: "rgb(255,255,255)",
tickcolor: "rgb(255,255,255)",
backgroundcolor: "#e5ecf6",
title: chartData.xaixs || "X轴", // 横坐标标题
},
yaxis: {
gridcolor: "rgb(255,255,255)",
tickcolor: "rgb(255,255,255)",
backgroundcolor: "#e5ecf6",
title: chartData.yaixs || "Y轴", // 纵坐标标题
},
// margin: {
// l: 50,
// r: 50,
// t: 50,
// b: 50,
// },
plot_bgcolor: "#e5ecf6",
gridcolor: "#fff",
bgcolor: "#e5ecf6", // 设置背景颜色
autosize: true, // 开启自适应
barmode: chartData.chartType === "bar" ? "stack" : "group", // 如果是柱状图则启用堆叠
};
if (
chartData.contract_Cp_curve_yData &&
chartData.contract_Cp_curve_yData.length > 0
) {
data.push({
x: chartData.contract_Cp_curve_xData,
y: chartData.contract_Cp_curve_yData,
mode: "lines+markers",
name: "合同功率曲线",
line: {
color: "red",
width: 1, // 设置线条的宽度为1
},
marker: { color: "red", size: 4 },
});
}
// 使用 Puppeteer 生成图表的截图
const browser = await puppeteer.launch({
headless: "new",
args: ["--no-sandbox", "--disable-setuid-sandbox"],
});
const tempDir = path.join(process.cwd(), "images");
await fs.ensureDir(tempDir);
const tempFilePath = path.join(
tempDir,
`temp_yaw_error_chart_${Date.now()}.jpeg`
);
try {
const page = await browser.newPage();
const htmlContent = `
静态偏航折线分图
`;
await page.setContent(htmlContent, { waitUntil: "networkidle0" });
await page.waitForFunction(() => window.chartRendered === true, {
timeout: 60000,
});
// 截图并保存到临时文件
const chartElement = await page.$("#chart");
await chartElement.screenshot({ path: tempFilePath, type: "jpeg" });
// 上传图片到服务器
const formData = new FormData();
formData.append("file", fs.createReadStream(tempFilePath));
const response = await axios.post(
`${process.env.API_BASE_URL}/examples/upload`,
{
filePath: tempFilePath,
bucketName,
objectName,
}
);
console.log("上传成功:", response.data);
return response?.data?.url;
} catch (error) {
console.error("生成折线图失败:", error);
throw error;
} finally {
await browser.close();
}
} catch (error) {
console.error("生成折线图失败:", error);
throw error;
}
};