Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,148 changes: 1,164 additions & 984 deletions client/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"vue": "^3.3.1",
"vue-markdown-render": "^2.1.1",
"vue-router": "^4.0.12",
"vuetify": "^3.9.0-beta.0"
"vuetify": "^3.10.0"
},
"devDependencies": {
"@types/geojson": "^7946.0.13",
Expand Down
3 changes: 3 additions & 0 deletions client/src/components/ColorPickerMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ defineProps({
const colorpickerMenu = ref(false);
const color = defineModel({ default: 'rgb(0, 0, 0)'});
function updateColor(colorVal: string) {
if (colorVal.includes('/')) {
colorVal = colorVal.replace(' / undefined)', ')');
}
if (!colorVal.includes(',')) {
// convert rgb(0 0 0) to rgb(0, 0, 0)
colorVal = colorVal.replace(/rgb\((\d+)\s+(\d+)\s+(\d+)\)/, 'rgb($1, $2, $3)');
Expand Down
6 changes: 3 additions & 3 deletions client/src/components/SpectrogramViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default defineComponent({
selectedId,
selectedType,
creationType,
blackBackground,
backgroundColor,
scaledVals,
configuration,
scaledWidth,
Expand Down Expand Up @@ -237,10 +237,10 @@ export default defineComponent({
createAnnotation,
cursorHandler,
imageCursorRef,
blackBackground,
wheelEvent,
scaledWidth,
scaledHeight,
backgroundColor
};
},
});
Expand All @@ -249,7 +249,7 @@ export default defineComponent({
<template>
<div
class="video-annotator"
:class="{ 'black-background': blackBackground, 'white-background': !blackBackground }"
:style="{ backgroundColor: backgroundColor }"
@wheel="wheelEvent($event)"
>
<div
Expand Down
6 changes: 3 additions & 3 deletions client/src/components/ThumbnailViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default defineComponent({
const {
scaledWidth,
scaledHeight,
blackBackground,
backgroundColor,
} = useState();

function updateViewerAndImages() {
Expand Down Expand Up @@ -154,7 +154,7 @@ export default defineComponent({
yScale,
scaledWidth,
scaledHeight,
blackBackground,
backgroundColor,
};
},
});
Expand All @@ -165,8 +165,8 @@ export default defineComponent({
<div
id="spectro"
ref="containerRef"
:style="{ backgroundColor: backgroundColor }"
class="playback-container"
:class="{ 'black-background': blackBackground, 'white-background': !blackBackground }"
/>
<layer-manager
v-if="initialized"
Expand Down
19 changes: 18 additions & 1 deletion client/src/components/geoJS/LayerManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { defineComponent, nextTick, onMounted, onUnmounted, PropType, Ref, ref, watch } from "vue";
import * as d3 from "d3";
import { SpectrogramAnnotation, SpectrogramSequenceAnnotation } from "../../api/api";
import { geojsonToSpectro, SpectroInfo } from "./geoJSUtils";
import { geojsonToSpectro, SpectroInfo, textColorFromBackground } from "./geoJSUtils";
import EditAnnotationLayer from "./layers/editAnnotationLayer";
import RectangleLayer from "./layers/rectangleLayer";
import CompressedOverlayLayer from "./layers/compressedOverlayLayer";
Expand Down Expand Up @@ -640,6 +640,7 @@ export default defineComponent({
// convert rgb(0 0 0) to rgb(0, 0, 0)
backgroundColor.value = backgroundColor.value.replace(/rgb\((\d+)\s+(\d+)\s+(\d+)\)/, 'rgb($1, $2, $3)');
}

const backgroundRgbColor = d3.color(backgroundColor.value) as d3.RGBColor;
const redStops: number[] = [backgroundRgbColor.r / 255];
const greenStops: number[] = [backgroundRgbColor.g / 255];
Expand All @@ -654,6 +655,22 @@ export default defineComponent({
rValues.value = redStops.join(' ');
gValues.value = greenStops.join(' ');
bValues.value = blueStops.join(' ');
const textColor = textColorFromBackground(backgroundColor.value);
if (freqLayer) {
freqLayer.setTextColor(textColor);
}
if (speciesLayer) {
speciesLayer.setTextColor(textColor);
}
if (legendLayer) {
legendLayer.setTextColor(textColor);
}
if (timeLayer) {
timeLayer.setTextColor(textColor);
}
if (speciesSequenceLayer) {
speciesSequenceLayer.setTextColor(textColor);
}

}

Expand Down
29 changes: 29 additions & 0 deletions client/src/components/geoJS/geoJSUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,11 +620,40 @@ function reOrdergeoJSON(coords: GeoJSON.Position[]) {
];
}

function luminance(r: number, g: number, b: number): number {
const toLinear = (c: number): number => {
const s = c / 255;
return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
};

const R = toLinear(r);
const G = toLinear(g);
const B = toLinear(b);

return 0.2126 * R + 0.7152 * G + 0.0722 * B;
}


function getContrastingColor(r: number, g: number, b: number): "black" | "white" {
const L = luminance(r, g, b);
return L > 0.179 ? "black" : "white";
}

function textColorFromBackground(rgbString: string): "black" | "white" {
const matches = rgbString.match(/\d+/g);
if (!matches || matches.length < 3) {
throw new Error("Invalid RGB string format");
}
const [r, g, b] = matches.map(Number);
return getContrastingColor(r, g, b);
}

export {
spectroToGeoJSon,
geojsonToSpectro,
reOrdergeoJSON,
useGeoJS,
spectroToCenter,
spectroSequenceToGeoJSon,
textColorFromBackground
};
11 changes: 9 additions & 2 deletions client/src/components/geoJS/layers/baseTextLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default abstract class BaseTextLayer<D> {
scaledWidth: number;
scaledHeight: number;

color = "white";



Expand Down Expand Up @@ -84,6 +85,12 @@ export default abstract class BaseTextLayer<D> {
this.redraw();
}

setTextColor(newColor: string) {
this.color = newColor;
this.textStyle = this.createTextStyle();
this.redraw();
}


destroy() {
if (this.textLayer) {
Expand Down Expand Up @@ -117,7 +124,7 @@ export default abstract class BaseTextLayer<D> {
createTextStyle(): LayerStyle<D> {
return {
...{
strokeColor: "white",
strokeColor: () => this.color,
strokeWidth: 2.0,
antialiasing: 0,
stroke: true,
Expand All @@ -126,7 +133,7 @@ export default abstract class BaseTextLayer<D> {
fontSize: () => this.xScale < 2.5 ? '12px' : '16px'
},
color: () => {
return "white";
return this.color;
},
textScaled: this.textScaled,
textBaseline: 'middle',
Expand Down
5 changes: 4 additions & 1 deletion client/src/components/geoJS/layers/freqLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ export default class FreqLayer extends BaseTextLayer<TextData> {
uniformPolygon: true,
fill: false,
},
strokeColor: () => {
return this.color;
},
strokeOpacity: (_point, _index, data) => {
// Reduce the rectangle opacity if a polygon is also drawn
if (data.grid) {
Expand Down Expand Up @@ -172,7 +175,7 @@ export default class FreqLayer extends BaseTextLayer<TextData> {
fontSize: '16px',
},
color: () => {
return "white";
return this.color;
},
offset: (data) => ({
x: data.offsetX || 0,
Expand Down
12 changes: 10 additions & 2 deletions client/src/components/geoJS/layers/legendLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,13 @@ export default class LegendLayer extends BaseTextLayer<TextData> {
this.textLayer.data([]).draw();
}

setTextColor(newColor: string) {
this.color = newColor;
this.textStyle = this.createTextStyle();
this.lineStyle = this.createLineStyle();
this.redraw();
}

setGridEnabled(val: boolean) {
this.gridEnabled = val;
if (this.gridEnabled) {
Expand All @@ -458,10 +465,11 @@ export default class LegendLayer extends BaseTextLayer<TextData> {
createLineStyle(): LayerStyle<LineData> {
return {
...{
strokeColor: "#00FFFF",
strokeColor: () => this.color,
strokeWidth: 2.0,
antialiasing: 0,
stroke: true,
color: () => this.color,
uniformPolygon: true,
fill: false,
},
Expand Down Expand Up @@ -496,7 +504,7 @@ export default class LegendLayer extends BaseTextLayer<TextData> {
fontSize: `${this.getFontSize(20, 12, this.xScale)}px`
},
color: () => {
return "white";
return this.color;
},
offset: (data) => ({
x: data.offsetX || 0,
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/geoJS/layers/speciesLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default class SpeciesLayer extends BaseTextLayer<TextData> {
fontSize: '18px',
},
color: () => {
return "white";
return this.color;
},
offset: (data) => ({
x: data.offsetX || 0,
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/geoJS/layers/speciesSequenceLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export default class SpeciesSequenceLayer extends BaseTextLayer<TextData> {
if (d.textType === "type") {
return "yellow";
}
return "white";
return this.color;
},
offset: (data) => ({
x: data.offsetX || 0,
Expand Down
13 changes: 12 additions & 1 deletion client/src/components/geoJS/layers/timeLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface LineData {
line: GeoJSON.LineString;
thicker?: boolean;
grid?: boolean;
markerLine?: boolean; // Line for markiing time endpoints
}

interface TextData {
Expand Down Expand Up @@ -103,6 +104,7 @@ export default class TimeLayer extends BaseTextLayer<TextData> {
[xmin, ymin + lineDist],
],
},
markerLine: true,
thicker: true,
});
this.lineData.push({
Expand All @@ -113,6 +115,7 @@ export default class TimeLayer extends BaseTextLayer<TextData> {
[xmax, ymin + lineDist],
],
},
markerLine: true,
thicker: true,
});
// Now we need to create the text Labels
Expand Down Expand Up @@ -163,6 +166,7 @@ export default class TimeLayer extends BaseTextLayer<TextData> {
[xmin, ymax - lineDist],
],
},
markerLine: true,
thicker: true,
});
this.lineData.push({
Expand All @@ -173,6 +177,7 @@ export default class TimeLayer extends BaseTextLayer<TextData> {
[xmax, ymax - lineDist],
],
},
markerLine: true,
thicker: true,
});
// Now we need to create the text Labels
Expand Down Expand Up @@ -296,8 +301,14 @@ export default class TimeLayer extends BaseTextLayer<TextData> {
uniformPolygon: true,
fill: false,
},
strokeColor: () => {
return this.color;
},
strokeOpacity: (_point, _index, data) => {
// Reduce the rectangle opacity if a polygon is also drawn
if (data.markerLine && this.zoomLevel < 0) {
return 0.0;
}
if (data.grid) {
return 0.5;
}
Expand Down Expand Up @@ -327,7 +338,7 @@ export default class TimeLayer extends BaseTextLayer<TextData> {
fontSize: `${this.getFontSize(16, 12, this.xScale)}px`,
},
color: () => {
return "white";
return this.color;
},
offset: (data) => ({
x: data.offsetX || 0,
Expand Down
1 change: 1 addition & 0 deletions client/src/components/geoJS/layers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface LayerStyle<D> {
strokeColor?: StyleFunction<string, D> | PointFunction<string, D>;
fillColor?: StyleFunction<string, D> | PointFunction<string, D>;
fillOpacity?: StyleFunction<number, D> | PointFunction<number, D>;
visible?: StyleFunction<boolean, D> | PointFunction<boolean, D>;
position?: (point: [number, number]) => { x: number; y: number };
color?: (data: D) => string;
textOpacity?: (data: D) => number;
Expand Down
4 changes: 1 addition & 3 deletions client/src/use/useState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ const otherUserAnnotations: Ref<OtherUserAnnotations> = ref({});
const sharedList: Ref<Recording[]> = ref([]);
const recordingList: Ref<Recording[]> = ref([]);
const nextShared: Ref<Recording | false> = ref(false);
const blackBackground = ref(true);
const scaledVals: Ref<{ x: number; y: number }> = ref({ x: 1, y: 1 });
const viewCompressedOverlay = ref(false);
const sideTab: Ref<"annotations" | "recordings"> = ref("annotations");
Expand All @@ -61,7 +60,7 @@ const configuration: Ref<Configuration> = ref({
is_admin: false,
});
const scaledWidth = ref(0);
const scaledHeight = ref(0);
const scaledHeight = ref(0);

type AnnotationState = "" | "editing" | "creating" | "disabled";
export default function useState() {
Expand Down Expand Up @@ -160,7 +159,6 @@ export default function useState() {
sharedList,
recordingList,
nextShared,
blackBackground,
scaledVals,
viewCompressedOverlay,
sideTab,
Expand Down
20 changes: 18 additions & 2 deletions client/src/views/Spectrogram.vue
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,24 @@ 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)';
const localBackgroundColor = localStorage.getItem('spectrogramBackgroundColor');
if (localBackgroundColor) {
backgroundColor.value = localBackgroundColor;
} else {
backgroundColor.value = configuration.value.default_spectrogram_background_color || 'rgb(0, 0, 0)';
}
const localColorScheme = localStorage.getItem('spectrogramColorScheme');
if (localColorScheme) {
colorScheme.value = colorSchemes.find((scheme) => scheme.value === localColorScheme) || colorSchemes[0];
} else if (configuration.value.default_color_scheme) {
colorScheme.value = colorSchemes.find((scheme) => scheme.value === configuration.value.default_color_scheme) || colorSchemes[0];
}
});
watch(backgroundColor, () => {
localStorage.setItem('spectrogramBackgroundColor', backgroundColor.value);
});
watch(colorScheme, () => {
localStorage.setItem('spectrogramColorScheme', colorScheme.value.value);
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const parentGeoViewerRef: Ref<any> = ref(null);
Expand Down