yawErrorBarSum.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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()}.jpeg`
  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. // 根据系统改路径
  102. executablePath: `${process.env.CHROME_PATH}`, // 根据系统改路径
  103. args: ["--no-sandbox", "--disable-setuid-sandbox"],
  104. });
  105. try {
  106. const page = await browser.newPage();
  107. const htmlContent = `
  108. <!DOCTYPE html>
  109. <html>
  110. <head>
  111. <meta charset="UTF-8">
  112. <title>静态偏航误差值</title>
  113. <script>${plotlyContent}</script>
  114. <style>
  115. body { margin: 0; }
  116. #chart { width: 800px; height: 600px; }
  117. </style>
  118. </head>
  119. <body>
  120. <div id="chart"></div>
  121. <script>
  122. window.onload = function() {
  123. Plotly.newPlot('chart', [${JSON.stringify(
  124. trace
  125. )}], ${JSON.stringify(layout)}).then(() => {
  126. window.chartRendered = true;
  127. });
  128. };
  129. </script>
  130. </body>
  131. </html>
  132. `;
  133. await page.setContent(htmlContent, { waitUntil: "networkidle0" });
  134. await page.waitForFunction(() => window.chartRendered === true, {
  135. timeout: 60000,
  136. });
  137. // 截图并保存到临时文件
  138. const chartElement = await page.$("#chart");
  139. await chartElement.screenshot({ path: tempFilePath, type: "jpeg" });
  140. // 上传图片到服务器
  141. const formData = new FormData();
  142. formData.append("file", fs.createReadStream(tempFilePath));
  143. const response = await axios.post(
  144. `${process.env.API_BASE_URL}/examples/upload`,
  145. {
  146. filePath: tempFilePath,
  147. bucketName,
  148. objectName,
  149. }
  150. );
  151. return response.data.url;
  152. } catch (error) {
  153. console.error("生成图表失败:", error);
  154. } finally {
  155. await browser.close();
  156. }
  157. } catch (error) {
  158. console.error("发生错误:", error);
  159. }
  160. };