import puppeteer from "puppeteer"; import fs from "fs-extra"; import path from "path"; import FormData from "form-data"; import axios from "axios"; // 导入 axios import { colorSchemes } from "../colors.js"; export const getFaultAllCharts = async ( data, bucketName, objectName, analysisTypeCode ) => { // 获取 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"); // console.log(data, "全场故障数据"); try { // 提取故障类型、故障次数和故障时长 const faultTypes = data.map((item) => item.fault_detail); const faultCounts = data.map((item) => item.count); const faultDurations = data.map((item) => item.fault_time_sum); // 故障次数的柱状图数据(左侧 Y 轴) const barTrace = { x: faultTypes.slice(0, 10), y: faultCounts.slice(0, 10), type: "bar", marker: { color: "#64ADC2" }, // 蓝色柱状图 name: "故障次数", hovertemplate: `故障类型: %{x}
故障次数: %{y} 次
`, }; // 故障时长的折线图数据(右侧 Y 轴) const lineTrace = { x: faultTypes.slice(0, 10), y: faultDurations.slice(0, 10), type: "scatter", mode: "lines+markers", // 线性图 + 点标记 line: { color: "#1A295D" }, // 红色折线 name: "故障时长", yaxis: "y2", // 使用第二个 Y 轴(右侧) hovertemplate: `故障类型: %{x}
故障时长: %{y} 小时
`, }; // 布局配置,设置双 Y 轴 const layout = { title: { text: "全场故障次数与时长分析Top10", font: { size: 16, // 设置标题字体大小(默认 16) weight: "bold", }, }, xaxis: { title: { text: "故障类型", }, tickangle: 30, tickmode: "array", tickvals: faultTypes.slice(0, 10), tickfont: { size: 12 }, gridcolor: "rgb(255,255,255)", tickcolor: "rgb(255,255,255)", backgroundcolor: "#e5ecf6", }, yaxis: { title: { text: "故障次数", }, titlefont: { color: "#64ADC2" }, tickfont: { color: "#64ADC2" }, side: "left", // 左侧的 Y 轴 showline: true, linecolor: "#64ADC2", gridcolor: "rgb(255,255,255)", tickcolor: "rgb(255,255,255)", backgroundcolor: "#e5ecf6", }, yaxis2: { title: { text: "故障时长 (小时)", }, titlefont: { color: "#1A295D" }, tickfont: { color: "#1A295D" }, overlaying: "y", // 在第一个 Y 轴上方绘制 side: "right", // 右侧的 Y 轴 position: 1, // 调整右侧轴的位置 showline: true, linecolor: "#1A295D", // 设置右侧轴线颜色 }, barmode: "group", // 柱状图分组 plot_bgcolor: "#e5ecf6", gridcolor: "#fff", bgcolor: "#e5ecf6", // 设置背景颜色 showlegend: false, margin: { t: 80, // 上边距 b: 150, // 下边距,给 X 轴标签更多空间 }, }; // 创建临时目录 const tempDir = path.join(process.cwd(), "images"); await fs.ensureDir(tempDir); const tempFilePath = path.join( tempDir, `temp_fault_all_chart_${Date.now()}.jpeg` ); // 使用 Puppeteer 生成图表的截图 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 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, } ); return response?.data?.url; } catch (error) { console.error("生成图表失败:", error); } finally { await browser.close(); } } catch (error) { console.error("发生错误:", error); } };