Skip to content

Commit

Permalink
Use defaultValue for Zarr URL to allow more edits (#50)
Browse files Browse the repository at this point in the history
This uses `defaultValue` instead of `value` in the JSX component definition, to allow more flexible editing on the Zarr URL. This also changes the `dataUrl` state from a `URL` to a `string` to simplify passing it around and validating it.

Closes #46 

---------

Co-authored-by: Ashley Anderson <[email protected]>
  • Loading branch information
andy-sweet and aganders3 authored Mar 13, 2024
1 parent 9e6a660 commit 0e49d68
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 17 deletions.
9 changes: 4 additions & 5 deletions src/ViewerState.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Vector3 } from "three";

export const DEFAULT_ZARR_URL = new URL(
export const DEFAULT_ZARR_URL =
"https://sci-imaging-vis-public-demo-data.s3.us-west-2.amazonaws.com" +
"/points-web-viewer/sparse-zarr-v2/ZSNS001_tracks_bundle.zarr",
);
"/points-web-viewer/sparse-zarr-v2/ZSNS001_tracks_bundle.zarr";

const HASH_KEY = "viewerState";

Expand All @@ -17,13 +16,13 @@ export function clearUrlHash() {

// Encapsulates all the persistent state in the viewer (e.g. that can be serialized and shared).
export class ViewerState {
dataUrl: URL;
dataUrl: string;
curTime: number;
cameraPosition: Vector3;
cameraTarget: Vector3;

constructor(
dataUrl: URL = DEFAULT_ZARR_URL,
dataUrl: string = DEFAULT_ZARR_URL,
curTime: number = 0,
// Default position and target from interacting with ZSNS001.
cameraPosition: Vector3 = new Vector3(500, 500, -1250),
Expand Down
29 changes: 17 additions & 12 deletions src/scene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default function Scene(props: SceneProps) {
const [playing, setPlaying] = useState(false);

// Other state that is not or does not need to be persisted.
const [trackManager, setTrackManager] = useState<TrackManager>();
const [trackManager, setTrackManager] = useState<TrackManager | null>(null);
const [numTimes, setNumTimes] = useState(0);
const [trackHighlightLength, setTrackHighlightLength] = useState(11);
const [loading, setLoading] = useState(false);
Expand Down Expand Up @@ -120,15 +120,14 @@ export default function Scene(props: SceneProps) {
// update the array when the dataUrl changes
useEffect(() => {
console.log("load data from %s", dataUrl);
const trackManager = loadTrackManager(dataUrl.toString());
const trackManager = loadTrackManager(dataUrl);
// TODO: add clean-up by returning another closure
trackManager.then((tm: TrackManager | null) => {
if (!tm) return;
setTrackManager(tm);
setNumTimes(tm.points.shape[0]);
setNumTimes(tm?.points.shape[0] || numTimes);
// Defend against the case when a curTime valid for previous data
// is no longer valid.
setCurTime(Math.min(curTime, tm.points.shape[0] - 1));
setCurTime(Math.min(curTime, tm?.points.shape[0] - 1 || numTimes - 1));
});
}, [dataUrl]);

Expand Down Expand Up @@ -187,6 +186,12 @@ export default function Scene(props: SceneProps) {
setLoading(false);
console.debug("IGNORE FETCH points at time %d", curTime);
}

// stop playback if there is no data
if (!trackManager) {
setPlaying(false);
}

return () => {
clearTimeout(loadingTimer);
ignore = true;
Expand Down Expand Up @@ -219,16 +224,16 @@ export default function Scene(props: SceneProps) {
<InputText
id="url-input"
label="Zarr URL"
placeholder={initialViewerState.dataUrl.toString()}
value={dataUrl.toString()}
onChange={(e) => setDataUrl(new URL(e.target.value))}
placeholder={initialViewerState.dataUrl}
defaultValue={initialViewerState.dataUrl}
onChange={(e) => setDataUrl(e.target.value)}
fullWidth={true}
intent={trackManager ? "default" : "error"}
/>
<InputSlider
id="time-frame-slider"
aria-labelledby="input-slider-time-frame"
disabled={trackManager === undefined}
disabled={!trackManager}
min={0}
max={numTimes - 1}
valueLabelDisplay="on"
Expand All @@ -252,7 +257,7 @@ export default function Scene(props: SceneProps) {
onLabel="Spin"
offLabel="Spin"
checked={autoRotate}
disabled={trackManager === undefined}
disabled={!trackManager}
onChange={(e) => {
setAutoRotate((e.target as HTMLInputElement).checked);
}}
Expand All @@ -261,13 +266,13 @@ export default function Scene(props: SceneProps) {
onLabel="Play"
offLabel="Play"
checked={playing}
disabled={trackManager === undefined}
disabled={!trackManager}
onChange={(e) => {
setPlaying((e.target as HTMLInputElement).checked);
}}
/>
<Button
disabled={trackManager === undefined}
disabled={!trackManager}
sdsType="primary"
sdsStyle="rounded"
onClick={() => canvas.current?.removeAllTracks()}
Expand Down

0 comments on commit 0e49d68

Please sign in to comment.