Skip to content

Commit e2dd1d6

Browse files
committed
Moved all volume and point-cloud plots to new "Plot" component and canvas. Moved data loader to Plot component. Renamed PlotArea to PlotLine. Added interactive modification of this area with tweakpane. Fixed plotline vertical scale issue.
1 parent e0fed43 commit e2dd1d6

File tree

17 files changed

+280
-130
lines changed

17 files changed

+280
-130
lines changed

src/app/globals.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,17 @@ li {
9494
top: 2.5rem !important ;
9595
right: 0.5rem !important;
9696
z-index: 100 !important;
97+
}
98+
99+
.plot-pane{
100+
position: fixed;
101+
top: 2.5rem !important ;
102+
right: 0.5rem !important;
103+
z-index: 100 !important;
104+
}
105+
106+
.line-plot-pane{
107+
position: absolute;
108+
bottom:300px;
109+
left: 50px;
97110
}

src/components/CanvasGeometry.tsx

Lines changed: 40 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
'use client';
2-
32
import * as THREE from 'three'
43
THREE.Cache.enabled = true;
54
import { Canvas } from '@react-three/fiber';
65
import { Center, OrbitControls, Environment } from '@react-three/drei'
76
import { ZarrDataset, variables } from '@/components/zarr/ZarrLoaderLRU'
87
import { useEffect, useState, useMemo, useRef } from 'react';
98
import { PointCloud, UVCube, PlotArea, DataCube } from '@/components/plots';
10-
import { GetColorMapTexture, ArrayToTexture, DefaultCube, colormaps } from '@/components/textures';
9+
import { GetColorMapTexture, ArrayToTexture, DefaultCubeTexture, colormaps } from '@/components/textures';
1110
import { Metadata } from '@/components/ui';
1211
import { plotContext, DimCoords } from '@/components/contexts';
1312
// import ComputeModule from '@/components/computation/ComputeModule'
14-
import { usePaneInput, usePaneFolder, useTweakpane } from '@lazarusa/react-tweakpane'
13+
import { usePaneInput, usePaneFolder, useTweakpane, useButtonBlade } from '@lazarusa/react-tweakpane'
1514
import { createPaneContainer } from '@/components/ui/paneContainer';
15+
import Plot from './plots/Plot';
1616

1717
interface Array{
1818
data:number[],
@@ -49,20 +49,16 @@ export function CanvasGeometry() {
4949
value: colormap
5050
})), []);
5151

52-
const paneContainer = createPaneContainer();
53-
5452
const pane = useTweakpane(
5553
{
56-
backgroundcolor: "#2d4967",
54+
backgroundcolor: "#2c3d4f",
5755
vName: "Default",
5856
plottype: "volume",
5957
cmap: "Spectral",
6058
flipCmap: false,
6159
},
6260
{
6361
title: 'Settings',
64-
container: paneContainer ?? undefined,
65-
expanded: true,
6662
}
6763
);
6864

@@ -71,7 +67,7 @@ export function CanvasGeometry() {
7167
value: '#2d4967'
7268
})
7369
const [variable] = usePaneInput(pane, 'vName', {
74-
label: 'Name',
70+
label: 'Plot Variable',
7571
options: [
7672
{
7773
text: 'Default',
@@ -82,7 +78,7 @@ export function CanvasGeometry() {
8278
value: 'Default'
8379
})
8480

85-
const [plotter] = usePaneInput(pane, 'plottype', {
81+
const [plotType] = usePaneInput(pane, 'plottype', {
8682
label: 'Plot type',
8783
options: [
8884
{
@@ -118,7 +114,7 @@ export function CanvasGeometry() {
118114
value: false
119115
})
120116

121-
const [texture, setTexture] = useState<THREE.DataTexture | THREE.Data3DTexture | null>(null) //Main Texture
117+
122118
const [shape, setShape] = useState<THREE.Vector3 | THREE.Vector3>(new THREE.Vector3(2, 2, 2))
123119
const [valueScales,setValueScales] = useState({maxVal:1,minVal:-1})
124120
const [colormap,setColormap] = useState<THREE.DataTexture>(GetColorMapTexture())
@@ -128,7 +124,7 @@ export function CanvasGeometry() {
128124
const [dataArray, setDataArray] = useState<Array | null>(null)
129125

130126
//Timeseries Plotting Information
131-
const [dimArrays,setDimArrays] = useState([[0],[0],[0]])
127+
const [dimArrays,setDimArrays] = useState<number[][]>([[0],[0],[0]])
132128
const [dimNames,setDimNames] = useState<string[]>(["default"])
133129
const [dimUnits,setDimUnits] = useState<string[]>(["Default"]);
134130
const [dimCoords, setDimCoords] = useState<DimCoords>();
@@ -141,68 +137,40 @@ export function CanvasGeometry() {
141137
const [executeReduction,setExecuteReduction] = useState<boolean>(false)
142138
const [showAnalysis, setShowAnalysis] = useState<boolean>(false)
143139

140+
//Camera states
141+
// const [resetCamera, setResetCamera] = useState<boolean>(false)
142+
143+
// useButtonBlade(pane, {
144+
// title: "Reset Camera",
145+
// label: "Reset Camera"
146+
// } , ()=>setResetCamera(true))
147+
144148
useEffect(()=>{
145149
setColormap(GetColorMapTexture(colormap,cmap,1,"#000000",0,flipCmap));
146150
},[cmap, colormap,flipCmap])
147151

148-
//DATA LOADING
149-
useEffect(() => {
150-
if (variable != "Default") {
151-
setShowLoading(true);
152-
//Need to add a check somewhere here to swap to 2D or 3D based on shape. Probably export two variables from GetArray
153-
ZarrDS.GetArray(variable).then((result) => {
154-
// result now contains: { data: TypedArray, shape: number[], dtype: string }
155-
const [texture, shape, scaling] = ArrayToTexture({
156-
data: result.data,
157-
shape: result.shape
158-
})
159-
setDataArray(result)
160-
console.log(`logging the shape since we will want to use it in the future for 2D vs 3D actions ${shape}`)
161-
if (texture instanceof THREE.DataTexture || texture instanceof THREE.Data3DTexture) {
162-
setTexture(texture)
163-
} else {
164-
console.error("Invalid texture type returned from ArrayToTexture");
165-
setTexture(null);
166-
}
167-
if (
168-
typeof scaling === 'object' &&
169-
'maxVal' in scaling &&
170-
'minVal' in scaling
171-
) {
172-
setValueScales(scaling as { maxVal: number; minVal: number });
173-
}
174-
const shapeRatio = result.shape[1] / result.shape[2] * 2;
175-
setShape(new THREE.Vector3(2, shapeRatio, 2));
176-
setShowLoading(false)
177-
})
178-
//Get Metadata
179-
ZarrDS.GetAttributes(variable).then((result)=>{
180-
setMetadata(result);
181-
const [dimArrs, dimMetas] = ZarrDS.GetDimArrays()
182-
setDimArrays(dimArrs)
183-
const dimNames = []
184-
const tempDimUnits = []
185-
for (const meta of dimMetas){
186-
dimNames.push(meta.standard_name)
187-
tempDimUnits.push(meta.units)
188-
}
189-
setDimNames(dimNames)
190-
setDimUnits(tempDimUnits)
191-
})
192-
152+
//These values are passed to the Plot Component
153+
const plotObj = {
154+
values:{
155+
plotType,
156+
colormap,
157+
ZarrDS,
158+
variable,
159+
shape,
160+
bgcolor
161+
},
162+
setters:{
163+
setShowLoading,
164+
setDataArray,
165+
setValueScales,
166+
setShape,
167+
setMetadata,
168+
setDimArrays,
169+
setDimNames,
170+
setDimUnits,
193171
}
194-
else{
195-
const texture = DefaultCube();
196-
// again need to check type before using it
197-
if (texture instanceof THREE.Data3DTexture || texture instanceof THREE.DataTexture) {
198-
setTexture(texture);
199-
}
200-
setShape(new THREE.Vector3(2, 2, 2))
201-
setMetadata(null)
202-
}
203-
}, [variable])
172+
}
204173

205-
//These are passed to the UVCube (will be renamed) to extract the timeseries info
206174
const timeSeriesObj ={
207175
setters:{
208176
setTimeSeries,
@@ -225,7 +193,7 @@ export function CanvasGeometry() {
225193
};
226194

227195
//This is the data being passed down the plot tree
228-
const plotObj = {
196+
const lineObj = {
229197
coords: dimCoords ?? defaultDimCoords,
230198
plotDim,
231199
dimNames,
@@ -251,39 +219,14 @@ export function CanvasGeometry() {
251219
return (
252220
<>
253221
<Loading showLoading={showLoading} />
254-
<div className='canvas'>
255-
<Canvas shadows camera={{ position: [-4.5, 3, 4.5], fov: 50 }}
256-
frameloop="demand"
257-
>
258-
259-
<Center top position={[-1, 0, 1]}/>
260-
{/* {dataArray && showAnalysis && <ComputeModule array={dataArray} cmap={colormap} shape={shape.toArray()} stateVars={analysisVars}/>} */}
261-
{/* Volume Plots */}
262-
263-
{plotter == "volume" && <>
264-
<DataCube volTexture={texture} shape={shape} colormap={colormap}/>
265-
<UVCube {...timeSeriesObj} />
266-
</>}
267-
268-
{/* Point Clouds Plots */}
269-
{plotter == "point-cloud" && <PointCloud textures={{texture,colormap}} />}
270-
271-
{/* Time Series Plots */}
272-
<OrbitControls minPolarAngle={0} maxPolarAngle={Math.PI / 2} enablePan={false}
273-
maxDistance={50}
274-
275-
/>
276-
<Environment preset="city" />
277-
278-
</Canvas>
279-
</div>
222+
<Plot values={plotObj.values} setters={plotObj.setters} timeSeriesObj={timeSeriesObj} />
280223
{/* {showAnalysis && <AnalysisWindow setters={analysisSetters}/>} */}
281224
{metadata && <Metadata data={metadata} /> }
282225

283-
<plotContext.Provider value={plotObj} >
226+
<plotContext.Provider value={lineObj} >
284227
{timeSeries.length > 2 && <PlotArea />}
285228
</plotContext.Provider>
286-
229+
287230
<button
288231
style={{
289232
position:'fixed',
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { createContext } from "react";
2+
import * as THREE from 'three'
3+

src/components/plots/DataCube.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useRef } from 'react'
33
import * as THREE from 'three'
44
import { vertexShader, fragmentShader } from '@/components/textures/shaders';
55
import { usePaneInput, usePaneFolder, useSliderBlade, useTweakpane } from '@lazarusa/react-tweakpane'
6+
import { createPaneContainer } from '../ui';
67

78

89
interface DataCubeProps {
@@ -13,13 +14,15 @@ interface DataCubeProps {
1314

1415
export const DataCube = ({ volTexture, shape, colormap }: DataCubeProps ) => {
1516
const meshRef = useRef<THREE.Mesh>(null);
16-
const pane = useTweakpane(
17+
const paneContainer = createPaneContainer("plot-pane");
18+
19+
const pane = useTweakpane(
1720
{
1821
flip: false,
1922
},
2023
{
2124
title: 'Volume',
22-
// container: container,
25+
container: paneContainer ?? undefined,
2326
expanded: true,
2427
}
2528
);

src/components/plots/FixedTicks.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ export function FixedTicks({
5353
const timeStrings = []
5454
for (let i = 0 ; i < xDimArray.length; i++){
5555
const timeStamp = Number(xDimArray[i])*unit
56-
// timeStrings.push(new Date(timeStamp).toDateString())
57-
const date = new Date(timeStamp);
58-
// const dateString = date.toDateString().replace(/\s(\d{4})$/, '\n$1');
59-
const dateString = `${date.getDate().toString().padStart(2, '0')}/${(date.getMonth() + 1).toString().padStart(2, '0')}\n${date.getFullYear()}`;
56+
timeStrings.push(new Date(timeStamp).toDateString())
57+
// const date = new Date(timeStamp);
58+
// // const dateString = date.toDateString().replace(/\s(\d{4})$/, '\n$1');
59+
// const dateString = `${date.getDate().toString().padStart(2, '0')}/${(date.getMonth() + 1).toString().padStart(2, '0')}\n${date.getFullYear()}`;
60+
// // timeStrings.push(dateString);
6061
// timeStrings.push(dateString);
61-
timeStrings.push(dateString);
6262
}
6363
return timeStrings
6464
}
@@ -68,7 +68,7 @@ export function FixedTicks({
6868

6969
const initialBounds = useMemo<ViewportBounds>(()=>{
7070
const worldWidth = window.innerWidth
71-
const worldHeight = (window.innerHeight-height-50)
71+
const worldHeight = (window.innerHeight-height)
7272

7373
const newBounds = {
7474
left: -worldWidth / 2 + camera.position.x,
@@ -256,6 +256,7 @@ export function FixedTicks({
256256
>
257257
{(yRange[0]+(normY*yDimSize)).toFixed(1)}
258258

259+
259260
</Text>
260261
)}
261262
</group>

0 commit comments

Comments
 (0)