Improved Ui and plotting stuff
This commit is contained in:
+46
-15
@@ -42,19 +42,33 @@ export default function Home() {
|
|||||||
const [plotType, setPlotType] = useState<PlotType>("scatter");
|
const [plotType, setPlotType] = useState<PlotType>("scatter");
|
||||||
const [colorscale, setColorscale] = useState<string>(COLORSCALES[0]);
|
const [colorscale, setColorscale] = useState<string>(COLORSCALES[0]);
|
||||||
|
|
||||||
|
// First row after header = axis sizes (X max, Y max, Z max); rest = plot data.
|
||||||
|
const plotData = rows.length > 1 ? rows.slice(1) : rows;
|
||||||
|
const axisSizes =
|
||||||
|
rows.length > 1 && x && y && z
|
||||||
|
? (() => {
|
||||||
|
const sx = Number(rows[0][x]);
|
||||||
|
const sy = Number(rows[0][y]);
|
||||||
|
const sz = Number(rows[0][z]);
|
||||||
|
return [sx, sy, sz].every((n) => Number.isFinite(n))
|
||||||
|
? { x: sx, y: sy, z: sz }
|
||||||
|
: null;
|
||||||
|
})()
|
||||||
|
: null;
|
||||||
|
|
||||||
// Build surface grid from scattered (x,y,z) points. Returns null if data isn't a grid.
|
// Build surface grid from scattered (x,y,z) points. Returns null if data isn't a grid.
|
||||||
function buildSurfaceGrid(): {
|
function buildSurfaceGrid(): {
|
||||||
xUnique: number[];
|
xUnique: number[];
|
||||||
yUnique: number[];
|
yUnique: number[];
|
||||||
zMatrix: number[][];
|
zMatrix: number[][];
|
||||||
} | null {
|
} | null {
|
||||||
const xVals = rows.map((r) => Number(r[x]));
|
const xVals = plotData.map((r) => Number(r[x]));
|
||||||
const yVals = rows.map((r) => Number(r[y]));
|
const yVals = plotData.map((r) => Number(r[y]));
|
||||||
const zVals = rows.map((r) => Number(r[z]));
|
const zVals = plotData.map((r) => Number(r[z]));
|
||||||
const xUnique = [...new Set(xVals)].sort((a, b) => a - b);
|
const xUnique = [...new Set(xVals)].sort((a, b) => a - b);
|
||||||
const yUnique = [...new Set(yVals)].sort((a, b) => a - b);
|
const yUnique = [...new Set(yVals)].sort((a, b) => a - b);
|
||||||
const keyToZ = new Map<string, number>();
|
const keyToZ = new Map<string, number>();
|
||||||
for (let i = 0; i < rows.length; i++) {
|
for (let i = 0; i < plotData.length; i++) {
|
||||||
const k = `${xVals[i]},${yVals[i]}`;
|
const k = `${xVals[i]},${yVals[i]}`;
|
||||||
if (!keyToZ.has(k)) keyToZ.set(k, zVals[i]);
|
if (!keyToZ.has(k)) keyToZ.set(k, zVals[i]);
|
||||||
}
|
}
|
||||||
@@ -75,9 +89,9 @@ export default function Home() {
|
|||||||
const Plotly = await import("plotly.js-dist-min");
|
const Plotly = await import("plotly.js-dist-min");
|
||||||
if (cancelled) return;
|
if (cancelled) return;
|
||||||
|
|
||||||
const xVals = rows.map((r) => Number(r[x]));
|
const xVals = plotData.map((r) => Number(r[x]));
|
||||||
const yVals = rows.map((r) => Number(r[y]));
|
const yVals = plotData.map((r) => Number(r[y]));
|
||||||
const zVals = rows.map((r) => Number(r[z]));
|
const zVals = plotData.map((r) => Number(r[z]));
|
||||||
|
|
||||||
const grid = buildSurfaceGrid();
|
const grid = buildSurfaceGrid();
|
||||||
const useSurface = plotType === "surface" && grid !== null;
|
const useSurface = plotType === "surface" && grid !== null;
|
||||||
@@ -104,6 +118,21 @@ export default function Home() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sceneLayout: {
|
||||||
|
xaxis: { title: { text: string }; range?: [number, number] };
|
||||||
|
yaxis: { title: { text: string }; range?: [number, number] };
|
||||||
|
zaxis: { title: { text: string }; range?: [number, number] };
|
||||||
|
} = {
|
||||||
|
xaxis: { title: { text: x } },
|
||||||
|
yaxis: { title: { text: y } },
|
||||||
|
zaxis: { title: { text: z } },
|
||||||
|
};
|
||||||
|
if (axisSizes) {
|
||||||
|
sceneLayout.xaxis.range = [0, axisSizes.x];
|
||||||
|
sceneLayout.yaxis.range = [0, axisSizes.y];
|
||||||
|
sceneLayout.zaxis.range = [0, axisSizes.z];
|
||||||
|
}
|
||||||
|
|
||||||
Plotly.newPlot(
|
Plotly.newPlot(
|
||||||
plotRef.current!,
|
plotRef.current!,
|
||||||
[trace],
|
[trace],
|
||||||
@@ -111,11 +140,7 @@ export default function Home() {
|
|||||||
paper_bgcolor: "#0b0d12",
|
paper_bgcolor: "#0b0d12",
|
||||||
plot_bgcolor: "#0b0d12",
|
plot_bgcolor: "#0b0d12",
|
||||||
font: { color: "#cfd3ff" },
|
font: { color: "#cfd3ff" },
|
||||||
scene: {
|
scene: sceneLayout,
|
||||||
xaxis: { title: { text: x } },
|
|
||||||
yaxis: { title: { text: y } },
|
|
||||||
zaxis: { title: { text: z } },
|
|
||||||
},
|
|
||||||
margin: { l: 0, r: 0, t: 0, b: 0 },
|
margin: { l: 0, r: 0, t: 0, b: 0 },
|
||||||
},
|
},
|
||||||
{ responsive: true }
|
{ responsive: true }
|
||||||
@@ -198,6 +223,12 @@ export default function Home() {
|
|||||||
file:rounded file:px-2 file:py-1"
|
file:rounded file:px-2 file:py-1"
|
||||||
/>
|
/>
|
||||||
</Control>
|
</Control>
|
||||||
|
<p className="text-xs text-muted">
|
||||||
|
First data row = axis sizes (X max, Y max, Z max). Plot uses rows after that.{" "}
|
||||||
|
<a href="/example-surface.csv" className="text-accent underline" download>
|
||||||
|
Example (surface)
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<Control label="X axis">
|
<Control label="X axis">
|
||||||
<select
|
<select
|
||||||
@@ -270,16 +301,16 @@ export default function Home() {
|
|||||||
</Control>
|
</Control>
|
||||||
|
|
||||||
{plotType === "surface" &&
|
{plotType === "surface" &&
|
||||||
rows.length > 0 &&
|
plotData.length > 0 &&
|
||||||
buildSurfaceGrid() === null && (
|
buildSurfaceGrid() === null && (
|
||||||
<p className="text-xs text-amber-500/90">
|
<p className="text-xs text-amber-500/90">
|
||||||
Surface needs a full X×Y grid of points. Showing dots instead.
|
Surface needs a full X and Y grid of points. Showing dots instead.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={exportPNG}
|
onClick={exportPNG}
|
||||||
className="w-full mt-2 bg-accent text-black text-sm rounded px-2 py-1 hover:opacity-90"
|
className="w-full mt-2 bg-accent text-sm rounded px-2 py-1 hover:opacity-90"
|
||||||
>
|
>
|
||||||
Export PNG
|
Export PNG
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user