/*
* @Author: your name
* @Date: 2025-04-14 16:09:13
* @LastEditTime: 2025-04-30 13:47:08
* @LastEditors: bogon
* @Description: In User Settings Edit
* @FilePath: /downLoadServer/src/server/utils/chartsCom/3DDrawingChart.js
*/
import puppeteer from "puppeteer";
import fs from "fs-extra";
import path from "path";
import FormData from "form-data";
import { colorSchemes } from "../colors.js";
export const generate3DDrawingChart = async (data) => {
try {
console.log("开始生成热力图...");
console.log("数据:", data);
const colorSchemesItem = colorSchemes[0].colors;
// 创建临时目录
const tempDir = path.join(process.cwd(), "images");
await fs.ensureDir(tempDir);
const tempFilePath = path.join(
tempDir,
`temp_heatmap_chart_${Date.now()}.png`
);
// 获取 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");
// 创建浏览器实例
const browser = await puppeteer.launch({
headless: "new",
args: ["--no-sandbox", "--disable-setuid-sandbox"],
});
try {
const page = await browser.newPage();
// 准备图表数据
const chartDataset = data.data[0]; // 修改为 data.chartData
const uniqueColors = [...new Set(chartDataset.color)];
const traces = uniqueColors.map((color, idx) => {
const colorData = chartDataset.color.map((c) => (c === color ? 1 : 0));
return {
x: chartDataset.xData.filter((_, i) => colorData[i] === 1),
y: chartDataset.yData.filter((_, i) => colorData[i] === 1),
z: chartDataset.zData.filter((_, i) => colorData[i] === 1),
mode: "markers", // 根据需要设置模式
type: "scatter3d",
marker: {
size: 1, // 使用动态点大小
color: colorSchemesItem[idx], // 使用配色方案
colorscale: "YlGnBu",
},
name: ` ${color}`,
// hovertemplate: `${data.xaixs}: %{x}
${data.yaixs}: %{y}
${data.zaixs}: %{z} `,
};
});
// 准备布局配置
const layout = {
title: {
text: chartDataset.title,
font: {
size: 16,
weight: "bold",
},
},
scene: {
xaxis: {
gridcolor: "rgb(255,255,255)",
tickcolor: "rgb(255,255,255)",
backgroundcolor: "#CFD4DC",
showbackground: true,
linecolor: "black", // 轴线颜色
ticks: "outside", // 设置刻度线在轴线外
fixedrange: true, // 防止缩放
tickcolor: "black",
tickangle: -10,
title: {
text: data.xaixs,
},
},
yaxis: {
type: "category",
categoryorder: "array", // 自定义顺序,确保间隔均匀
categoryarray: [...new Set(chartDataset.yData)],
gridcolor: "rgb(255,255,255)",
linecolor: "black",
ticks: "outside",
gridcolor: "rgb(255,255,255)",
tickcolor: "rgb(255,255,255)",
backgroundcolor: "#CFD4DC",
showbackground: true,
tickcolor: "black",
tickangle: 25,
title: {
text: data.yaixs,
},
},
zaxis: {
gridcolor: "rgb(255,255,255)",
tickcolor: "rgb(255,255,255)",
backgroundcolor: "#CFD4DC",
showbackground: true,
fixedrange: true, // 防止缩放
linecolor: "black", // 轴线颜色
ticks: "outside", // 设置刻度线在轴线外
tickcolor: "black",
tickangle: -90,
title: {
text: data.zaixs,
},
},
aspectratio: {
x: 2.2,
y: 1.7,
z: 1,
},
plot_bgcolor: "#e5ecf6",
gridcolor: "#fff",
bgcolor: "#e5ecf6", // 设置背景颜色
camera: {
up: {
x: 0.200292643688136,
y: 0.2488259353493132,
z: 0.947612004346693,
},
center: {
x: -0.052807476121180814,
y: 0.02451796399554085,
z: -0.022911006648570736,
},
eye: {
x: -2.126379643342493,
y: -2.551422475965373,
z: 1.0917667684145647,
},
projection: {
type: "orthographic",
},
},
},
margin: { t: 50, b: 50, l: 50, r: 50 },
staticPlot: false,
showlegend: true,
legend: {
marker: {
size: 10, // 图例中点的大小
},
},
};
// 准备 HTML 内容
const htmlContent = `
热力图
`;
// ... existing code ...
// 设置页面内容
await page.setContent(htmlContent, {
waitUntil: "networkidle0",
});
// 等待图表渲染完成,延长超时时间
await page.waitForFunction(() => window.chartRendered === true, {
timeout: 150000, // 延长到 120 秒
});
// 截图并保存到临时文件
const chartElement = await page.$("#chart");
await chartElement.screenshot({
path: tempFilePath,
type: "png",
});
// 上传图片到服务器
const formData = new FormData();
formData.append("file", fs.createReadStream(tempFilePath));
// 发送上传请求
const response = await axios.post(
`${process.env.API_BASE_URL}/examples/upload`,
{ filePath: tempFilePath }
);
// return formData;
} catch (error) {
console.error("生成3D图失败:", error);
throw error;
} finally {
await browser.close();
}
} catch (error) {
console.error("生成3D图失败:", error);
throw error;
}
};