diff --git a/applications/visualizer/frontend/src/components/viewers/EM/EMStackTilesViewer.tsx b/applications/visualizer/frontend/src/components/viewers/EM/EMStackTilesViewer.tsx
index 05970abe..ad3ddcf4 100644
--- a/applications/visualizer/frontend/src/components/viewers/EM/EMStackTilesViewer.tsx
+++ b/applications/visualizer/frontend/src/components/viewers/EM/EMStackTilesViewer.tsx
@@ -1,4 +1,4 @@
-import { Box } from "@mui/material";
+import { Box, Typography } from "@mui/material";
import "ol/ol.css";
import { type Feature, Map as OLMap, View } from "ol";
import type { FeatureLike } from "ol/Feature";
@@ -174,11 +174,39 @@ const interactions = defaultInteractions({
}),
]);
+const NoEMData = () => {
+ return (
+
+
+ No EM Data Available
+
+
+ Please select a dataset containing EM data to view
+
+
+ );
+};
+
const EMStackViewer = () => {
const currentWorkspace = useGlobalContext().getCurrentWorkspace();
// We take the first active dataset at the moment (will change later)
const firstActiveDataset = Object.values(currentWorkspace.activeDatasets)?.[0];
+ if (!firstActiveDataset.emData) {
+ return ;
+ }
+
+ const hasNeuronSegmentations = !!firstActiveDataset.emData.segmentationSize;
+ const hasSynapseSegmentations = !!firstActiveDataset.emData.synapsesSegmentationUrl;
+
const [minSlice, maxSlice] = firstActiveDataset.emData.sliceRange;
const startSlice = Math.floor((maxSlice + minSlice) / 2);
const [segSlice, segSetSlice] = useState(startSlice);
@@ -195,15 +223,16 @@ const EMStackViewer = () => {
const [showNeurons, setShowNeurons] = useState(true);
const [showSynapses, setShowSynapses] = useState(true);
- const startZoom = useMemo(() => {
- const emData = firstActiveDataset.emData;
- if (!emData) {
- return undefined;
- }
- return emData.minZoom;
- }, [firstActiveDataset.emData]);
+ // EM tiles reverse the maximum and minimum zooms
+ // lower numbers are more zoomed in (0 is max zoom possible)
+ // In OpenLayers, 0 is the minimum zoom and higher number are
+ // more zoomed in.
+ const startZoom = firstActiveDataset.emData.maxZoom;
- const extent = useMemo(() => [0, 0, ...firstActiveDataset.emData.segmentationSize], [firstActiveDataset.emData.segmentationSize]);
+ const extent = useMemo(
+ () => [0, 0, ...(firstActiveDataset.emData.segmentationSize || firstActiveDataset.emData.maxResolution)],
+ [firstActiveDataset.emData.segmentationSize],
+ );
const projection = useMemo(() => {
return new Projection({
@@ -309,46 +338,48 @@ const EMStackViewer = () => {
newLayer: (slice) => newEMLayer(firstActiveDataset, slice, tilegrid, projection),
});
- ringSeg.current = new SlidingLayer({
- map: map,
- cacheSize: ringSize,
- startAt: startSlice,
- extent: [minSlice, maxSlice],
- newLayer: (slice) => newSegLayer(firstActiveDataset, slice),
- onSlide: (slice, layer) => {
- layer.setStyle((feature) => neuronsStyleRef.current(feature));
- currSegLayer.current = layer;
- segSetSlice(slice);
- },
- });
-
- map.on("click", (e) => onFeatureClickRef.current(e.coordinate));
+ if (hasNeuronSegmentations) {
+ ringSeg.current = new SlidingLayer({
+ map: map,
+ cacheSize: ringSize,
+ startAt: startSlice,
+ extent: [minSlice, maxSlice],
+ newLayer: (slice) => newSegLayer(firstActiveDataset, slice),
+ onSlide: (slice, layer) => {
+ layer.setStyle((feature) => neuronsStyleRef.current(feature));
+ currSegLayer.current = layer;
+ segSetSlice(slice);
+ },
+ });
- ringSynSeg.current = new SlidingLayer({
- map: map,
- cacheSize: ringSize,
- startAt: startSlice,
- extent: [minSlice, maxSlice],
- newLayer: (slice) => newSynapsesSegLayer(firstActiveDataset, slice),
- onSlide: (_, layer) => {
- layer.setStyle((feature) => synapsesStyleRef.current(feature));
- currSynSegLayer.current = layer;
- },
- });
+ map.on("click", (e) => onFeatureClickRef.current(e.coordinate));
+ }
- newSynapsesSegLayer;
+ if (hasSynapseSegmentations) {
+ ringSynSeg.current = new SlidingLayer({
+ map: map,
+ cacheSize: ringSize,
+ startAt: startSlice,
+ extent: [minSlice, maxSlice],
+ newLayer: (slice) => newSynapsesSegLayer(firstActiveDataset, slice),
+ onSlide: (_, layer) => {
+ layer.setStyle((feature) => synapsesStyleRef.current(feature));
+ currSynSegLayer.current = layer;
+ },
+ });
+ }
function handleSliceScroll(e: WheelEvent) {
const scrollUp = e.deltaY < 0;
if (scrollUp) {
ringEM.current.next();
- ringSeg.current.next();
- ringSynSeg.current.next();
+ ringSeg.current?.next();
+ ringSynSeg.current?.next();
} else {
ringEM.current.prev();
- ringSeg.current.prev();
- ringSynSeg.current.prev();
+ ringSeg.current?.prev();
+ ringSynSeg.current?.prev();
}
}
@@ -400,8 +431,8 @@ const EMStackViewer = () => {
const onResetView = () => {
// reset sliding window
ringEM.current.goto(startSlice);
- ringSeg.current.goto(startSlice);
- ringSynSeg.current.goto(startSlice);
+ ringSeg.current?.goto(startSlice);
+ ringSynSeg.current?.goto(startSlice);
if (!mapRef.current) return;
const view = mapRef.current.getView();