diff --git a/client/src/components/ColorSchemeDialog.vue b/client/src/components/ColorSchemeDialog.vue index 9a102e6c..fcc764f3 100644 --- a/client/src/components/ColorSchemeDialog.vue +++ b/client/src/components/ColorSchemeDialog.vue @@ -1,5 +1,5 @@ @@ -89,34 +35,25 @@ function onContoursEnabledChange(checked: boolean) { > - Overlay & Contour Options + Mask Overlay Options - - - - - -
- - - - Contours may not be performant on large recordings. - -
- - -
diff --git a/client/src/components/geoJS/geoJSUtils.ts b/client/src/components/geoJS/geoJSUtils.ts index a48be70b..9f236785 100644 --- a/client/src/components/geoJS/geoJSUtils.ts +++ b/client/src/components/geoJS/geoJSUtils.ts @@ -74,6 +74,9 @@ const useGeoJS = () => { opacity: number ) => { if (images.length === 0) return; + if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) { + return; + } layer.node().css("opacity", String(opacity)); while (features.length > images.length) { const feature = features.pop(); @@ -81,6 +84,9 @@ const useGeoJS = () => { } let previousWidth = 0; const totalBaseWidth = images.reduce((sum, img) => sum + img.naturalWidth, 0); + if (!Number.isFinite(totalBaseWidth) || totalBaseWidth <= 0) { + return; + } images.forEach((image, index) => { const scale = width / totalBaseWidth; const currentWidth = image.width * scale; diff --git a/client/src/use/usePulseMetadata.ts b/client/src/use/usePulseMetadata.ts index 3538d024..50807dd0 100644 --- a/client/src/use/usePulseMetadata.ts +++ b/client/src/use/usePulseMetadata.ts @@ -61,7 +61,8 @@ function getInitialLabelsMode(): PulseMetadataLabelsMode { const pulseMetadataList: Ref = ref([]); const pulseMetadataLoading = ref(false); -const viewPulseMetadataLayer = ref(stored.viewPulseMetadataLayer ?? false); +// Default to showing pulse metadata unless user explicitly turned it off. +const viewPulseMetadataLayer = ref(stored.viewPulseMetadataLayer ?? true); async function loadPulseMetadata(recordingId: number) { pulseMetadataLoading.value = true; diff --git a/client/src/use/useState.ts b/client/src/use/useState.ts index 45425c00..7e51872e 100644 --- a/client/src/use/useState.ts +++ b/client/src/use/useState.ts @@ -93,7 +93,8 @@ const contoursEnabled = ref(false); const imageOpacity = ref(1.0); const contourOpacity = ref(1.0); const contoursLoading = ref(false); -const viewMaskOverlay = ref(false); +// Default mask overlay to visible at 50% opacity. +const viewMaskOverlay = ref(true); const maskOverlayOpacity = ref(0.50); const setContoursEnabled = (value: boolean) => { contoursEnabled.value = value; diff --git a/client/src/views/NABat/NABatSpectrogram.vue b/client/src/views/NABat/NABatSpectrogram.vue index ad8b04e8..76d4660e 100644 --- a/client/src/views/NABat/NABatSpectrogram.vue +++ b/client/src/views/NABat/NABatSpectrogram.vue @@ -18,8 +18,7 @@ import SpectrogramViewer from "@components/SpectrogramViewer.vue"; import { SpectroInfo } from "@components/geoJS/geoJSUtils"; import ThumbnailViewer from "@components/ThumbnailViewer.vue"; import useState from "@use/useState"; -import ColorPickerMenu from "@components/ColorPickerMenu.vue"; -import ColorSchemeSelect from "@components/ColorSchemeSelect.vue"; +import ColorSchemeDialog from "@components/ColorSchemeDialog.vue"; import TransparencyFilterControl from "@/components/TransparencyFilterControl.vue"; import RecordingInfoDialog from "@components/RecordingInfoDialog.vue"; import RecordingAnnotations from "@components/RecordingAnnotations.vue"; @@ -33,8 +32,7 @@ export default defineComponent({ ThumbnailViewer, RecordingInfoDialog, RecordingAnnotations, - ColorPickerMenu, - ColorSchemeSelect, + ColorSchemeDialog, TransparencyFilterControl }, props: { @@ -53,9 +51,6 @@ export default defineComponent({ toggleLayerVisibility, layerVisibility, colorScale, - colorSchemes, - colorScheme, - backgroundColor, selectedId, selectedType, scaledVals, @@ -82,12 +77,12 @@ export default defineComponent({ const loadedImage = ref(false); const allImagesLoaded: Ref = ref([]); const compressed = ref(configuration.value.spectrogram_view === 'compressed'); - const colorpickerMenu = ref(false); const errorMessage: Ref = ref(null); const additionalErrors: Ref = ref([]); const gridEnabled = ref(false); const recordingInfo = ref(false); + const recordingMap = ref(false); const disabledFeatures = ref(['speciesLabel', 'endpointLabels', 'durationLabels', 'timeLabels']); const loadData = async () => { @@ -157,9 +152,6 @@ export default defineComponent({ ); onMounted(() => { loadData(); - colorScheme.value = colorSchemes.find((scheme) => scheme.value === configuration.value.default_color_scheme) || colorSchemes[0]; - backgroundColor.value = configuration.value.default_spectrogram_background_color || 'rgb(0, 0, 0)'; - }); // eslint-disable-next-line @typescript-eslint/no-explicit-any const parentGeoViewerRef: Ref = ref(null); @@ -226,11 +218,6 @@ export default defineComponent({ toggleDrawingBoundingBox, fixedAxes, toggleFixedAxes, - // Color Scheme - colorSchemes, - colorScheme, - backgroundColor, - colorpickerMenu, // Other user selection selectedUsers, colorScale, @@ -238,6 +225,7 @@ export default defineComponent({ recordingInfo, // Disabled Featuers not in NABat disabledFeatures, + recordingMap, }; }, }); @@ -254,9 +242,20 @@ export default defineComponent({ > + + + @@ -273,6 +272,19 @@ export default defineComponent({ Recording Information + + + Recording Location Map +
@@ -290,33 +302,33 @@ export default defineComponent({ >
xScale: - {{ scaledVals.x.toFixed(2) }}x + {{ scaledVals.x.toFixed(2) }}x
yScale: - {{ scaledVals.y.toFixed(2) }}x + {{ scaledVals.y.toFixed(2) }}x
- - + + - Toggle between locked and floating axes + Toggle Compressed View + - Draw bounding boxes to measure pulses + Draw a bound box to measure pulses Turn Time Label On/Off - - - Turn Legend Grid On/Off - - - - Toggle Compressed View - @@ -455,21 +439,56 @@ export default defineComponent({ Highlight Compressed Areas -
- - -
-
+
+ + + + Settings + + + + {{ fixedAxes ? 'mdi-axis-lock' : 'mdi-axis' }} + + + Toggle Axes Type + + + + + + + {{ gridEnabled ? 'mdi-grid' : 'mdi-grid-off' }} + + + Toggle Grid + + + + + + + + + + @@ -498,31 +517,37 @@ export default defineComponent({ - - - - - View Annotations in sideTab - - - + + + + + + + + View Annotations in sideTab + + + + + + -
+
(null); const previousUnsubmittedId = ref(null); @@ -106,6 +107,7 @@ export default defineComponent({ const allImagesLoaded: Ref = ref([]); const gridEnabled = ref(false); const recordingInfo = ref(false); + const recordingMap = ref(false); const compressed = ref(configuration.value.spectrogram_view === 'compressed'); const colorpickerMenu = ref(false); const getAnnotationsList = async (annotationId?: number) => { @@ -147,7 +149,6 @@ export default defineComponent({ const loading = ref(false); const spectrogramData: Ref = ref(null); const loadData = async () => { - viewMaskOverlay.value = false; const tempViewPulseMetadataLayer = viewPulseMetadataLayer.value; viewPulseMetadataLayer.value = false; contoursEnabled.value = false; @@ -183,7 +184,6 @@ export default defineComponent({ if (tempViewPulseMetadataLayer) { viewPulseMetadataLayer.value = true; } - } else { console.error("No URL found for the spectrogram"); } @@ -241,6 +241,14 @@ export default defineComponent({ nextUnsubmittedId.value = null; previousUnsubmittedId.value = null; } + // Automatically load pulse metadata when the layer is enabled and data has not yet been fetched. + if ( + viewPulseMetadataLayer.value && + currentRecordingId.value != null && + pulseMetadataList.value.length === 0 + ) { + await loadPulseMetadata(currentRecordingId.value); + } loading.value = false; }; const setSelection = (annotationId: number) => { @@ -297,6 +305,9 @@ export default defineComponent({ freqRef.value = freq; }; watch(compressed, () => { + // Reset zoom and compressed overlay state when toggling views + scaledVals.value = { x: 1, y: 1 }; + viewCompressedOverlay.value = false; loadData(); if (drawingBoundingBox.value) { toggleDrawingBoundingBox(); @@ -400,6 +411,7 @@ export default defineComponent({ goToPreviousUnreviewed, nextUnsubmittedId, previousUnsubmittedId, + recordingMap, }; }, }); @@ -413,9 +425,20 @@ export default defineComponent({ > + + + @@ -432,6 +455,19 @@ export default defineComponent({ Recording Information + + + Recording Location Map +
@@ -458,15 +494,29 @@ export default defineComponent({ -
+
Mode: {{ annotationState }}
+ + + Toggle Compressed View +
- - - Toggle between locked and floating axes -