From 4ce0ed41054b357bfa2437e6b27dc9d070aae2cd Mon Sep 17 00:00:00 2001 From: Jeran Date: Wed, 11 Jun 2025 11:27:29 +0200 Subject: [PATCH 1/2] mobile_scroll --- src/components/LandingHome.tsx | 51 ++++++++++-------- src/components/ui/VariableScroller.tsx | 60 ++++++++++++++-------- src/components/ui/css/VariableScroller.css | 36 +++++++++++++ src/utils/GlobalStates.ts | 6 ++- 4 files changed, 111 insertions(+), 42 deletions(-) diff --git a/src/components/LandingHome.tsx b/src/components/LandingHome.tsx index e76b95a4..d2f7bb1b 100644 --- a/src/components/LandingHome.tsx +++ b/src/components/LandingHome.tsx @@ -3,7 +3,7 @@ import * as THREE from 'three' THREE.Cache.enabled = true; import { DataStores } from '@/components/zarr/DataStores' import { ZarrDataset, GetStore } from '@/components/zarr/ZarrLoaderLRU'; -import { useState } from 'react'; +import { useRef, useState } from 'react'; import VariableScroller from './ui/VariableScroller'; import { useEffect, useMemo } from 'react'; import { Analysis, PlotArea, Plot } from '@/components/plots'; @@ -11,7 +11,7 @@ import { GetColorMapTexture } from '@/components/textures'; import { MiddleSlider } from '@/components/ui'; import { Metadata, ShowAnalysis, Loading } from '@/components/ui'; import { useGlobalStore } from '@/utils/GlobalStates'; -import { useShallow } from 'zustand/shallow'; +import { useShallow, shallow } from 'zustand/shallow'; import { PaneStore } from '@/components/zarr/PaneStore'; import useCSSVariable from '@/components/ui/useCSSVariable'; import { GetTitleDescription } from '@/components/zarr/GetMetadata'; @@ -22,7 +22,7 @@ export function LandingHome() { const { bgcolor, fullmetadata, variables} = DataStores(); const [settings, setSettings] = useState({plotType: 'volume', cmap: 'Spectral', flipCmap: false }); const initStore = useGlobalStore(useShallow(state=>state.initStore)) - + const [zMeta, setZMeta] = useState([]) const ZarrDS = useMemo(() => new ZarrDataset(initStore), [initStore]) const [titleDescription, setTitleDescription] = useState<{ title?: string; description?: string }>({}); @@ -35,15 +35,20 @@ export function LandingHome() { }, [initStore]); const { title, description } = titleDescription; - - const setColormap = useGlobalStore(state=>state.setColormap) - const metadata = useGlobalStore(state=>state.metadata) - const {colormap, timeSeries, variable} = useGlobalStore(useShallow(state=>({colormap:state.colormap, timeSeries:state.timeSeries, variable:state.variable}))) + const { setColormap, setVariables, colormap, timeSeries, variable, metadata } = useGlobalStore( + useShallow(state => ({ + setColormap: state.setColormap, + setVariables: state.setVariables, + colormap: state.colormap, + timeSeries: state.timeSeries, + variable: state.variable, + metadata: state.metadata, + })) + ); const [showLoading, setShowLoading] = useState(false); const textColor = useCSSVariable('--foreground'); const fogColor = useCSSVariable('--background'); - //Timeseries Plotting Information const [canvasWidth, setCanvasWidth] = useState(0) useEffect(() => { @@ -54,24 +59,28 @@ export function LandingHome() { setColormap(GetColorMapTexture(colormap, settings.cmap, 1, "#000000", 0, settings.flipCmap)); },[settings.cmap, colormap, settings.flipCmap, setColormap]) + useEffect(()=>{ + variables.then(e=> setVariables(e)) + fullmetadata.then(e=> setZMeta(e)) + },[]) + //These values are passed to the Plot Component - const plotObj = { - plotType: settings.plotType, - ZarrDS, - variable, - bgcolor, - canvasWidth - } + const plotObj = useMemo(() => ({ + plotType: settings.plotType, + ZarrDS, + variable, + bgcolor, + canvasWidth + }), [settings.plotType, ZarrDS, variable, bgcolor, canvasWidth]); //This is the data being passed down the plot tree - const analysisObj = { - setters:{ - }, - values:{ + const analysisObj = useMemo(() => ({ + setters: {}, + values: { ZarrDS, canvasWidth, } - } + }), [ZarrDS, canvasWidth]); return ( <> @@ -81,7 +90,7 @@ export function LandingHome() { {canvasWidth > 10 && } {canvasWidth > 10 && } - {variable === "Default" && } + {variable === "Default" && } {variable != "Default" && } {metadata && } {timeSeries.length > 2 && } diff --git a/src/components/ui/VariableScroller.tsx b/src/components/ui/VariableScroller.tsx index 8cf5f9cc..69d75543 100644 --- a/src/components/ui/VariableScroller.tsx +++ b/src/components/ui/VariableScroller.tsx @@ -1,7 +1,6 @@ import React, {useState, useEffect, useMemo, useRef} from 'react' import { useGlobalStore } from '@/utils/GlobalStates' -import { GetStore, ZarrDataset } from '../zarr/ZarrLoaderLRU'; -import { GetZarrMetadata } from '../zarr/GetMetadata'; +import { useShallow } from 'zustand/shallow'; import './css/VariableScroller.css' const formatArray = (value: string | number[]): string => { @@ -12,7 +11,7 @@ const formatArray = (value: string | number[]): string => { const MetaDataInfo = ({meta} : {meta : any}) =>{ const [show, setShow] = useState(false) - const setVariable = useGlobalStore(state=> state.setVariable) + const setVariable = useGlobalStore(useShallow(state=> state.setVariable)) return(
@@ -44,12 +43,14 @@ const MetaDataInfo = ({meta} : {meta : any}) =>{ } -const VariableScroller = ({vars, zarrDS} : {vars : Promise, zarrDS : ZarrDataset}) => { - const [variables, setVariables] = useState([]) +const VariableScroller = ({zMeta} : {zMeta : Object[]}) => { + const variables = useGlobalStore(useShallow(state=>state.variables)) const [selectedIndex, setSelectedIndex] = useState(Math.floor(variables.length / 2)); const [variable, setVariable] = useState("Default") const [meta, setMeta] = useState(null) //This is the individual metadata for the element - const [zMeta, setZMeta] = useState(null) //This is all the metadata. + const [scrollHeight, setScrollHeight] = useState(82); + const previousTouch = useRef(null) + const touchDelta = useRef(0) const handleScroll = (event: any) => { const newIndex = @@ -59,36 +60,55 @@ const VariableScroller = ({vars, zarrDS} : {vars : Promise, zarrDS : Z } }; + const handleTouchScroll = (event: any) => { + const touch = event.touches[0] + const newY = touch.clientY + const prev = previousTouch.current ? previousTouch.current : newY + const thisDelta = prev - newY + previousTouch.current = newY + touchDelta.current += thisDelta + if (Math.abs(touchDelta.current) >= scrollHeight){ + const newIndex = + selectedIndex + (touchDelta.current > 0 ? 1 : -1); + if (newIndex >= 0 && newIndex < variables.length) { + setSelectedIndex(newIndex); + touchDelta.current = 0; + } + } + } + useEffect(()=>{ //Update variable onScroll if (variables){ setVariable(variables[selectedIndex]) } },[selectedIndex, variables]) - useEffect(()=>{ - vars.then(e=>setVariables(e)) - },[vars]) - - useEffect(()=>{ - if(zarrDS){ - //@ts-expect-error - GetZarrMetadata(zarrDS.groupStore).then(e=>{setZMeta(e)}) //groupStore is private but I really don't care - } - },[zarrDS]) - - useEffect(()=>{ + useEffect(()=>{ //Grab relevant metadata if(zMeta){ const relevant = zMeta.find((e : any) => e.name === variable) setMeta(relevant) } },[variable]) + useEffect(()=>{ //Sets scrollsize. Doesn't work with resize though + const width = window.innerWidth + if (width <= 480){ + setScrollHeight(42) + } + else if (width <= 570){ + setScrollHeight(54) + } + else { + setScrollHeight(82) + } + },[]) + return ( -
+
{previousTouch.current = null; touchDelta.current = 0}}> {meta && }
{variables.map((variable, index) => { diff --git a/src/components/ui/css/VariableScroller.css b/src/components/ui/css/VariableScroller.css index 67792e64..f0bd7a9c 100644 --- a/src/components/ui/css/VariableScroller.css +++ b/src/components/ui/css/VariableScroller.css @@ -63,4 +63,40 @@ cursor: pointer; font-size: 10px; margin-top: 5px; +} + +@media (max-width: 1024px) { + .meta-container{ + top: 5%; + left: 10%; + font-size: 16px; + min-width: 350px; + max-width: 450px; + } +} + +@media (max-width: 570px) { + .meta-container{ + top: 5%; + left: 7.5%; + font-size: 16px; + width: 85%; + } + .scroll-item { + font-size: 32px; + margin: 3px; + } +} + +@media (max-width: 480px) { + .meta-container{ + top: 48px; + left: 7.5%; + font-size: 14px; + width: 85%; + } + .scroll-item { + font-size: 24px; + margin: 3px; + } } \ No newline at end of file diff --git a/src/utils/GlobalStates.ts b/src/utils/GlobalStates.ts index a084113b..780e04e0 100644 --- a/src/utils/GlobalStates.ts +++ b/src/utils/GlobalStates.ts @@ -31,6 +31,7 @@ type StoreState = { flipY:boolean; initStore:string; variable: string; + variables: string[]; setShape: (shape: THREE.Vector3) => void; setValueScales: (valueScales: { maxVal: number; minVal: number }) => void; @@ -47,10 +48,12 @@ type StoreState = { setFlipY: (flipY:boolean) => void; setInitStore: (initStore:string ) => void; setVariable: (variable: string) => void; + setVariables: (variables: string[]) => void; }; export const useGlobalStore = create((set) => ({ + shape: new THREE.Vector3(2, 2, 2), valueScales: { maxVal: 1, minVal: -1 }, colormap: GetColorMapTexture(), @@ -66,7 +69,7 @@ export const useGlobalStore = create((set) => ({ flipY: false, initStore: "https://s3.bgc-jena.mpg.de:9000/esdl-esdc-v3.0.2/esdc-16d-2.5deg-46x72x1440-3.0.2.zarr", variable: 'Default', - + variables: [], setShape: (shape) => set({ shape }), setValueScales: (valueScales) => set({ valueScales }), setColormap: (colormap) => set({ colormap }), @@ -85,4 +88,5 @@ export const useGlobalStore = create((set) => ({ console.log('✅ setting variable:', variable) set({ variable }) }, + setVariables: (variables) => set({variables}) })); \ No newline at end of file From 7edb9b2794cd4fb69d54938d173baf04539344c5 Mon Sep 17 00:00:00 2001 From: Jeran Date: Wed, 11 Jun 2025 11:33:01 +0200 Subject: [PATCH 2/2] lint --- src/components/ui/VariableScroller.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/VariableScroller.tsx b/src/components/ui/VariableScroller.tsx index 69d75543..361ae01b 100644 --- a/src/components/ui/VariableScroller.tsx +++ b/src/components/ui/VariableScroller.tsx @@ -43,7 +43,7 @@ const MetaDataInfo = ({meta} : {meta : any}) =>{ } -const VariableScroller = ({zMeta} : {zMeta : Object[]}) => { +const VariableScroller = ({zMeta} : {zMeta : object[]}) => { const variables = useGlobalStore(useShallow(state=>state.variables)) const [selectedIndex, setSelectedIndex] = useState(Math.floor(variables.length / 2)); const [variable, setVariable] = useState("Default")