From a37024de92d384fde055c5302743961c0d711386 Mon Sep 17 00:00:00 2001 From: kaloster Date: Wed, 2 Oct 2024 13:14:49 +0000 Subject: [PATCH] improved dot size calculation --- .infra/rdev/values.yaml | 2 +- client/src/components/Graph/Graph.tsx | 28 ++++++++++++++--- client/src/components/Graph/drawPointsRegl.ts | 5 ++- .../Graph/openseadragon-scalebar.js | 31 ++++++++++++++++++- client/src/global.d.ts | 3 +- client/src/util/glHelpers.ts | 20 ++++++------ 6 files changed, 72 insertions(+), 17 deletions(-) diff --git a/.infra/rdev/values.yaml b/.infra/rdev/values.yaml index 9550e7db7..8bfd5f32f 100644 --- a/.infra/rdev/values.yaml +++ b/.infra/rdev/values.yaml @@ -2,7 +2,7 @@ stack: services: explorer: image: - tag: sha-687399d7 + tag: sha-0e33281a replicaCount: 1 env: # env vars common to all deployment stages diff --git a/client/src/components/Graph/Graph.tsx b/client/src/components/Graph/Graph.tsx index 907483530..38bf26179 100644 --- a/client/src/components/Graph/Graph.tsx +++ b/client/src/components/Graph/Graph.tsx @@ -24,7 +24,7 @@ import { Dataframe } from "util/dataframe"; import { RootState } from "reducers"; import { Field } from "common/types/schema"; import { Query } from "annoMatrix/query"; -import { THROTTLE_MS } from "util/constants"; +import { SCALE_MAX, SCALE_MAX_HIRES, THROTTLE_MS } from "util/constants"; import { isSpatialMode, shouldShowOpenseadragon } from "common/selectors"; import { fetchDeepZoomImageFailed } from "actions/config"; import { track } from "analytics"; @@ -1193,10 +1193,10 @@ class Graph extends React.Component { pixelsPerMeter: 1000000, // this needs to be adjusted based on the image minWidth: "75px", location: Openseadragon.ScalebarLocation.BOTTOM_LEFT, - color: "white", + color: "black", fontColor: "black", backgroundColor: "rgba(255, 255, 255, 0.5)", - barThickness: 3, + barThickness: 2, }); /** @@ -1307,7 +1307,26 @@ class Graph extends React.Component { ); const { width, height } = this.reglCanvas; - const { imageHeight, scaleref, spotDiameterFullres } = unsMetadata; + const { imageHeight, scaleref, spotDiameterFullres, resolution } = + unsMetadata; + + // DEBUG ************************************** + // console.log("spotDiameterFullres: ", spotDiameterFullres); + // console.log("scaleref: ", scaleref); + // console.log("zoom: ", camera?.distance()); + // console.log("imageHeight: ", imageHeight); + // console.log("minViewportDimension: ", Math.min(width, height)); + // console.log("scalefactor: ", Math.min(width, height) / imageHeight); + + // console.log(resolution); + + // if (camera && camera.distance()) { + // console.log( + // "baseSize: ", + // (camera?.distance() / 12) * spotDiameterFullres * scaleref + // ); + // } + // DEBUG ************************************** regl?.poll(); @@ -1324,6 +1343,7 @@ class Graph extends React.Component { imageHeight, scaleref, spotDiameterFullres, + scaleMax: resolution === "hires" ? SCALE_MAX_HIRES : SCALE_MAX, isSpatial: isSpatialMode(this.props), }); } diff --git a/client/src/components/Graph/drawPointsRegl.ts b/client/src/components/Graph/drawPointsRegl.ts index 042d2aae9..79250c58f 100644 --- a/client/src/components/Graph/drawPointsRegl.ts +++ b/client/src/components/Graph/drawPointsRegl.ts @@ -17,6 +17,7 @@ interface ReglProps { imageHeight: number; scaleref: number; spotDiameterFullres: number; + scaleMax: number; isSpatial: boolean; } @@ -37,6 +38,7 @@ export default function drawPointsRegl(regl: Regl) { uniform float imageHeight; uniform float scaleref; uniform float spotDiameterFullres; + uniform float scaleMax; uniform bool isSpatial; varying lowp vec4 fragColor; @@ -61,7 +63,7 @@ export default function drawPointsRegl(regl: Regl) { getFlags(flag, isBackground, isSelected, isHighlight); if (isSpatial) { - size = pointSizeSpatial(nPoints, minViewportDimension, isSelected, isHighlight, distance, imageHeight, scaleref, spotDiameterFullres); + size = pointSizeSpatial(nPoints, minViewportDimension, isSelected, isHighlight, distance, imageHeight, scaleref, spotDiameterFullres, scaleMax); } else { size = pointSize(nPoints, minViewportDimension, isSelected, isHighlight); } @@ -104,6 +106,7 @@ export default function drawPointsRegl(regl: Regl) { spotDiameterFullres: regl.prop( "spotDiameterFullres" ), + scaleMax: regl.prop("scaleMax"), isSpatial: regl.prop("isSpatial"), }, diff --git a/client/src/components/Graph/openseadragon-scalebar.js b/client/src/components/Graph/openseadragon-scalebar.js index f7b618ab3..0c22702bb 100644 --- a/client/src/components/Graph/openseadragon-scalebar.js +++ b/client/src/components/Graph/openseadragon-scalebar.js @@ -110,7 +110,7 @@ this.setDrawScalebarFunction(options.type || $.ScalebarType.MICROSCOPY); this.color = options.color || "black"; this.fontColor = options.fontColor || "black"; - this.backgroundColor = options.backgroundColor || "none"; + this.backgroundColor = options.backgroundColor || "black"; this.fontSize = options.fontSize || ""; this.fontFamily = options.fontFamily || ""; this.barThickness = options.barThickness || 2; @@ -268,15 +268,44 @@ this.divElt.style.top = `${location.y}px`; }, drawMicroscopyScalebar(size, text) { + // this.divElt.style.display = "flex"; + // this.divElt.style.alignItems = "flex-end"; // Align the ticks to the bottom + // this.divElt.style.justifyContent = "space-between"; + + // OG code **************************************************** this.divElt.style.fontSize = this.fontSize; this.divElt.style.fontFamily = this.fontFamily; this.divElt.style.textAlign = "center"; this.divElt.style.color = this.fontColor; this.divElt.style.border = "none"; this.divElt.style.borderBottom = `${this.barThickness}px solid ${this.color}`; + + this.divElt.style.borderRight = `${this.barThickness}px solid ${this.color}`; + this.divElt.style.borderLeft = `${this.barThickness}px solid ${this.color}`; + this.divElt.style.backgroundColor = this.backgroundColor; this.divElt.innerHTML = text; this.divElt.style.width = `${size}px`; + + // // New code **************************************************** + + // // Create the first label (0) + // const label0 = document.createElement("div"); + // label0.className = "label"; + // label0.innerHTML = "0"; + // label0.style.top = "3px"; + // label0.style.fontSize = "12px"; + + // const tick1 = document.createElement("span"); + // tick1.className = "tick"; + // tick1.style.position = "absolute"; + // tick1.style.top = "10px"; // Align tick above the line + // tick1.style.left = "7px"; + // tick1.style.height = "6px"; // Smaller tick + // tick1.style.width = "2px"; + // tick1.style.backgroundColor = "black"; + // label0.appendChild(tick1); + // this.divElt.appendChild(label0); }, drawMapScalebar(size, text) { this.divElt.style.fontSize = this.fontSize; diff --git a/client/src/global.d.ts b/client/src/global.d.ts index 88d611104..f045fe99a 100644 --- a/client/src/global.d.ts +++ b/client/src/global.d.ts @@ -3,7 +3,8 @@ import { Viewer, Options } from "openseadragon"; /** * We use v4, but the types are for v3. This is a temporary workaround. * https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/openseadragon - */ declare module "openseadragon" { + */ +declare module "openseadragon" { interface Viewer { scalebar: (options: ScalebarOptions) => void; } diff --git a/client/src/util/glHelpers.ts b/client/src/util/glHelpers.ts index 65c33cd8f..9d2480bda 100644 --- a/client/src/util/glHelpers.ts +++ b/client/src/util/glHelpers.ts @@ -90,25 +90,27 @@ export const densityFactor = 0.9; export const glPointSizeSpatial = ` - float pointSizeSpatial(float nPoints, float minViewportDimension, bool isSelected, bool isHighlight, float distance, float imageHeight, float scaleref, float spotDiameterFullres) { + float pointSizeSpatial(float nPoints, float minViewportDimension, bool isSelected, bool isHighlight, float distance, float imageHeight, float scaleref, float spotDiameterFullres, float scaleMax) { float scaleFactor = (minViewportDimension / imageHeight) ; + float maxPointSize = spotDiameterFullres * scaleref; // Actual size of the spot in full resolution - // Adjust base size based on distance (zoom level) - float adjustedDistance = clamp(distance, 1., 2.5); // Clamp the distance to avoid extreme values - float zoomFactor = 1.0 / adjustedDistance * distance * ${densityFactor}; // Inverse of adjustedDistance and multiply by distnace and density factor to get smoother dot size change - float adjustedZoomFactor = clamp(zoomFactor, 0.1, .9); // Clamp the zoom factor to avoid extreme values and overlapping dots + float minPointSize = maxPointSize * scaleFactor - 3.; // Minimum size of the spot in the current resolution - float baseSize = spotDiameterFullres * scaleref * scaleFactor * adjustedZoomFactor; // Base size proportional to viewport + float scaleStep = (maxPointSize - minPointSize) / scaleMax; + + float adjustedPointSize = scaleStep * distance + minPointSize; + + float pointSize = clamp(adjustedPointSize, minPointSize, maxPointSize); // isHighlight has to be checked before isSelected to ensure that highlight works as intended if (isHighlight) { - return baseSize * 2.0; // Increase size if selected + return pointSize * 2.0; // Increase size if selected } else if (isSelected) { - return baseSize * 1.5; // Increase size if highlighted + return pointSize * 1.5; // Increase size if highlighted } else { - return baseSize; + return pointSize; } } `;