/* * @Author: your name * @Date: 2025-05-23 17:19:20 * @LastEditTime: 2025-07-04 17:03:11 * @LastEditors: bogon * @Description: In User Settings Edit * @FilePath: /downLoadServer/src/server/utils/chartsCom/PlotlyChartsFen.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"; /** * 生成折线图并上传 * @param {Object} data - 图表数据 * @returns {Promise} - 返回图片URL */ export const generatePlotlyChartsFen = async ( data, bucketName, objectName, fieldEngineCode ) => { try { // 创建临时目录 const tempDir = path.join(process.cwd(), "images"); await fs.ensureDir(tempDir); const tempFilePath = path.join( tempDir, `temp_heatmap_chart_${Date.now()}.jpeg` ); // 获取 plotly.js 的绝对路径 const plotlyPath = path.join( process.cwd(), "src", "public", "js", "plotly-latest.min.js" ); const plotlyContent = await fs.readFile(plotlyPath, "utf-8"); // 创建浏览器实例 const browser = await puppeteer.launch({ headless: "new", // 根据系统改路径 executablePath: `${process.env.CHROME_PATH}`, // 根据系统改路径 args: ["--no-sandbox", "--disable-setuid-sandbox"], }); try { const page = await browser.newPage(); // 准备图表数据 const sortedData = data.data.sort((a, b) => { if ( a.enginCode === fieldEngineCode && b.enginCode !== fieldEngineCode ) { return 1; } if ( a.enginCode !== fieldEngineCode && b.enginCode === fieldEngineCode ) { return -1; } return 0; }); const finalData = []; let enginName = ""; console.log(fieldEngineCode, "fieldEngineCode"); sortedData .filter((item) => item.enginName !== "合同功率曲线") .forEach((turbine) => { const color = turbine.enginCode === fieldEngineCode ? "#406DAB" : "#D3D3D3"; enginName = turbine.enginCode === fieldEngineCode ? turbine.enginName : ""; const chartConfig = { x: turbine.xData, y: turbine.yData, connectgaps: false, name: turbine.enginName, mode: "lines", fill: "none", line: { color }, marker: { color }, }; finalData.push(chartConfig); }); const filterData = data.data.filter( (item) => item.enginName === "合同功率曲线" ); console.log(filterData, "合同功率曲线"); // 添加合同功率曲线 if (filterData && filterData[0].enginName === "合同功率曲线") { finalData.push({ x: filterData[0].xData, y: filterData[0].yData, mode: "lines+markers", name: "合同功率曲线", line: { color: "red", width: 1, }, marker: { color: "red", size: 4 }, }); } // 准备布局配置 const layout = { title: { text: `机组 ${enginName}风速功率曲线分析`, font: { size: 16, weight: "bold", }, }, xaxis: { title: { text: "风速(m/s)" || "x轴", }, gridcolor: "rgb(255,255,255)", tickcolor: "rgb(255,255,255)", backgroundcolor: "#e5ecf6", }, yaxis: { title: { text: "功率(kW)" || "Y轴" }, gridcolor: "rgb(255,255,255)", tickcolor: "rgb(255,255,255)", backgroundcolor: "#e5ecf6", }, margin: { l: 50, r: 50, t: 50, b: 50, }, autosize: true, plot_bgcolor: "#e5ecf6", gridcolor: "#fff", bgcolor: "#e5ecf6", legend: { orientation: "h", xanchor: "center", x: 0.5, y: -0.2, }, }; // 创建HTML内容 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)); // return formData; // 发送上传请求 const response = await axios.post( `${process.env.API_BASE_URL}/examples/upload`, { filePath: tempFilePath, bucketName, objectName } ); return response?.data?.url; } finally { await browser.close(); } } catch (error) { console.error("生成折线图失败:", error); throw error; } };