123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
- <style>
- body {
- margin: 0;
- }
- #plot {
- width: 100vw;
- height: 100vh;
- }
- </style>
- </head>
- <body>
- <div id="plot"></div>
- <script>
- const xLabels = ["A", "B", "C"];
- const yLabels = ["Monday", "Tuesday", "Wednesday"];
- const dataMatrix = [
- [5, 8, 6],
- [4, 2, 9],
- [7, 3, 5],
- ];
- // 构造立方体柱子
- const traces = [];
- const barWidth = 0.8;
- for (let xi = 0; xi < xLabels.length; xi++) {
- for (let yi = 0; yi < yLabels.length; yi++) {
- const height = dataMatrix[yi][xi];
- const x = xi;
- const y = yi;
- const z = 0;
- // 立方体8个顶点
- const vertices = [
- [x, y, z],
- [x + barWidth, y, z],
- [x + barWidth, y + barWidth, z],
- [x, y + barWidth, z],
- [x, y, z + height],
- [x + barWidth, y, z + height],
- [x + barWidth, y + barWidth, z + height],
- [x, y + barWidth, z + height],
- ];
- // 每个立方体的面(两个三角形组成一个面)
- const faces = [
- [0, 1, 2],
- [0, 2, 3], // bottom
- [4, 5, 6],
- [4, 6, 7], // top
- [0, 1, 5],
- [0, 5, 4], // front
- [1, 2, 6],
- [1, 6, 5], // right
- [2, 3, 7],
- [2, 7, 6], // back
- [3, 0, 4],
- [3, 4, 7], // left
- ];
- // 拆解为 Plotly mesh3d 的输入格式
- const xVals = vertices.map((v) => v[0]);
- const yVals = vertices.map((v) => v[1]);
- const zVals = vertices.map((v) => v[2]);
- const i = faces.map((f) => f[0]);
- const j = faces.map((f) => f[1]);
- const k = faces.map((f) => f[2]);
- traces.push({
- type: "mesh3d",
- x: xVals,
- y: yVals,
- z: zVals,
- i,
- j,
- k,
- opacity: 1,
- color: `rgb(${50 + xi * 50}, ${100 + yi * 50}, 200)`,
- flatshading: true,
- showscale: false,
- });
- }
- }
- const layout = {
- scene: {
- xaxis: {
- title: "X",
- tickvals: [0.4, 1.4, 2.4],
- ticktext: xLabels,
- },
- yaxis: {
- title: "Y",
- tickvals: [0.4, 1.4, 2.4],
- ticktext: yLabels,
- },
- zaxis: { title: "Z" },
- aspectratio: {
- x: 2.2,
- y: 1.7,
- z: 1,
- },
- bgcolor: "#e5ecf6",
- aspectmode: "manual",
- gridcolor: "#fff",
- 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",
- },
- },
- staticPlot: false,
- showlegend: true,
- legend: {
- itemsizing: "constant", // ✅ 统一图例 marker 大小
- font: {
- size: 12,
- },
- marker: {
- size: 10,
- },
- },
- },
- margin: { t: 50, b: 50, l: 50, r: 50 },
- };
- Plotly.newPlot("plot", traces, layout);
- </script>
- </body>
- </html>
|