yawErrorBarSum.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import puppeteer from "puppeteer";
  2. import fs from "fs-extra";
  3. import path from "path";
  4. import FormData from "form-data";
  5. import axios from "axios"; // 导入 axios
  6. import { colorSchemes } from "../colors.js";
  7. import { text } from "stream/consumers";
  8. export const getYawErrorBarSumCharts = async (
  9. data,
  10. bucketName,
  11. objectName,
  12. analysisTypeCode
  13. ) => {
  14. try {
  15. // 提取静态偏航误差值和机组数量
  16. let a = [];
  17. let b = [];
  18. let c = [];
  19. data.map((item) => {
  20. if (item["[0,3]"] != "0.0") {
  21. a.push(item["[0,3]"]);
  22. }
  23. if (item["(3,5]"] != "0.0") {
  24. b.push(item["(3,5]"]);
  25. }
  26. if (item["(5, )"] != "0.0") {
  27. c.push(item["(5, )"]);
  28. }
  29. });
  30. const xData = ["(0,3]", "(3,5]", "(>5]"]; // 偏航误差区间
  31. const yData = [a.length, b.length, c.length]; // 各区间的机组数量
  32. // 每个柱子的颜色
  33. const colors = [
  34. "#8AC8BE", // (0, 3] 蓝色
  35. "#407DB3", // (3, 5] 绿色
  36. "#1B2973", // (5, ∞] 红色
  37. ];
  38. const trace = {
  39. x: xData, // 横坐标数据
  40. y: yData, // 纵坐标数据
  41. type: "bar", // 当前图表类型
  42. marker: {
  43. color: colors, // 为每个柱子分配不同的颜色
  44. },
  45. // hovertemplate:
  46. // `偏航误差值:` + ` %{x} <br> ` + `台数:` + "%{y} <br> <extra></extra>",
  47. };
  48. const layout = {
  49. title: {
  50. text: "静态偏航误差的绝对值机组台数分布情况",
  51. font: {
  52. size: 16,
  53. weight: "bold",
  54. },
  55. }, // 图表标题
  56. xaxis: {
  57. title: { text: "静态偏航误差值(度)" }, // 横坐标标题
  58. gridcolor: "rgb(255,255,255)",
  59. tickcolor: "rgb(255,255,255)",
  60. backgroundcolor: "#e5ecf6",
  61. },
  62. yaxis: {
  63. title: {
  64. text: "台数",
  65. }, // 纵坐标标题
  66. gridcolor: "rgb(255,255,255)",
  67. tickcolor: "rgb(255,255,255)",
  68. backgroundcolor: "#e5ecf6",
  69. },
  70. margin: {
  71. l: 50,
  72. r: 50,
  73. t: 50,
  74. b: 50,
  75. },
  76. autosize: true, // 开启自适应
  77. // showlegend: true, // 显示图例
  78. plot_bgcolor: "#e5ecf6",
  79. gridcolor: "#fff",
  80. bgcolor: "#e5ecf6", // 设置背景颜色
  81. };
  82. // 创建临时目录
  83. const tempDir = path.join(process.cwd(), "images");
  84. await fs.ensureDir(tempDir);
  85. const tempFilePath = path.join(
  86. tempDir,
  87. `temp_yaw_error_bar_sum_chart_${Date.now()}.png`
  88. );
  89. // 获取 plotly.js 的绝对路径
  90. const plotlyPath = path.join(
  91. process.cwd(),
  92. "src",
  93. "public",
  94. "js",
  95. "plotly-3.0.1.min.js"
  96. );
  97. const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
  98. // 使用 Puppeteer 生成图表的截图
  99. const browser = await puppeteer.launch({
  100. headless: "new",
  101. args: ["--no-sandbox", "--disable-setuid-sandbox"],
  102. });
  103. try {
  104. const page = await browser.newPage();
  105. const htmlContent = `
  106. <!DOCTYPE html>
  107. <html>
  108. <head>
  109. <meta charset="UTF-8">
  110. <title>静态偏航误差值</title>
  111. <script>${plotlyContent}</script>
  112. <style>
  113. body { margin: 0; }
  114. #chart { width: 800px; height: 600px; }
  115. </style>
  116. </head>
  117. <body>
  118. <div id="chart"></div>
  119. <script>
  120. window.onload = function() {
  121. Plotly.newPlot('chart', [${JSON.stringify(
  122. trace
  123. )}], ${JSON.stringify(layout)}).then(() => {
  124. window.chartRendered = true;
  125. });
  126. };
  127. </script>
  128. </body>
  129. </html>
  130. `;
  131. await page.setContent(htmlContent, { waitUntil: "networkidle0" });
  132. await page.waitForFunction(() => window.chartRendered === true, {
  133. timeout: 60000,
  134. });
  135. // 截图并保存到临时文件
  136. const chartElement = await page.$("#chart");
  137. await chartElement.screenshot({ path: tempFilePath, type: "png" });
  138. // 上传图片到服务器
  139. const formData = new FormData();
  140. formData.append("file", fs.createReadStream(tempFilePath));
  141. const response = await axios.post(
  142. `${process.env.API_BASE_URL}/examples/upload`,
  143. {
  144. filePath: tempFilePath,
  145. bucketName,
  146. objectName,
  147. }
  148. );
  149. return response.data.url;
  150. console.log("上传成功:", response.data);
  151. } catch (error) {
  152. console.error("生成图表失败:", error);
  153. } finally {
  154. await browser.close();
  155. }
  156. } catch (error) {
  157. console.error("发生错误:", error);
  158. }
  159. };