Skip to content

Commit 8123a0e

Browse files
authored
Improve Text Label Scaling (#230)
* improve text label scaling * adjusting time/species/freq layers tor text scaling * update the nginx.nominio.template name * revert max zoom level * allow scaling changes to update time Duration * abstract Text base layer and font scaling * fontScaling only in compressed view * lint: indention fix
1 parent fd83d44 commit 8123a0e

File tree

10 files changed

+240
-233
lines changed

10 files changed

+240
-233
lines changed

client/src/components/geoJS/LayerManager.vue

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -572,11 +572,14 @@ export default defineComponent({
572572
speciesLayer?.setScaledDimensions(props.scaledWidth, props.scaledHeight);
573573
speciesSequenceLayer?.setScaledDimensions(props.scaledWidth, props.scaledHeight);
574574
sequenceAnnotationLayer?.setScaledDimensions(props.scaledWidth, props.scaledHeight);
575-
if (timeLayer && layerVisibility.value.includes("time")) {
575+
if (timeLayer && (layerVisibility.value.includes("time") || layerVisibility.value.includes('duration'))) {
576+
if (layerVisibility.value.includes("time")) {
577+
timeLayer.displayDuration = false;
578+
} else {
579+
timeLayer.displayDuration = true;
580+
}
576581
timeLayer.formatData(annotations, sequenceAnnotations);
577582
timeLayer.redraw();
578-
} else {
579-
timeLayer?.disable();
580583
}
581584
if (freqLayer && layerVisibility.value.includes("freq")) {
582585
freqLayer.formatData(annotations);
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
2+
3+
/* eslint-disable class-methods-use-this */
4+
import { SpectroInfo } from "../geoJSUtils";
5+
import { LayerStyle } from "./types";
6+
import geo from "geojs";
7+
8+
9+
10+
export default abstract class BaseTextLayer<D> {
11+
textData: D[];
12+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
13+
textLayer: any;
14+
15+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
16+
geoViewerRef: any;
17+
18+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
19+
event: (name: string, data: any) => void;
20+
21+
spectroInfo: SpectroInfo;
22+
23+
textStyle: LayerStyle<D>;
24+
25+
scaledWidth: number;
26+
scaledHeight: number;
27+
28+
29+
30+
31+
textScaled: number | undefined;
32+
33+
zoomLevel: number;
34+
35+
xScale: number;
36+
37+
compressedView: boolean;
38+
39+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
40+
constructor(
41+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
42+
geoViewerRef: any,
43+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
44+
event: (name: string, data: any) => void,
45+
spectroInfo: SpectroInfo
46+
) {
47+
this.geoViewerRef = geoViewerRef;
48+
this.spectroInfo = spectroInfo;
49+
this.textData = [];
50+
this.scaledWidth = 0;
51+
this.scaledHeight = 0;
52+
this.event = event;
53+
this.xScale = 0;
54+
this.compressedView = false;
55+
//Only initialize once, prevents recreating Layer each edit
56+
this.textStyle = this.createTextStyle();
57+
this.geoViewerRef.geoOn(geo.event.zoom, (event: {zoomLevel: number}) => this.onZoom(event));
58+
this.zoomLevel = this.geoViewerRef.camera().zoomLevel;
59+
60+
}
61+
62+
setScaledDimensions(newWidth: number, newHeight: number) {
63+
this.scaledWidth = newWidth;
64+
this.scaledHeight = newHeight;
65+
if (this.spectroInfo.compressedWidth) {
66+
this.xScale = newWidth / this.spectroInfo.compressedWidth;
67+
this.compressedView = true;
68+
} else {
69+
this.xScale = newWidth / this.spectroInfo.width;
70+
this.compressedView = false;
71+
}
72+
}
73+
74+
onZoom(event: {zoomLevel: number}) {
75+
this.zoomLevel = event.zoomLevel;
76+
this.textScaled = undefined;
77+
if ((this.zoomLevel || 0) < -1.5 ) {
78+
this.textScaled = -1.5;
79+
} else if ((this.zoomLevel || 0) > 0) {
80+
this.textScaled = Math.sqrt(this.zoomLevel || 1);
81+
} else {
82+
this.textScaled = this.zoomLevel;
83+
}
84+
this.redraw();
85+
}
86+
87+
88+
destroy() {
89+
if (this.textLayer) {
90+
this.geoViewerRef.deleteLayer(this.textLayer);
91+
}
92+
}
93+
94+
95+
96+
redraw() {
97+
// add some styles
98+
this.textLayer.data(this.textData).style(this.createTextStyle()).draw();
99+
}
100+
101+
disable() {
102+
this.textLayer.data([]).draw();
103+
}
104+
105+
getFontSize(fontA: number, fontB: number, xScale: number) {
106+
if (xScale >= 2.5) {
107+
return fontA; // clamp high
108+
} else if (xScale <= 1.0) {
109+
return fontB; // clamp low
110+
} else {
111+
const t = (xScale - 1.0) / (2.5 - 1.0); // normalized progress
112+
return fontB + t * (fontA - fontB); // linear interpolation
113+
}
114+
}
115+
116+
117+
createTextStyle(): LayerStyle<D> {
118+
return {
119+
...{
120+
strokeColor: "white",
121+
strokeWidth: 2.0,
122+
antialiasing: 0,
123+
stroke: true,
124+
uniformPolygon: true,
125+
fill: false,
126+
fontSize: () => this.xScale < 2.5 ? '12px' : '16px'
127+
},
128+
color: () => {
129+
return "white";
130+
},
131+
textScaled: this.textScaled,
132+
textBaseline: 'middle',
133+
};
134+
}
135+
136+
}

client/src/components/geoJS/layers/freqLayer.ts

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable class-methods-use-this */
22
import { SpectrogramAnnotation } from "../../../api/api";
33
import { SpectroInfo, spectroToGeoJSon } from "../geoJSUtils";
4+
import BaseTextLayer from "./baseTextLayer";
45
import { LayerStyle } from "./types";
56

67
interface LineData {
@@ -17,32 +18,14 @@ interface TextData {
1718
offsetX?: number;
1819
}
1920

20-
export default class FreqLayer {
21+
export default class FreqLayer extends BaseTextLayer<TextData> {
2122
lineData: LineData[];
2223

2324
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2425
lineLayer: any;
2526

26-
textData: TextData[];
27-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
28-
textLayer: any;
29-
30-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
31-
geoViewerRef: any;
32-
33-
34-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
35-
event: (name: string, data: any) => void;
36-
37-
spectroInfo: SpectroInfo;
38-
39-
textStyle: LayerStyle<TextData>;
4027
lineStyle: LayerStyle<LineData>;
4128

42-
scaledWidth: number;
43-
scaledHeight: number;
44-
45-
4629
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4730
constructor(
4831
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -51,13 +34,8 @@ export default class FreqLayer {
5134
event: (name: string, data: any) => void,
5235
spectroInfo: SpectroInfo
5336
) {
54-
this.geoViewerRef = geoViewerRef;
37+
super(geoViewerRef, event, spectroInfo);
5538
this.lineData = [];
56-
this.spectroInfo = spectroInfo;
57-
this.textData = [];
58-
this.scaledWidth = 0;
59-
this.scaledHeight = 0;
60-
this.event = event;
6139
//Only initialize once, prevents recreating Layer each edit
6240
const layer = this.geoViewerRef.createLayer("feature", {
6341
features: ["text", "line"],
@@ -73,11 +51,6 @@ export default class FreqLayer {
7351
this.lineStyle = this.createLineStyle();
7452
}
7553

76-
setScaledDimensions(newWidth: number, newHeight: number) {
77-
this.scaledWidth = newWidth;
78-
this.scaledHeight = newHeight;
79-
}
80-
8154
destroy() {
8255
if (this.textLayer) {
8356
this.geoViewerRef.deleteLayer(this.textLayer);
@@ -196,6 +169,7 @@ export default class FreqLayer {
196169
stroke: true,
197170
uniformPolygon: true,
198171
fill: false,
172+
fontSize: '16px',
199173
},
200174
color: () => {
201175
return "white";
@@ -204,7 +178,9 @@ export default class FreqLayer {
204178
x: data.offsetX || 0,
205179
y: data.offsetY || 0,
206180
}),
207-
textAlign: 'starts',
181+
textAlign: 'start',
182+
textScaled: this.textScaled,
183+
textBaseline: 'bottom',
208184
};
209185
}
210186
}

0 commit comments

Comments
 (0)