| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- 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";
- // 获取 plotly.js 的绝对路径
- const plotlyPath = path.join(
- process.cwd(),
- "src",
- "public",
- "js",
- "echarts.min.js"
- );
- const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
- // HTML 模板
- const getHtmlContent = () => `
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <title>Radar Chart</title>
- <script>${plotlyContent}</script>
- <style>
- html, body { margin: 0; padding: 0; width: 600px; height: 600px; }
- #chart { width: 100%; height: 100%; }
- </style>
- </head>
- <body>
- <div id="chart"></div>
- <script>
- window.renderChart = function (chartData, itemCsvData) {
- function calcValues(data) {
- const matrix = data.map((item) => [
- item.TurbinePowerRate,
- item.TurbineRunRate,
- item.WindSpeedAvr,
- item.Thi,
- item.Ws,
- ]);
- const max = matrix[0].map((_, i) => Math.max(...matrix.map(row => row[i])));
- const min = matrix[0].map((_, i) => Math.min(...matrix.map(row => row[i])));
- const median = matrix[0].map((_, i) => {
- const sorted = matrix.map(row => row[i]).sort((a, b) => a - b);
- const mid = Math.floor(sorted.length / 2);
- return sorted.length % 2 === 0
- ? (sorted[mid - 1] + sorted[mid]) / 2
- : sorted[mid];
- });
- return { max, min, median };
- }
- const { max, min, median } = calcValues(itemCsvData);
- const values = [
- chartData.TurbinePowerRate,
- chartData.TurbineRunRate,
- chartData.WindSpeedAvr,
- chartData.Thi,
- chartData.Ws,
- ];
- const indicators = [
- { name: "风机能量利用率", max: max[0], min: min[0] },
- { name: "风机可利用率", max: max[1], min: min[1] },
- { name: "平均风速", max: max[2], min: min[2] },
- { name: "等效利用小时", max: max[3], min: min[3] },
- { name: "功率曲线一致性系数", max: max[4], min: min[4] },
- ];
- const chart = echarts.init(document.getElementById("chart"));
- chart.setOption({
- title: {
- text: chartData.wind_turbine_name + "机组指标",
- left: "center",
- },
- radar: {
- indicator: indicators,
- center: ["50%", "50%"],
- radius: "60%",
- },
- series: [
- {
- type: "radar",
- data: [
- {
- value: values,
- name: chartData.wind_turbine_name,
- areaStyle: { color: "rgba(99,110,252,0.3)" },
- },
- {
- value: median,
- name: "中位值",
- lineStyle: {
- type: "dashed",
- color: "#f39c12",
- },
- },
- ],
- },
- ],
- });
- };
- </script>
- </body>
- </html>
- `;
- export const getRadarCharts = async (
- chartData,
- itemCsvData,
- bucketName,
- objectName
- ) => {
- const browser = await puppeteer.launch();
- const page = await browser.newPage();
- // 创建临时目录
- const tempDir = path.join(process.cwd(), "images");
- await fs.ensureDir(tempDir);
- const tempFilePath = path.join(
- tempDir,
- `temp_scatter_chart_${Date.now()}.png`
- );
- await page.setContent(getHtmlContent(), { waitUntil: "load" });
- // 等待 renderChart 被定义
- await page.waitForFunction(() => typeof window.renderChart === "function");
- // 调用渲染函数
- await page.evaluate(
- (chartData, itemCsvData) => {
- window.renderChart(chartData, itemCsvData);
- },
- chartData,
- itemCsvData
- );
- // 再等待图表渲染完成(给 ECharts 时间)
- (await page.waitForTimeout)
- ? page.waitForTimeout(1000)
- : new Promise((res) => setTimeout(res, 1000));
- // 上传逻辑
- // 截图并保存到临时文件
- const chartElement = await page.$("#chart");
- await chartElement.screenshot({
- path: tempFilePath,
- type: "png",
- });
- try {
- const newUrl = objectName.substring(0, objectName.lastIndexOf("/"));
- // 上传图片到服务器
- 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: newUrl + "/" + chartData.wind_turbine_name + ".jpg",
- }
- );
- return response?.data?.url;
- } catch (error) {
- console.error("❌ 上传失败:", error.message);
- }
- };
|